Horsy
Horsy

Reputation: 75

Haskell Generic Type

So I just started learning Haskell and I have been stuck on this for quite some time already. So I have a function that calculates a number after an offset has been minus (minimum value is 0). I managed to do this function with the types explicitly shown.

offSetter :: Int -> Int -> Int
offSetter number offset
    | number - offset >= 0 = number - offset
    | otherwise = 0

But when I tried to change it to use generic types as below, it keeps giving me an error. Am I doing it wrong?

offSetter :: Num a => a -> a -> a
offSetter number offset
    | number - offset >= 0 = number - offset
    | otherwise = 0

The error I'm getting:

* Could not deduce (Ord a) arising from a use of '>='
      from the context: Num a
        bound by the type signature for:
                   offSetter :: forall a. Num a => a -> a -> a
        at src\test.hs:57:1-33
      Possible fix:
        add (Ord a) to the context of
          the type signature for:
            offSetter :: forall a. Num a => a -> a -> a
    * In the expression: number - offset >= 0
      In a stmt of a pattern guard for
                     an equation for `offSetter':
        number - offset >= 0

Upvotes: 0

Views: 169

Answers (2)

Code-Apprentice
Code-Apprentice

Reputation: 83567

As you discovered, you need to add the type class Ord as a constraint to the type a with the following type signature:

offSetter :: (Num a, Ord a) => a -> a -> a

This is because Ord is the typeclass with comparison operators like (>=).

So Ord is used because there are elements like Strings that is not applicable to Num?

No, since String is not a member of the Num typeclass, the original declaration already excludes it as a possible candidate for the type a. As I stated earlier, you need to use Ord in order to guarantee that the type a has the operator (>=) available.

Upvotes: 4

Horsy
Horsy

Reputation: 75

Solved it by adding Ord a:

offSetter :: (Num a, Ord a) => a -> a -> a
offSetter number1 offSet
    | number1 - offSet >= 0 = number1 - offSet
    | otherwise = 0

Upvotes: 4

Related Questions