MMacphail
MMacphail

Reputation: 561

How to get the maxBound of a type that has a Bounded instance

The following Haskell code does not compile:

getMaxBound :: (Bounded a) => a -> a
getMaxBound _ = maxBound :: a

The error I get is the following:

Could not deduce (Bounded a1) arising from a use of ‘maxBound’
  from the context: Bounded a
    bound by the type signature for:
               getMaxBound :: Bounded a => a -> a
    at rot13.hs:3:1-36

Why can't I get the maxBound of a bounded type in Haskell?

Ideally, I would use this function like this:

getMaxBound 3
> 9223372036854775807

getMaxBound 'c'
> '\1114111'

I feel like every time I have any type a which has a Bounded instance, I should be able to get the maxBound of that type.

What am I missing?

Upvotes: 2

Views: 1046

Answers (2)

sara
sara

Reputation: 3589

Willem's answer should work just fine in this case, but an alternative that might also be useful in more complicated cases is to use -XScopedTypeVariables

if you add the line {-# LANGUAGE ScopedTypeVariables #-} to the top of the file, your code should compile.

what the extension does is to allow you to reference the type variables from an outer scope in an inner scope. in your code, a gets shadowed in the function body, and there is no connection between it and the outer a, causing you to lose the Bounded a context!

Upvotes: 5

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476614

Type signature is sufficient

Since the signature already restricts the type, you can drop the :: a part in the function body:

getMaxBound :: Bounded a => a -> a
getMaxBound _ = maxBound

The type signature specifies that type of the input of the function is the same as the type of the output of the function.

For example:

Prelude> getMaxBound (3 :: Int)
9223372036854775807
Prelude> getMaxBound 'c'
'\1114111'
Prelude> getMaxBound True
True
Prelude> getMaxBound LT
GT

Using the ScopedTypeVariables extension

We can also use the ScopedTypeVariables extension [Haskell-wiki], and then implement it with a reference to the a type variable:

{-# LANGUAGE ScopedTypeVariables #-}

getMaxBound :: forall a . Bounded a => a -> a
getMaxBound _ = maxBound :: a

Upvotes: 4

Related Questions