Skip to content

References Tutorial

Boldizsár Németh edited this page Sep 30, 2016 · 4 revisions

What is a reference?

A reference is a property accessor. You can think of it as a setter and getter method. For example if you have a point datatype: data Point = Point Double Double then, you may define references x and y to access the two Double values inside the point. You can use the reference to get their values and also to modify them.

Why do we need references?

The simplest problem references solve is the problem of handling a large nested data structure. For example, take the following datatypes:

data Arrow = Arrow { from :: Point, to :: Point }
data Point = Point { x :: Double, y :: Double }

If you want to shift the arrow, you have to define a function that takes it to parts and repacks it:

shiftArrowX :: Double -> Arrow -> Arrow
shiftArrowX d (Arrow (Point fromX fromY) (Point toX toY)) 
  = Arrow (Point (fromX + d) fromY) (Point (toX + d) toY)

This packing and repacking gets more complicated each time the representation grows. The references library solves this problem by letting you define references:

data Arrow = Arrow { _from :: Point, _to :: Point }
data Point = Point { _x :: Double, _y :: Double }
makeReferences ''Arrow
makeReferences ''Point

Then shiftArrowX can be defined using references:

shiftArrowX :: Double -> Arrow -> Arrow
shiftArrowX d = (from &+& to) & y .- (+d)

What is the type of a reference?

The type of :t from is (Monad w, Monad r) => Reference w r MU MU Arrow Arrow Point Point

The first 4 type variables are the write-read semantic monads of the reference. The last 4 are the type of the context type, and the accessed element.

We don't have any constraints (aside from Monad) for w and r, and that shows that the from element is always present in an arrow. Here the context type and the accessed element is present twice in the type. In other cases when the data type is polymorphic, using a reference may actually change the type of the context. For example, the type of the context and elements types for the reference just (that accesses the possible existing element inside a Maybe value) will be: (Maybe a) (Maybe b) a b. That shows that by replacing the element inside a just with something of type b, you will get a (Maybe b) as a result

Clone this wiki locally