It’s a horribly contrived example, but anyway… this typechecks:
newtype Foo c = Foo { runFoo :: c -> Bool }
newtype Bar c = Bar { runBar :: Int -> c }
foo :: Eq c => Bar c -> (c -> [c]) -> Bar (Foo c)
foo bar f = Bar res
where res n = Foo judge
where judge c = (c`elem`) . f $ runBar bar n
and works
GHCi> let foo0 = foo (Bar id) (\n -> [n, n*2])
GHCi> map (runFoo $ runBar foo0 4) [1..10]
[False,False,False,True,False,False,False,True,False,False]
but if I add the obvious type signature to the local function judge,
foo :: Eq c => Bar c -> (c -> [c]) -> Bar (Foo c)
foo bar f = Bar res
where res n = Foo judge
where judge :: c -> Bool
judge c = (c`elem`) . f $ runBar bar n
it fails with
Could not deduce (c ~ c2)
from the context (Eq c)
bound by the type signature for
foo :: Eq c => Bar c -> (c -> [c]) -> Bar (Foo c)
and so on. Hardly surprising in Haskell 98, but I’d think ScopedTypeVariables should allow to write such signatures, but apparently it doesn’t. Is there a specific reason for this, is it intentional that it doesn’t work with nested wheres, and what workarounds are there if this turns up in a comparable real-word problem?
Apparently you forgot to bring the type variable
cinto scope with an explicitforall,compiles fine.
ScopedTypeVariablesby itself doesn’t bring the type variables from the signature into scope, only those with an explicitforallare brought into scope.