I'm having trouble with PureScript typeclasses. I have to say, up front, that I'm not a Haskell expert either so my apologies if these are obvious errors.
I've tried several different approaches and hit a wall for each. I'm basically trying to define a show
function for an edge in a graph. One approach looks like this:
module Foo where
data Edge n = Edge { from :: n, to :: n }
instance showEdge :: (Show n) => Show (Edge n) where
show e = "Edge from "++(show e.from)++" to "++(show e.to)
e = Edge { from: 1, to: 2 }
main = show e
This gives me the error:
$ psc src/Attempt1.purs
Error at src/Attempt1.purs line 6, column 27:
Error in declaration showEdge
Cannot unify Prim.Object with Foo.Edge.
I'm guessing this has something to do with the fact that it is inferring the type of e
in the definition of show
. I tried adding a type annotation here, but I get a syntax error:
module Foo where
data Edge n = Edge { from :: n, to :: n }
instance showEdge :: (Show n) => Show (Edge n) where
show e :: Edge n
show e = "Edge from "++(show e.from)++" to "++(show e.to)
e = Edge { from: 1, to: 2 }
main = show e
The second thing I tried was this:
module Foo where
type Edge n = { from :: n, to :: n }
instance showEdge :: (Show n) => Show (Edge n) where
show e = "Edge from "++(show e.from)++" to "++(show e.to)
e :: Edge Number
e = { from: 1, to: 2 }
main = show e
This gives me:
$ psc src/Attempt2.purs
Error at src/Attempt2.purs line 5, column 1:
Type synonym instances are disallowed
So I then tried explicitly listing the underlying type:
module Foo where
type Edge n = { from :: n, to :: n }
instance showEdge :: (Show n) => Show { from :: n, to :: n } where
show e = "Edge from "++(show e.from)++" to "++(show e.to)
e :: Edge Number
e = { from: 1, to: 2 }
main = show e
which gives me:
$ psc src/Attempt3.purs
Error at src/Attempt3.purs line 5, column 1:
Error in type (to :: n, from :: n):
Type class instance head is invalid.
I have no idea what the "type class instance head" is, so I've got nowhere to go from there.
All three attempts failed. Probably for completely different reasons. Being new to PureScript, I just don't know what the issue is. I've been trying to following along looking at examples from the various Data.*
types and reading PureScript by Example. I haven't been able to figure this out.
Thanks for any assistance.
Actually, you were almost there with your first attempt, the problem you have here is Edge
is a data constructor with one field containing an object, whereas the same syntax in Haskell is defining functions for accessing several fields in your data.
Haskell doesn't have objects/records as first class objects the way PureScript does, so all you need to do is unwrap the object from your Edge
:
show (Edge e) = "Edge from " ++ show e.from ++ " to " ++ show e.to
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With