[MLton-commit] r6356
Vesa Karvonen
vesak at mlton.org
Sun Jan 27 03:35:29 PST 2008
Added StaticSum.map. Also tweaked the STATIC_SUM signature.
----------------------------------------------------------------------
U mltonlib/trunk/com/ssh/extended-basis/unstable/detail/typing/static-sum.sml
U mltonlib/trunk/com/ssh/extended-basis/unstable/public/typing/static-sum.sig
----------------------------------------------------------------------
Modified: mltonlib/trunk/com/ssh/extended-basis/unstable/detail/typing/static-sum.sml
===================================================================
--- mltonlib/trunk/com/ssh/extended-basis/unstable/detail/typing/static-sum.sml 2008-01-26 00:22:52 UTC (rev 6355)
+++ mltonlib/trunk/com/ssh/extended-basis/unstable/detail/typing/static-sum.sml 2008-01-27 11:35:29 UTC (rev 6356)
@@ -15,4 +15,5 @@
fun sum x f = f x
fun split x = x (fn x => (inL x, inL x), fn x => (inR x, inR x))
fun out x = x (match, match)
+ fun map (f, g) = sum (inL o f, inR o g)
end
Modified: mltonlib/trunk/com/ssh/extended-basis/unstable/public/typing/static-sum.sig
===================================================================
--- mltonlib/trunk/com/ssh/extended-basis/unstable/public/typing/static-sum.sig 2008-01-26 00:22:52 UTC (rev 6355)
+++ mltonlib/trunk/com/ssh/extended-basis/unstable/public/typing/static-sum.sig 2008-01-27 11:35:29 UTC (rev 6356)
@@ -5,7 +5,8 @@
*)
(**
- * A static sum allows one to make choices at the type level.
+ * A static sum allows one to write functions with argument type dependent
+ * result types.
*
* As an example, consider the following function:
*
@@ -20,24 +21,52 @@
*
* In other words, {succ} is a function that is given a static sum that
* holds either an int or a real. {succ} then returns the value plus 1.
+ * The type of the result of {succ} depends on the type of the argument.
*
* The design is mostly copied from Stephen Weeks.
+ *
+ * See also: [http://mlton.org/StaticSum]
*)
signature STATIC_SUM = sig
type ('dL, 'cL, 'dR, 'cR, 'c) dom
type ('dL, 'cL, 'dR, 'cR, 'c) cod
type ('dL, 'cL, 'dR, 'cR, 'c) t =
('dL, 'cL, 'dR, 'cR, 'c) dom -> ('dL, 'cL, 'dR, 'cR, 'c) cod
- (** The type of static sums. *)
+ (**
+ * The type of static sums. In the type variables, 'd stands for
+ * domain and 'c for codomain.
+ *
+ * The key difference between an ordinary sum type, like {(int, real)
+ * Sum.t}, and a static sum type, like {(int, real, real, int, real)
+ * StaticSum.t}, is that the ordinary sum type says nothing about the
+ * type of the result of deconstructing a sum while the static sum type
+ * specifies the type.
+ *)
- val inL : 'a -> ('a, 'b, 'c, 'd, 'b) t
+ val inL : 'dL -> ('dL, 'cL, 'dR, 'cR, 'cL) t
(** Injects the given value to a static sum as the left element. *)
- val inR : 'c -> ('a, 'b, 'c, 'd, 'd) t
+ val inR : 'dR -> ('dL, 'cL, 'dR, 'cR, 'cR) t
(** Injects the given value to a static sum as the right element. *)
- val match : ('a, 'b, 'c, 'd, 'e) t -> ('a -> 'b) * ('c -> 'd) -> 'e
+ val map : ('dL0 -> 'dLL) * ('dR0 -> 'dRR) ->
+ ('dL0, ('dLL, 'cLL, 'dRL, 'cRL, 'cLL) t,
+ 'dR0, ('dLR, 'cLR, 'dRR, 'cRR, 'cRR) t,
+ ('dL, 'cL, 'dR, 'cR, 'c) t) t -> ('dL, 'cL, 'dR, 'cR, 'c) t
(**
+ * Applies one of the given functions to the value carried by the
+ * static sum. {map} satisfies the following laws:
+ *
+ *> map (f, g) (inL x) = inL (f x)
+ *> map (f, g) (inR x) = inR (g x)
+ *
+ * {map} is not primitive, it can be implemented as:
+ *
+ *> fun map (f, g) = sum (inL o f, inR o g)
+ *)
+
+ val match : ('dL, 'cL, 'dR, 'cR, 'c) t -> ('dL -> 'cL) * ('dR -> 'cR) -> 'c
+ (**
* Performs case analysis on the given static sum. {match} satisfies
* the following laws:
*
@@ -45,12 +74,27 @@
*> match (inR x) (f, g) = g x
*)
- val sum : ('a -> 'b) * ('c -> 'd) -> ('a, 'b, 'c, 'd, 'e) t -> 'e
- (** {sum} is equivalent to {flip match}. *)
+ val out : ('L, 'L, 'R, 'R, 'c) t -> 'c
+ (**
+ * Extracts the value from the given static sum. {out} satisfies the
+ * following laws:
+ *
+ *> out (inL x) = x
+ *> out (inR x) = x
+ *
+ * {out} is not primitive, it can be implemented as:
+ *
+ *> fun out s = match s (id, id)
+ *)
- val split : ('a,
- ('a, 'b, 'c, 'd, 'b) t * ('a, 'e, 'f, 'g, 'e) t, 'h,
- ('i, 'j, 'h, 'k, 'k) t * ('l, 'm, 'h, 'n, 'n) t, 'o) t -> 'o
+ val split : ('dL, ('dL, 'cLL1, 'dRL1, 'cRL1, 'cLL1) t *
+ ('dL, 'cLL2, 'dRL2, 'cRL2, 'cLL2) t,
+ 'dR, ('dLR1, 'cLR1, 'dR, 'cRR1, 'cRR1) t *
+ ('dLR2, 'cLR2, 'dR, 'cRR2, 'cRR2) t,
+ ('dL1, 'cL1, 'dR1, 'cR1, 'c1) t *
+ ('dL2, 'cL2, 'dR2, 'cR2, 'c2) t) t ->
+ ('dL1, 'cL1, 'dR1, 'cR1, 'c1) t *
+ ('dL2, 'cL2, 'dR2, 'cR2, 'c2) t
(**
* Splits a given static sum into two "branches" that can be assigned
* types independently. {split} satisfies the following laws:
@@ -64,16 +108,6 @@
*> fn x => (inR x, inR x))
*)
- val out : ('a, 'a, 'b, 'b, 'c) t -> 'c
- (**
- * Extracts the value from the given static sum. {out} satisfies the
- * following laws:
- *
- *> out (inL x) = x
- *> out (inR x) = x
- *
- * {out} is not primitive, it can be implemented as:
- *
- *> fun out s = match s (id, id)
- *)
+ val sum : ('dL -> 'cL) * ('dR -> 'cR) -> ('dL, 'cL, 'dR, 'cR, 'c) t -> 'c
+ (** {sum} is equivalent to {flip match}. *)
end
More information about the MLton-commit
mailing list