The following which uses FooA
explicitly as the type in (#)
and in queryP
compiles as expected:
{-# LANGUAGE RankNTypes, ScopedTypeVariables #-}
module Foo where
class Foo a where
newtype FooParser a = FooParser { (#) :: FooA -> (a, FooA) }
queryP :: (FooA -> a) -> FooParser a
queryP f = FooParser $ \(b :: FooA) -> (f b, b)
data FooA = FooA Int
instance Foo FooA where
But when I try to define FooParser
and queryP
using the typeclass Foo
like so:
{-# LANGUAGE RankNTypes, ScopedTypeVariables #-}
module Foo where
class Foo a where
newtype FooParser a = FooParser { (#) :: Foo b => b -> (a, b) }
queryP :: Foo b => (b -> a) -> FooParser a
queryP f = FooParser $ \(b :: Foo b => b) -> (f b, b)
I get a could-not-deduce error:
Foo.hs:11:52:
Could not deduce (b ~ b1)
from the context (Foo b)
bound by the type signature for
queryP :: Foo b => (b -> a) -> FooParser a
at Foo.hs:10:11-42
or from (Foo b1)
bound by a type expected by the context: Foo b1 => b1 -> (a, b1)
at Foo.hs:11:12-53
‘b’ is a rigid type variable bound by
the type signature for queryP :: Foo b => (b -> a) -> FooParser a
at Foo.hs:10:11
‘b1’ is a rigid type variable bound by
a type expected by the context: Foo b1 => b1 -> (a, b1)
at Foo.hs:11:12
Relevant bindings include
b :: Foo b => b (bound at Foo.hs:11:26)
f :: b -> a (bound at Foo.hs:11:8)
queryP :: (b -> a) -> FooParser a (bound at Foo.hs:11:1)
In the expression: b
In the expression: (f b, b)
How can I specify that the b
in the lambda function in queryP
is of the same instance of the typeclass Foo
as in the first parameter of f
?