I'm putting together a geometry library in haskell. I'm not intending to release it, it's just a project that I'm using to improve my knowledge of the language.
I have a Local datatype, with the following definition
data Local a where
MkLocal :: (Vectorise a) => ReferenceFrame -> a -> Local a
A reference frame is a Vector pointing to the origin of the frame and an angle representing the rotation of the frame, both defined wrt the "absolute" frame of reference (hey, it's not the real world!). A Vectorise geometry is one which has an invertible transformation into a list of Vector.
It occurred to me that Local could be an instance of Functor as follows:
instance Functor Local where
fmap f geom = localise (frame geom) (f $ local geom)
but the compiler complains that there is no instance of Vectorisable for the use of localise in the definition. Is there any way around this limitation using one of the myriad GHC extensions?
EDIT: As requested in the comments, here are some of the types used
local :: Local a -> a
frame :: Local a -> ReferenceFrame
localise :: (Vectorise a) => ReferenceFrame -> a -> Local a
The error is
No instance for (Vectorise b)
arising from a use of `localise'
In the expression:
localise (frame geom) (f $ local geom)
In an equation for `fmap':
fmap f lgeom = localise (frame geom) (f $ local geom))
In the instance declaration for `Functor Local'
Which makes sense, because the type for fmap is (a -> b) -> f a -> f b. It can infer that a must be an instance of Vectorise, but I was wondering how it could infer that b was, unless I could specify (somehow) I could tell the compiler that f must have the restricted return type without defining another typeclass when there is already one that almost fits the bill already (or alternately, if someone could helpfully explain why restricting classes in this way would break type inference somehow).
ps. I also fixed up a typo where I had reversed local and frame reversed in the definition of fmap
localise,localandframeand the error message that you get. My guess is that you're missinginstance VectoriseforLocal. - Mikhail Glushenkovfthat I need to declare asVectoriseas far as I can see, notLocal a. - ovangle