Haskell: Defining a variable inside a typeclass

Viewed 99

I am new to Haskell and I stumbled upon this problem while playing around with classes. So basically instead of defining functions inside a class, I want to define variables. In my case I'm defining a variable maxvalue inside the class Maxable. This worked just fine with Int. Now assuming a type a is an instance of Maxable, I want to define instance Maxable (Maybe a), which you can see in the third block of my code didn't work.

class Maxable a where
  maxvalue :: a

-- This works fine
instance Maxable Int where
  maxvalue = 2147483647

-- Error: Could not deduce (Maxable a1) arising from a use of ‘maxvalue’
instance Maxable a => Maxable (Maybe a) where
  maxvalue = maxvalue :: a

What should I replace maxvalue = maxvalue :: a with so that "(Maybe a).maxvalue == a.maxvalue" ?

1 Answers

You're actually really close to the right answer!

First, to actually solve the problem, you need to recognize that in your Maxable instance for Maybe a, the type of maxvalue needs to be of type Maybe a. However, in your definition, you're making it of type a. So, how do you turn a value of type a into a value of type Maybe a? You use the Just constructor. In short, you can write:

instance Maxable a => Maxable (Maybe a) where
  maxvalue = Just maxvalue

As it turns out, GHC is smart enough to use the right maxvalue without you even needing to use the :: a annotation.


But, what about that error you got? Why did it tell you something about Maxable a1? The problem that GHC is pointing out comes from the fact that you used the explicit type signature maxvalue :: a in your definition. By default, GHC does not scope type variables, so GHC didn't know that you wanted to use the same a there that you're using in your instance head. GHC assumed you just wanted a new, fresh type variable, which, internally, it decided to call a1. Then, it got confused at you because, while it knows that a is Maxable (because you said so in the instance context), it doesn't know that a1 is Maxable.

To get a better error message in this case, you can enable the GHC extension ScopedTypeVariables by adding

{-# LANGUAGE ScopedTypeVariables #-}

to the top of your file. If you run your current code with this language extension, you'll get a different error, with GHC complaining that a is not equal to Maybe a. As I stated above, this can be solved by using the Just constructor.

Related