As far as usage and syntax go,
newtype is basically the same as
data except that a
newtype can have only one field and one constructor. Easy enough.
For me, the part that took some time to sink in is that it’s possible for the field to be a function.
It’s important to note that the right hand side defines the constructor of the type. In this case the constructor takes a function that takes a single arg
s and returns a tuple
This matches the way that data constructors work - the right hand side defines the constructor function. This is the part that caused me some confusion. I knew how to define and use
data but the penny hadn’t fully dropped that the parameters on the left hand side were not used to define the constructor. I thought of the right hand side as purely for defining the accessor functions.
In hindsight this is obvious but isn’t that always the case?
As a dumb example we can create a silly function that makes a tuple and use that in the constructor
We now have an instance of the
Foo type wrapped around our (partially applied)
makeTuple function. If we compare
runFoo we can see that that mirror each other and can be used to wrap and unwrap the function
s -> (s, a)
Note that when applying
Foo instance) we can see that we need one more argument to be passed in order to get back the tuple.
and the one line version