Home > Back-end >  Haskell type inference with char
Haskell type inference with char

Time:10-28

I don't understand why when I look at the type for example of:
a = (1, 2)
I get a :: (Num a, Num b) => (a, b)
instead, if I look at the type of:
b = ('a', 'b')
I get b :: (Char, Char) and not something like: b :: (Char a, Char b) => (a, b)?

Thanks in advance!

CodePudding user response:

Num is a typeclass, it is a set of types, this looks a bit similar to what an interface is in Java/C#/... The types that are members of the Num typeclass need to implement a certain set of functions, like in Java where types that implement the interface should implement certain methods. A Char on the other hand is a type, not a typeclass.

If you write an integer literal, it can be of any type that is a member of the Num typeclass, since that typeclass has a function fromInteger :: Num a => Integer -> a that is then called to convert the integer literal to that number type.

If you write a char literal like 'a' on the other hand, then the only type to which this can be resolved is a Char.

For string literals, you can use the OverloadedStrings extension, in that case a string literal can take any type that is a member of the IsString typeclass.

CodePudding user response:

Haskell has two types of literals: monomorphic and polymorphic. (Though it might be more accurate to say, literals can evaluate to values of monomorphic or polymorphic types.)

'c' is an example of a monomorphic literal; it is a value of a single type, namely Char.

> :t 'c'
'c' :: Char

1, on the other hand, is a polymorphic literal. It can be a value of any type that has a Num instance.

> :t 1
1 :: Num p => p
> :t 1 :: Int
1 :: Int :: Int
> > :t 1 :: Char

<interactive>:1:1: error:
    • No instance for (Num Char) arising from the literal ‘1’
    • In the expression: 1 :: Char

Other polymorphic literals include

  1. Floating-point literals

    > :t 3.4
    3.4 :: Fractional p => p
    
  2. String literals, when the OverloadedStrings extension is enabled.

     > :t "foo"
     "foo" :: [Char]
     > :set -XOverloadedStrings
     > :t "foo"
     "foo" :: Data.String.IsString p => p
    
  3. List literals, when the OverloadedLists extension is enabled.

    > :t ['a', 'b']
    ['a', 'b'] :: [Char]
    > :set -XOverloadedLists
    > :t ['a', 'b']
    ['a', 'b'] :: (GHC.Exts.IsList l, GHC.Exts.Item l ~ Char) => l
    
  4. Data constructors like Nothing (if you want to think of nullary constructors as literals)

    > :t Nothing
    Nothing :: Maybe a
    

    Nothing, for example, can be a value of type Maybe Int, Maybe Char, etc.

  • Related