I’m currently learning both. But could someone elaborate ?
I think the main reason is namespacing. In Haskell defining a record type automatically defines (in the defining module) getter functions with the same names as the record fields. E.g.,
-- Business.hs
module Business (Emp, Dept, id, name) where
data Emp = Emp { id :: Int, name :: String, dept :: Dept }
data Dept = Dept { id :: Int, name :: String }
Now, which type are id
and name
referring to? Trick question, this is a compile error because it would create identifiers with the same names in the same module.
In OCaml though we can have multiple modules in the same file:
(* business.ml *)
module Dept = struct
type t = { id : int; name : string }
end
module Emp = struct
type t = { id : int; name : string; dept : Dept.t }
end
And by using the module name to prefix the field name, there is no ambiguity about which type should be inferred:
let dept_name { Dept.name } = name
But this is just a specific case of OCaml’s better modularity, which also helps with namespacing of data constructors (same way as record fields) and several other advantanges.
I think the modules are unnecessary for this, and just the record types suffice:
# type t = { a: int; b: string};;
type t = { a : int; b : string; }
# type s = { a: int; b: string};;
type s = { a : int; b : string; }
# let ex: (s * t) = {a = 1; b = "foo"}, {a = 2; b = "bar"};;
val ex : s * t = ({a = 1; b = "foo"}, {a = 2; b = "bar"})
Additional nice things in OCalm treatment of records are:
- inline record types of constructors
- record field punning
- nice syntax for record updates
I wouldn’t be surprised if all of these things (and more) are available in Haskell via one extension or another tho.
Haskell has the first and third built in, no language extensions needed.