But assuming you do manage to compile and install Oleg's library, here's how you'd use it in an OCaml session:
#require "delimcc";; (* loading Oleg's library this way requires the findlib package *)
+ (* if you don't have findlib, you'll need to start ocaml like
+ * this instead: ocaml -I /path/to/directory/containing/delimcc delimcc.cma
+ *)
open Delimcc;; (* this lets you say e.g. new_prompt instead of Delimcc.new_prompt *)
let p = new_prompt ();;
let prompt thunk = push_prompt p thunk;;
We will however try to give some general advice about how to translate between OCaml and Haskell.
* Again, it may sometimes be useful to [try Haskell in your web browser](http://tryhaskell.org/)
-* There are many Haskell tutorials and textbooks available. This is probably the most actively developed: [Haskell Wikibook](http://en.wikibooks.org/wiki/Haskell)
-* [Yet Another Haskell Tutorial](http://www.cs.utah.edu/~hal/docs/daume02yaht.pdf) (much of this excellent book has supposedly been integrated into the Haskell Wikibook)
-* All About Monads has supposedly also been integrated into the Haskell Wikibook
+* There are many Haskell tutorials and textbooks available. This is probably the most actively developed: [Haskell wikibook](http://en.wikibooks.org/wiki/Haskell)
+* [Yet Another Haskell Tutorial](http://www.cs.utah.edu/~hal/docs/daume02yaht.pdf) (much of this excellent book has supposedly been integrated into the Haskell wikibook)
+* All About Monads has supposedly also been integrated into the Haskell wikibook
* (A not-so-)[Gentle Introduction to Haskell](http://web.archive.org/web/http://www.haskell.org/tutorial/) (archived)
* [Learn You a Haskell for Great Good](http://learnyouahaskell.com/)
type Weight = Integer
type Person = (Name, Address) -- supposing types Name and Address to be declared elsewhere
- then you can use a value of type `Integer` wherever a `Weight` is expected, and vice versa. `newtype` and `data` on the other hand, create genuinely new types. `newtype` is basically just an efficient version of `data` that you can use in special circumstances. `newtype` must always take one type argument and have one value constructor. For example:
+ then you can use a value of type `Integer` wherever a `Weight` is expected, and vice versa. <!-- `type` is allowed to be parameterized -->
+
+ `newtype` and `data` on the other hand, create genuinely new types. `newtype` is basically just an efficient version of `data` that you can use in special circumstances. `newtype` must always take one type argument and have one value constructor. For example:
newtype PersonalData a = PD a
You could also say:
- data PersonalData a = PD a
+ data PersonalData2 a = PD2 a
- And `data` also allows multiple type arguments, and multiple variants and value constructors.
+ And `data` also allows multiple type arguments, and multiple variants and value constructors. <!-- Subtle difference: whereas `PersonalData a` is isomorphic to `a`, `PersonalData2 a` has an additional value, namely `PD2 _|_`. In a strict language, this is an additional type an expression can have, but it would not be a value. -->
OCaml just uses the one keyword `type` for all of these purposes:
type person = name * address;;
type 'a personal_data = PD of 'a;;
+* When a type only has a single variant, as with PersonalData, Haskell programmers will often use the same name for both the type and the value constructor, like this:
+
+ data PersonalData3 a = PersonalData3 a
+
+ The interpreter can always tell from the context when you're using the type name and when you're using the value constructor.
+
* The type constructors discussed above took simple types as arguments. In Haskell, types are also allowed to take *type constructors* as arguments:
data BarType t = Bint (t Integer) | Bstring (t string)
##Records##
-Haskell and OCaml both have `records`, which are essentially just tuples with a pretty interface. The syntax for declaring and using these is a little bit different in the two languages.
+Haskell and OCaml both have `records`, which are essentially just tuples with a pretty interface. We introduced these in the wiki notes [here](/coroutines_and_aborts/).
+
+The syntax for declaring and using these is a little bit different in the two languages.
* In Haskell one says:
In OCaml:
- let { red = r; green = g } = c
+ let { red = r; green = g; _ } = c
in r
In Haskell:
In OCaml it's:
- # let makegray ({red = r} as c) = { c with green=r; blue=r };;
+ # let makegray ({ red = r; _ } as c) = { c with green=r; blue=r };;
val makegray : color -> color = <fun>
# makegray { red = 0; green = 127; blue = 255 };;
- : color = {red = 0; green = 0; blue = 0}
+* Records just give your types a pretty interface; they're entirely dispensable. Instead of:
+
+ type color = { red : int; green : int; blue : int };;
+ let c = { red = 0; green = 127; blue = 255 };;
+ let r = c.red;;
+
+ You could instead just use a more familiar data constructor:
+
+ type color = Color of (int * int * int);;
+ let c = Color (0, 127, 255);;
+
+ and then extract the field you want using pattern-matching:
+
+ let Color (r, _, _) = c;;
+ (* or *)
+ match c with Color (r, _, _) -> ...
+
+ (Or you could just use bare tuples, without the `Color` data constructor.)
+
+ The record syntax only exists because programmers sometimes find it more convenient to say:
+
+ ... c.red ...
+
+ than to reach for those pattern-matching constructions.
+
+
##Functions##
which can be translated straightforwardly into OCaml.
+ For more details, see:
+
+ * [Haskell wikibook on do-notation](http://en.wikibooks.org/wiki/Haskell/do_Notation)
+ * [Yet Another Haskell Tutorial on do-notation](http://en.wikibooks.org/wiki/Haskell/YAHT/Monads#Do_Notation)
+ * [Do-notation considered harmful](http://www.haskell.org/haskellwiki/Do_notation_considered_harmful)
+
* If you like the Haskell do-notation, there's [a library](http://www.cas.mcmaster.ca/~carette/pa_monad/) you can compile and install to let you use something similar in OCaml.
* In order to do any printing, Haskell has to use a special `IO` monad. So programs will look like this: