```
type Either α β = Left α | Right β
```

Some terminology: in this type declaration, `Either` is known as a *type-constructor*, since it takes some types `α`

and `β`

as arguments and yields a new type. We call `Left α`

one of the *variants* for the type `Either α β`

. `Left` and `Right` are known as *value constructors* or *data constructors* or just *constructors*. You can use `Left` in any context where you need a function, for example:
map Left [1, 2]
In OCaml, value constructors are still capitalized, but type names are lowercase. Type variables take the form `'a` instead of `a`, and if there are multiple type variables, they're not Curried but instead have to be grouped in a tuple. The syntax for whether they appear first or second is also somewhat different. So we have instead:
type ('a,'b) either = Left of 'a | Right of 'b;;
type ('a,'b) foo_type = Foo_constructor1 of 'a * 'b | Foo_constructor2 of 'a * 'b;;
In OCaml, constructors aren't full-fledged functions, so you need to do this instead:
List.map (fun x -> Left x) [1; 2]
Apart from these differences, there are many similarities between Haskell's and OCaml's use of constructors. For example, in both languages you can do:
let Left x = Left 1 in x + 1
* In addition to the `data` keyword, Haskell also sometimes uses `type` and `newtype` to declare types. `type` is used just to introduce synonyms. If you say:
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:
newtype PersonalData a = PD a
You could also say:
data PersonalData a = PD a
And `data` also allows multiple type arguments, and multiple variants and value constructors.
OCaml just uses the one keyword `type` for all of these purposes:
type weight = int;;
type person = name * address;;
type 'a personal_data = PD of 'a;;
* 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)
One does this for example when defining monad transformers---the type constructor `ReaderT` takes some base monad's type constructor as an argument.
The way to do this this in OCaml is less straightforward. [See here](/code/tree_monadize.ml) for an example.
* Haskell has a notion of *type-classes*. They look like this:
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 this type-class:
instance Eq Integer where
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:
elem :: (Eq a) => a -> [a] -> Bool
says that the function `elem` is only defined over types `a` that belong to the type-class `Eq`. For such types `a`, `elem` has the type `a -> [a] -> Bool`.
Similarly:
instance (Eq a) => Eq (Tree a) where
Leaf a == Leaf b = a == b
(Branch l1 r1) == (Branch l2 r2) = (l1==l2) && (r1==r2)
_ == _ = False
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 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:
Prelude> type Maybe a = Nothing | Just a
Prelude> let x = [] :: [Int]
Prelude> :t x
x :: [Int]
Prelude> let x = () :: ()
Prelude> let x = (1, True) :: (Int, Bool)
corresponds to this block in OCaml:
# type 'a option = None | Some of 'a;;
type 'a option = None | Some of 'a
# let (x : int list) = [];;
val x : int list = []
# let (x : unit) = ();;
val x : unit = ()
# let (x : int * bool) = (1, true);;
val x : int * bool = (1, true)
* Haskell has a plethora of numerical types, including the two types `Int` (integers limited to a machine-dependent range) and `Integer` (unbounded integers). The same arithmetic operators (`+` and so on) work for all of these. OCaml also has several different numerical types (though not as many). In OCaml, by default, one has to use a different numerical operator for each type:
# 1 + 2;;
- : int = 3
# 1.0 + 2.0;;
Error: This expression has type float but an expression was expected of type int
# 1.0 +. 2.0;;
- : float = 3.
However the comparison operators are polymorphic. You can equally say:
# 1 = 2;;
- : bool = false
# 1.0 = 2.0;;
- : bool = false
# 2 > 1;;
- : bool = true
# 2.0 > 1.0;;
- : bool = true
But you must still apply these operators to expressions of the same type:
# 2.0 > 1;;
Error: This expression has type int but an expression was expected of type float
* We'll discuss differences between Haskell's and OCaml's record types below.
#Lists, Tuples, Unit, Booleans#
* As noted above, Haskell describes the type of a list of `Int`s as `[Int]`. OCaml describes it as `int list`. Haskell describes the type of a pair of `Int`s as `(Int, Int)`. OCaml describes it as `int * int`. Finally, Haskell uses `()` to express both the unit type and a value of that type. In OCaml, one uses `()` for the value and `unit` for the type.
* Haskell describes the boolean type as `Bool` and its variants are `True` and `False`. OCaml describes the type as `bool` and its variants are `true` and `false`. This is an inconsistency in OCaml: other value constructors must always be capitalized.
* As noted above, in Haskell one builds up a list by saying `1 : [2, 3]`. In OCaml one says `1 :: [2; 3]`. In Haskell, one can test whether a list is empty with either:
lst == []
null lst
In OCaml, there is no predefined `null` or `isempty` function. One can still test whether a list is empty using the comparison `lst = []`.
* In Haskell, the expression [1..5] is the same as [1,2,3,4,5], and the expression [0..] is a infinite lazily-evaluated stream of the natural numbers. In OCaml, there is no [1..5] shortcut, lists must be finite, and they are eagerly evaluated. It is possible to create lazy streams in OCaml, even infinite ones, but you have to use other techniques than the native list type.
* Haskell has *list comprehensions*:
[ x * x | x <- [1..10], odd x]
In OCaml, one has to write this out longhand:
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.
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";;
- : 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#
* Haskell permits both:
foo x =
let result1 = x * x
result2 = x + 1
in result1 + result2
and:
foo x = result1 + result2
where result1 = x * x
result2 = x + 1
OCaml permits only:
let foo x =
let result1 = x * x
in let result2 = x + 1
in result1 + result2;;
#Patterns#
* In OCaml:
# let (x, y) as both = (1, 2)
in (both, x, y);;
- : (int * int) * int * int = ((1, 2), 1, 2)
The same in Haskell:
let both@(x,y) = (1, 2)
in (both, x, y)
* In OCaml:
match list_expression with
| y::_ when odd y -> result1
| y::_ when y > 5 -> result2
| y::_ as whole -> (whole, y)
| [] -> result4
The same in Haskell:
case list_expression of
(y:_) | odd y -> result1
| y > 5 -> result2
whole@(y:_) -> (whole, y)
[] -> result4
#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.
* In Haskell one says:
-- declare a record type
data Color = Col { red, green, blue :: Int }
-- create a value of that type
let c = Col { red = 0, green = 127, blue = 255 }
In OCaml one says instead:
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 `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 a single field of a record like this:
let c = Col { red = 0, green = 127, blue = 255 }
in red c -- evaluates to 0
In OCaml one says:
let c = { red = 0; green = 127; blue = 255 }
in c.red (* evaluates to 0 *)
* 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 Col { red = red c, green = 50, blue = 50 }
In OCaml:
let c2 = { c with green = 50; blue = 50 }
(* evaluates to { red = c.red; green = 50; blue = 50 }
* One pattern matches on records in similar ways. In Haskell:
let Col { red = r, green = g } = c
in r
In OCaml:
let { red = r; green = g } = c
in r
In Haskell:
makegray c@(Col { red = r } ) = c { green = r, blue = r }
is equivalent to:
makegray c = let Col { red = r } = c
in { red = r, green = r, blue = r }
In OCaml it's:
# let makegray ({red = r} as c) = { c with green=r; blue=r };;
val makegray : color -> color =