Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do algebraic datatypes in Haskell equal discriminated unions in F#?

I am learning Haskell and would like to know whether the constructs known in Haskell as algebraic datatypes are the same that discriminated unions in F# or there are some subtle differences between them.

I would also appreciate much a good comparison between F# (my first functional language) and other functional languages, especially as regards similar concepts but with substantial but important differences.

like image 339
Alexander Galkin Avatar asked Nov 16 '11 17:11

Alexander Galkin


People also ask

Are the unions of f# discriminated?

What we need is a type that represents all possible integers PLUS all possible booleans. In other words, a “sum” type. In this case the new type is the “sum” of the integer type plus the boolean type. In F#, a sum type is called a “discriminated union” type.

What is an algebraic data type Haskell?

This is a type where we specify the shape of each of the elements. Wikipedia has a thorough discussion. "Algebraic" refers to the property that an Algebraic Data Type is created by "algebraic" operations. The "algebra" here is "sums" and "products": "sum" is alternation ( A | B , meaning A or B but not both)

How is a discriminated union defined?

Discriminated unions are useful for heterogeneous data; data that can have special cases, including valid and error cases; data that varies in type from one instance to another; and as an alternative for small object hierarchies. In addition, recursive discriminated unions are used to represent tree data structures.


2 Answers

(I come from OCaml, but I looked over the relevant F# stuff and it seems the same. Correct me if I'm wrong.) They are the same, just different terminology for the same thing, but there are a few syntactical differences. For example, to define a constructor with multiple data elements, in OCaml and F# you write the type as if they were stuffed in a tuple:

Haskell:

data Whatever = Foo TypeA TypeB

OCaml / F#:

type whatever = Foo of typeA * typeB

Similarly, to pattern match on it, you similarly act like a single argument that is a tuple with all the data members stuffed inside:

Haskell:

case x of Foo a b -> ...

OCaml / F#:

match x with Foo (a, b) -> ...

Edit: apparently the following does not apply in F#

Also, in Haskell the constructor automatically becomes a function that you can use by itself like any other value:

zipWith Foo xs ys

OCaml/F# don't do this. You could manually define your own functions for each constructor.

like image 69
newacct Avatar answered Oct 10 '22 21:10

newacct


I'm not very familiar with Haskell (I've only read Learn You a Haskell) but I haven't yet come across a basic difference between DUs and Haskell's algebraic data types--they're both attempts to model the same concept. Having said that, F# and Haskell have very different type systems (e.g., Haskell has type classes/higher-kinded types; F# is deeply grounded in OOP, etc.) so there is asymmetry, but nothing limited to these data types.

like image 36
Daniel Avatar answered Oct 10 '22 21:10

Daniel