translating tweaks
authorJim Pryor <profjim@jimpryor.net>
Sat, 4 Dec 2010 14:22:39 +0000 (09:22 -0500)
committerJim Pryor <profjim@jimpryor.net>
Sat, 4 Dec 2010 14:22:39 +0000 (09:22 -0500)
Signed-off-by: Jim Pryor <profjim@jimpryor.net>
translating_between_OCaml_Scheme_and_Haskell.mdwn

index 7b66cb3..171f644 100644 (file)
@@ -1,6 +1,6 @@
 The functional programming literature tends to use one of four languages: Scheme, OCaml, Standard ML (SML), or Haskell. With experience, you'll grow comfortable switching between these. At the beginning, though, it can be confusing.
 
-The easiest translations are between OCaml and SML. These languages are both derived from a common ancestor, ML. For the most part, the differences between them are only superficial. [Here's a translatio nmanual](http://www.mpi-sws.org/~rossberg/sml-vs-ocaml.html).
+The easiest translations are between OCaml and SML. These languages are both derived from a common ancestor, ML. For the most part, the differences between them are only superficial. [Here's a translatiomanual](http://www.mpi-sws.org/~rossberg/sml-vs-ocaml.html).
 
 In some respects these languages are closer to Scheme than to Haskell: Scheme, OCaml and SML all default to call-by-value evaluation order, and all three have native syntax for mutation and other imperative idioms (though that's not central to their design). Haskell is different in both respects: the default evaluation order is call-by-name (strictly speaking, it's "call-by-need", which is a more efficient cousin), and the only way to have mutation or the like is through the use of monads.
 
@@ -205,10 +205,10 @@ So we have:
                class Eq a where
                  (==)    :: a -> a -> Bool
 
-       This declares the type-class `Eq`; in order to belong to this class, a type `a` will have to supply its own implementation of the function ==, with the type a -> a -> Bool. Here is how the `Integer` class signs up to join the type-class:
+       This declares the type-class `Eq`; in order to belong to this class, a type `a` will have to supply its own implementation of the function `==`, with the type `a -> a -> Bool`. Here is how the `Integer` class signs up to join this type-class:
 
                instance Eq Integer where
-                 x == y  =  ...
+                 x == y  =  ... some definition for the Integer-specific version of that function here ...
 
        Type expressions can be conditional on some of their parameters belonging to certain type-classes. For example:
 
@@ -225,7 +225,7 @@ So we have:
 
        says that if `a` belongs to the typeclass `Eq`, then so too does `Tree a`, and in such cases here is the implementation of `==` for `Tree a`...
 
-*      OCaml doesn't have type-classes. You can do soemthing similar with OCaml modules that take are parameterized on other modules. Again, [see here](/code/tree_monadize.ml) for an example.
+*      OCaml doesn't have type-classes. You can do something similar with OCaml modules that take are parameterized on other modules. Again, [see here](/code/tree_monadize.ml) for an example.
 
 
 *      Some specific differences in how certain types are expressed. This block in Haskell:
@@ -237,7 +237,7 @@ So we have:
                Prelude> let x = () :: ()
                Prelude> let x = (1, True) :: (Int, Bool)
 
-corresponds to this block in OCaml:
+       corresponds to this block in OCaml:
 
                # type 'a option = None | Some of 'a;;
                type 'a option = None | Some of 'a
@@ -299,14 +299,17 @@ corresponds to this block in OCaml:
 
                List.map (fun x -> x * x) (List.filter odd [1..10]);;
 
-*      In Haskell, the expressions "abc" and ['a','b','c'] are equivalent. (Strings are just lists of chars. In OCaml, these expressions have two different types.
+*      In Haskell, the expressions "abc" and ['a','b','c'] are equivalent. (Strings are just lists of chars.) In OCaml, these expressions have two different types.
 
        Haskell uses the operator `++` for appending both strings and lists (since Haskell strings are just one kind of list). OCaml uses different operators:
 
-               "string1" ^ "string2"
-               ['s';'t'] @ ['r';'i';'n';'g']
-               (* or equivalently *)
-               List.append ['s';'t'] ['r';'i';'n';'g']
+               # "string1" ^ "string2";;
+               - : string = "string1string2"
+               # ['s';'t'] @ ['r';'i';'n';'g'];;
+               - : char list = ['s'; 't'; 'r'; 'i'; 'n'; 'g']
+               # (* or equivalently *)
+                 List.append ['s';'t'] ['r';'i';'n';'g'];;
+               - : char list = ['s'; 't'; 'r'; 'i'; 'n'; 'g']
 
 
 #Let and Where#
@@ -369,27 +372,27 @@ Haskell and OCaml both have `records`, which are essentially just tuples with a
 *      In Haskell one says:
 
                -- declare a record type
-               data Color = C { red, green, blue :: Int }
+               data Color = Col { red, green, blue :: Int }
                -- create a value of that type
-               let c = C { red = 0, green = 127, blue = 255 }
+               let c = Col { red = 0, green = 127, blue = 255 }
 
        In OCaml one says instead:
 
-               type color = { red : int; green : int; blue : int};;
+               type color = { red : int; green : int; blue : int };;
                let c = { red = 0; green = 127; blue = 255 }
 
-       Notice that OCaml doesn't use any value constructor `C`. The record syntax `{ red = ...; green = ...; blue = ... }` is by itself the constructor. The record labels `red`, `green`, and `blue` cannot be re-used for any other record type.
+       Notice that OCaml doesn't use any value constructor `Col`. The record syntax `{ red = ...; green = ...; blue = ... }` is by itself the constructor. The record labels `red`, `green`, and `blue` cannot be re-used for any other record type.
 
 *      In Haskell, one may have multiple constructors for a single record type, and one may re-use record labels within that type, so long as the labels go with fields of the same type:
 
                data FooType = Constructor1 {f :: Int, g :: Float} | Constructor2 {f :: Int, h :: Bool}
 
-*      In Haskell, one can extract the field of a record like this:
+*      In Haskell, one can extract a single field of a record like this:
 
-               let c = C { red = 0, green = 127, blue = 255 }
+               let c = Col { red = 0, green = 127, blue = 255 }
                in red c    -- evaluates to 0
 
-       In OCaml:
+       In OCaml one says:
 
                let c = { red = 0; green = 127; blue = 255 }
                in c.red    (* evaluates to 0 *)
@@ -397,7 +400,7 @@ Haskell and OCaml both have `records`, which are essentially just tuples with a
 *      In both languages, there is a special syntax for creating a copy of an existing record, with some specified fields altered. In Haskell:
 
                let c2 = c { green = 50, blue = 50 }
-               -- evaluates to C { red = red c, green = 50, blue = 50 }
+               -- evaluates to Col { red = red c, green = 50, blue = 50 }
 
        In OCaml:
 
@@ -406,7 +409,7 @@ Haskell and OCaml both have `records`, which are essentially just tuples with a
 
 *      One pattern matches on records in similar ways. In Haskell:
 
-               let C { red = r, green = g } = c
+               let Col { red = r, green = g } = c
                in r
 
        In OCaml:
@@ -416,11 +419,11 @@ Haskell and OCaml both have `records`, which are essentially just tuples with a
 
        In Haskell:
 
-               makegray c@(C { red = r} ) = c { green = r, blue = r }
+               makegray c@(Col { red = r } ) = c { green = r, blue = r }
 
        is equivalent to:
 
-               makegray c = let C { red = r } = c
+               makegray c = let Col { red = r } = c
                             in { red = r, green = r, blue = r }
 
        In OCaml it's:
@@ -486,7 +489,7 @@ Haskell and OCaml both have `records`, which are essentially just tuples with a
                  | x' when x' = 0 -> 0
                  | _ -> -1
 
-*      In Haskell the equality comparison operator is `==`, and the non-equality operator is `/=`. In OCaml, `==` expresses "physical identity", which has no analogue in Haskell because Haskell has no mutable types. See our discussion of "Four grades of mutable involvement" in the [[Week9]] notes. In OCaml the operator corresponding to Haskell's `==` is just `=`, and the corresponding non-equality operator is `<>`.
+*      In Haskell the equality comparison operator is `==`, and the non-equality operator is `/=`. In OCaml, `==` expresses "physical identity", which has no analogue in Haskell because Haskell has no mutable types. See our discussion of "Four grades of mutation involvement" in the [[Week9]] notes. In OCaml the operator corresponding to Haskell's `==` is just `=`, and the corresponding non-equality operator is `<>`.
 
 *      In both Haskell and OCaml, one can use many infix operators as prefix functions by parenthesizing them. So for instance:
 
@@ -494,10 +497,10 @@ Haskell and OCaml both have `records`, which are essentially just tuples with a
 
        will work in both languages. One notable exception is that in OCaml you can't do this with the list constructor `::`:
 
-       # (::) 1 [1;2];;
-       Error: Syntax error
-       # (fun x xs -> x :: xs) 1 [1; 2];;
-       - : int list = [1; 1; 2]
+               # (::) 1 [1;2];;
+               Error: Syntax error
+               # (fun x xs -> x :: xs) 1 [1; 2];;
+               - : int list = [1; 1; 2]
 
 *      Haskell also permits two further shortcuts here that OCaml has no analogue for. In Haskell, in addition to writing: