Haskell seems to be having trouble resolving 'g == [a]' when performing type inference. Any ideas how to make this work?
Thx
module X where
import Control.Monad.State.Lazy
class Generator g where
next :: State g a
instance Generator ([] a) where
next = nextL
nextL :: State [a] a
nextL = state $ split
split :: [a] -> (a, [a])
split l = (head l, tail l)
Reid's right in his comment. When you write
class Generator g where
next :: State g a
you're really saying
class Generator g where
next :: forall a. State g a
so that from a given state in g
, your clients can generate an element of whatever type a
they wish for, rather than whatever type is being supplied by the state in g
.
There are three sensible ways to fix this problem. I'll sketch them in the order I'd prefer them.
Plan A is to recognize that any generator of things is in some sense a container of them, so presentable as a type constructor rather than a type. It should certainly be a Functor
and with high probability a Comonad
. So
class Comonad f => Generator f where
move :: forall x. f x -> f x
next :: forall x. State (f x) x
next = state $ \ g -> (extract g, move g)
-- laws
-- move . duplicate = duplicate . move
instance Generator [] where
move = tail
If that's all Greek to you, maybe now is your opportunity to learn some new structure on a need-to-know basis!
Plan B is to ignore the comonadic structure and add an associated type.
class Generator g where
type From g
next :: State g (From g)
instance Generator [a] where
type From [a] = a
next = state $ \ (a : as) -> (a, as)
Plan C is the "functional dependencies" version, which is rather like MonadSupply, as suggested by Cirdec.
class Generator g a | g -> a where
next :: State g a
instance Generator [a] a where
next = state $ \ (a : as) -> (a, as)
What all of these plans have in common is that the functional relationship between g
and a
is somehow acknowledged. Without that, there's nothing doing.
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