darenn
darenn

Reputation: 479

Getting minBound of a bounded type

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

Answers (1)

chi
chi

Reputation: 116174

You need to enable the ScopedTypeVariables extension and use explicit foralls:

{-# 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

Related Questions