Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# type definition using `of` keyword

Tags:

f#

Let me state that I am very green in F# (but 4 years experience in C#). I wanted to start learning F# and I was following the TryFSharp.org tutorials. I came to the point of the computation expressions but things weren't exactly clear. So I started to google it. I came across another tutorial / article which explained it a lot better in the first example (the logging example). But then I read on and came to the second example; I cannot follow the flow of the code or how it is supposed to work, perhaps because I don't understand the definition of the State type:

type State<'a, 's> = State of ('s -> 'a * 's)

I have worked with a few simple types in F# already, I have seen struct, class, record but I have no clue how to read this type or what it is supposed to do. I also can't figure out what the of keyword is doing in there.

So my question is: what does this type definition do / what does the of keyword in it do?

like image 411
SynerCoder Avatar asked Apr 18 '14 11:04

SynerCoder


2 Answers

The code defines a discriminated union type named State whose only constructor is also named State and takes an argument of type 's -> 'a * 's. The of keyword separated the constructor name from its argument type.

So basically it says that a State is a function of type 's -> 'a * 's, but you need to use the State constructor to create a State and thus have to write let myState = State someFunction rather than let myState = someFunction.

like image 178
sepp2k Avatar answered Oct 20 '22 15:10

sepp2k


As already stated, State is a single case discriminated union type. A two-case union type would look like:

type Multi = 
  | First of name:string
  | Second of number:int

One way to think of this is Multi as a base class and First and Second as subclasses where First requires a string in the constructor and Second requires an int. This is a very powerful construct not available in C#. It is powerful because you can pattern match of values of this type and the compiler will force you to handle every case.

A single case union is helpful as a wrapper of another type. In your example, the State type wraps a function from type 's to a pair (C# tuple) 'a * 's. It turns out that this is a very interesting type because it forms a monad and as a result you get all sorts of functions around it. For example, this gist shows how the State monad can be used to implement functional random value generators.

like image 32
eulerfx Avatar answered Oct 20 '22 15:10

eulerfx