First I define the following data type
data Supply s a = S (Stream s -> (a, Stream s))
data Stream a = Cons a (Stream a)
Then I want to implement a function which maps to a Supply
with the following type signature:
mapSupply :: (a -> b) -> Supply s a -> Supply s b
And here is my implementation: (which compiles with no problem)
mapSupply :: (a -> b) -> Supply s a -> Supply s b
mapSupply mapFunc (S supFuncA) = S supFuncB where
supFuncB strm = let (la, strms) = supFuncA strm in
((mapFunc la), strms)
Then I met a problem when I tried to write down the type signature for the helper function named supFuncB
which I defined inside mapSupply
.
The type signature for supFuncB
is very simple and should be:
supFuncB :: Stream s -> (b, Stream s)
However when I tried to add the type signature in the code, I got a compiler error. The code looks like this
mapSupply :: (a -> b) -> Supply s a -> Supply s b
mapSupply mapFunc (S supFuncA) = S supFuncB where
supFuncB :: Stream s -> (b, Stream s)
supFuncB strm = let (la, strms) = supFuncA strm in
((mapFunc la), strms)
And then compiler complained:
• Couldn't match type ‘s1’ with ‘s’
‘s1’ is a rigid type variable bound by
the type signature for:
supFuncB :: forall s1 b1. Stream s1 -> (b1, Stream s1)
at Main.hs:58:5-41
‘s’ is a rigid type variable bound by
the type signature for:
mapSupply :: forall a b s. (a -> b) -> Supply s a -> Supply s b
at Main.hs:56:1-49
Expected type: Stream s1
Actual type: Stream s
• In the expression: strms
In the expression: ((mapFunc la), strms)
In the expression:
let (la, strms) = supFuncA strm in ((mapFunc la), strms)
I'm very new to Haskell and I don't understand why the compile would fail? And what should be the correct type signature if I were to add it in the code.
ScopedTypeVariables
kind of issue than a monomorphism restriction one -- there are no constraints to make the monomorphism restriction kick in. – duplodeScopedTypeVariables
you'd also need an explicitforall
to put the type variables into scope. see this answer (I'm not 100% sure this is an actual duplicate) – Mor A.mapSupply
justfmap
if you definetype Supply s a = State s a
? – chepner