It is said structs are better in ocaml compared to haskell

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.

2 Likes

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.

1 Like

Haskell has the first and third built in, no language extensions needed.