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
Floating-point literals
> :t 3.4 3.4 :: Fractional p => pString literals, when the
OverloadedStringsextension is enabled.> :t "foo" "foo" :: [Char] > :set -XOverloadedStrings > :t "foo" "foo" :: Data.String.IsString p => pList literals, when the
OverloadedListsextension is enabled.> :t ['a', 'b'] ['a', 'b'] :: [Char] > :set -XOverloadedLists > :t ['a', 'b'] ['a', 'b'] :: (GHC.Exts.IsList l, GHC.Exts.Item l ~ Char) => lData constructors like
Nothing(if you want to think of nullary constructors as literals)> :t Nothing Nothing :: Maybe aNothing, for example, can be a value of typeMaybe Int,Maybe Char, etc.
