Reputation: 479
I've been trying to do something like:
f :: (Enum a, Bounded a) => A a b -> [(a,b)]
f x = [(as,bs) | as <- [minBound :: a ..] , bs <- x somefunction as]
but the minbound there doesnt seem to work. how can I get that?
Upvotes: 3
Views: 445
Reputation: 116174
You need to enable the ScopedTypeVariables
extension and use explicit forall
s:
{-# ScopedTypeVariables #-}
f :: forall a b . (Enum a, Bounded a) => A a b -> [(a,b)]
f x = [(as,bs) | as <- [minBound :: a ..] , bs <- x somefunction as]
Without this, in Haskell every type signature is interpreted independently from the others. That is the a
in minBound :: a
has nothing to do with the a
in the signature above.
If you really want to stick with no extensions, you can write an auxiliary function instead:
myBound :: Bounded a => A a b -> a
myBound x = minBound -- does not really depend on x
f :: (Enum a, Bounded a) => A a b -> [(a,b)]
f x = [(as,bs) | as <- [myBound x ..] , bs <- x somefunction as]
In this specific case, as @dfeuer points out below, there is a much simpler solution. We can simply remove the type annotation on minBound
:
-- no extensions
f :: (Enum a, Bounded a) => A a b -> [(a,b)]
f x = [(as,bs) | as <- [minBound ..] , bs <- x somefunction as]
This works because the list comprehension outputs pairs (as,bs)
, so Haskell can see that as
must have type a
, and that minBound
must be of the same type of as
.
Upvotes: 7