Recently I sent a pull request to the PureScript compiler enabling type signatures on methods in instances. This is similar to the functionality enabled by the InstanceSigs extension in Haskell. This functionality should be available in the next version of the PureScript compiler, 0.11.5.
This article is for PureScripters who may not be familiar
InstanceSigs from Haskell. I will explain what this allows, and why you may want to use it.
What are type signatures in instances?
The following code shows an example of defining a datatype
Foo and writing an
Eq instance for it:
import Prelude data Foo = Foo Int String -- Here is what the Eq class looks like, -- in case you don't know it off the top of your head: -- class Eq a where -- eq :: a -> a -> Boolean instance eqFoo :: Eq Foo where eq (Foo int1 string1) (Foo int2 string2) = eq int1 int2 && eq string1 string2
The next version of the PureScript compiler will allow a type signature to be specified for
eq in the
Eq Foo instance:
instance eqFoo :: Eq Foo where eq :: Foo -> Foo -> Boolean eq (Foo int1 string1) (Foo int2 string2) = eq int1 int2 && eq string1 string2
Why would I want to use this?
There are three main reasons for putting signatures on methods in instances:
Let's think about the example above. The
Eqtype class is defined in the
Foodatatype and the
Eq Fooinstance may be defined in the module
My.Foo. When reading through the
My.Foomodule, the reader may not have the
Data.Eqmodule open, so they wouldn't be able to check what the type of
eqshould be. They would have to work it out from the value of the method. This may be somewhat difficult if they are not familiar with the surrounding code.
As a general rule of thumb, it is helpful for readers of your code if you specify type signatures on instance methods when the type class is not defined in the same module.
Personally, I like to specify type signatures on instance methods even when the instance is defined in the same module as the type class. People rarely complain about too many type signatures, but it can be a pain reading code with too few type signatures.
Sometimes it is preferable to do "type-driven development" when writing PureScript code. This usually means writing the type signature first and filling in the body of the method afterwards. When writing the body of the method, it is nice to have an explicit type signature to guide your code.
This is especially nice when you have a type class with multiple parameters and methods with complicated types.
To bring scoped type variables into scope. I show an example of this in the original proposal.
None of the three reasons above absolutely require instance signatures, but instance signatures make it a little nicer to write PureScript code.