import Diagrams.Prelude
import Diagrams.Backend.Cairo
type Dia = Diagram Cairo R2
class Turtlish t where
pic :: t s -> Dia
state :: t s -> s
move :: s -> t s -> t s
(>>>),(+++) :: t s -> t s -> t s
x >>> y = x +++ move (state x) y
But I have different turtles planned. I want a regular turtle, a Sankey turtle which also has a width, and we could imagine sub-turtles that only had the angle or only the position. But in all cases, I think the above class describes how I want to compose diagrams together. I already tried it with monads but I'm now thinking that I want something like the above instead of a monad.
data TurtState = TurtState P2 CircleFrac
data TurtWorld s = TurtWorld Dia s
I know exactly what s is above but otherwise the kinds don't match below.
instance Turtlish TurtWorld where
pic (TurtWorld d _) = d
state (TurtWorld _ s) = s
(TurtWorld d1 _) +++ (TurtWorld d2 s2) =
TurtWorld (d1 `atop` d2) s2
move (pp,aa) (TurtWorld d (p,a)) = TurtWorld
(d # rotate aa # translate pp)
( (p # rotate aa + pp) , (a+aa) )
Naturally, it barfs over move saying:
Couldn't match type `s' with `(R2, t0)'
`s' is a rigid type variable bound by
the type signature for move :: s -> TurtWorld s -> TurtWorld s
at turtle.hs:20:3
In the pattern: (pp, aa)
In an equation for `move':
move (pp, aa) (TurtWorld d (p, a))
= TurtWorld
(d # rotate aa # translate pp) ((p # rotate aa + pp), (a + aa))
In the instance declaration for `Turtlish TurtWorld'
because it hasn't a clue what (pp,aa) is and wants s totally generic anyway.
But what am I supposed to do instead? Isn't it an everyday thing to use a generic pattern with a specific type?
Adrian.