For a uni assignment, we have been given a line of Haskell code which shows:
newtype TC a = TC ([Id] -> Either TypeError ([Id], a))
Firstly, TypeError is something which needs to be implemented by us for the assignment so I can't post the data declaration here, but my question is this. How do I read the code above? What is the a right after the newtype TC? I also don't understand how TC is being reused to the right of the equals sign.
I think a here is a type variable since newtype works similarly to data. I don't know how knowing this will help my understanding.
The
ain the newtype declarationexpresses much the same as the
xin a function declarationais a type parameter. So you'll be able to useTCas, for example,TC IntorTC Bool, similar to how you're able to useflikef 1orf "bla bla"(depending on its type).The case
TC Intis equivalent to the following alternative:That is a bit of a confusing quirk in Haskell. Actually
TCis not reused, rather you're declaring two separate entities which are both calledTC. You could also call them differently:TC_Tis a type constructor. This is the thing that will appear in type signatures, i.e.TC_T IntorTC_T Bool.TC_Vis a value constructor. You use this when, well, generating values of typeTC_T IntorTC_T Bool.So for example, you might write these:
With your original version it looks like this:
...but it's still two separate things both called
TVhere. Most newtypes in Haskell call the type- and value constructors the same, but often only the type constructor is exported from a module and the value constructor left as an implementation detail.Most of this is the same for
dataas fornewtype. You could as well have... the only difference to the newtype version is a subtle indirection: if it's
data, then the compiler inserts an indirection which allows a bit more lazyness, but in this case there's hardly a point to doing that.In practice, you generally use
dataonly when you need multiple constructors and/or a constructor with multiple fields, whichnewtypedoes not support.