Thanks, but I still don't know how to fix it.
In the meantime, I'm struggling with something more basic. I plan to write a basic monad that puts diagrams on top of each other, then I'll let State take care of pushing the origin and angle along (turtle style). But I'm already stuck on that basic monad.
It's >>= has to explicitly use the fact that each monad has a journey there and a journey back. The thing on the right of >>= will be inserted in between them. But I always get either "something is a rigidly bound type variable" or "Monad should have kind * -> *"
I just don't know how this is supposed to work.
I want the monad to contain two trails, in the sense of the Diagrams module. If I bind two of them together, for the time being, I'll just stick them on top of each other (at least I think the State monad will rescue me from that.) I have no particular reason to tell the thing on the right of >>= about the thing on the left. Neither do I have a reason for >>= to be polymorphic.
Right now I'm thinking that I'll have to define a class for things that provide a journey there and a journey back. I'd rather not, because there's only one of them but I can't seem to restrict the game any other way, but this way isn't helping either.
Ideally I'd be able to write something like this:
data Sankey = Sankey {there, back :: Trail R2}
instance Monad Sankey where
return t b = Sankey t b
l@(Sankey t b) >>= f = let (Sankey t' b') = f l in
Sankey (t <> t') (b <> b')
although I have no reason to pass l to f. But the compiler barfs anyway. I feel that Haskell is more complicated than what I'm trying to do. Under duress I tried:
class Pic a where
there :: a -> Trail R2
back :: a -> Trail R2
data Trails p = Trails p
instance (Pic p) => Monad (Trails p) where
return = Trails
(Trails l) >>= f = let (Trails r) = f l in
((there l <> there r),(back r <> back l))
But it doesn't like that either. What am I missing?
Adrian.