Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the type of Nothing in Haskell?

Tags:

I'm at page 118 of the book "Learn You a Haskell for Great Good!"

It is written there:

ghci> :t Nothing  Nothing :: Maybe a 

Here is my question:

If I understand correctly, Nothing is a value and only concrete types can have values, but Maybe a is not a concrete type. So how can it have the value Nothing?

The book also says:

Notice that the type of Nothing is Maybe a. Its type is polymorphic.

What does polymorphic type mean? How should I understand this? Is this not in contradiction with the rule that only concrete types can have values?

EDIT:

From the PDF version of the book :

We say that a type is concrete if it doesn't take any type parameters at all (like Int or Bool), or if it takes type parameters and they're all filled up (like Maybe Char). If you have some value, its type is always a concrete type.

like image 324
jhegedus Avatar asked Feb 27 '14 10:02

jhegedus


People also ask

What is just and nothing in Haskell?

The type has two constructors, Just a and Nothing . When a type has multiple constructors, it means that a value of the type must have been constructed with just one of the possible constructors. For this type, a value was either constructed via Just or Nothing , there are no other (non-error) possibilities.

What is empty Haskell?

From HaskellWiki. An empty type is one that has no values. They're often used with phantom types or type arithmetic.

What are types in Haskell?

In Haskell, every statement is considered as a mathematical expression and the category of this expression is called as a Type. You can say that "Type" is the data type of the expression used at compile time. To learn more about the Type, we will use the ":t" command.

What is a data type in Haskell?

The Haskell standard data type Maybe is typically declared as: data Maybe a = Just a | Nothing. What this means is that the type Maybe has one type variable, represented by the a and two constructors Just and Nothing. (Note that Haskell requires type names and constructor names to begin with an uppercase letter).


Video Answer


2 Answers

It's not in contradiction. Nothing is a value, and its concrete type may be any possible instantiation of Maybe a.

Otherwise said, values of type Maybe a continue to have concrete types Maybe Int, Maybe String, Maybe Whatever, and in particular, Nothing is able to be typed by each of them, depending on the context. That's because its constructor, which is again called Nothing :: Maybe a, does not take any parameters and therefore it can be called as-is to generate values of type Maybe a. We will have one per concrete type, if you wish.

Without a context, of course ghci will give you the most general type it can infer for Nothing, which is Maybe a, but it's not its concrete type. That will depend on the individual expressions you will use Nothing in. E.g.:

ghci> Nothing Nothing it :: Maybe a 

This is what you probably typed, or something like that. There is no further context, therefore Nothing doesn't get typed with a concrete type.

ghci> Nothing :: Maybe Int Nothing it :: Maybe Int 

Here I forced it to assume the concrete type Maybe Int.

ghci> 1 + fromMaybe 2 Nothing 3 it :: Integer 

If I mix it with a sum of integers (fromMaybe :: a -> Maybe a -> a takes a default value and a Maybe a and returns either the value in the Just or the default with Nothing), then Nothing will get typed as Maybe Integer by the system, since you expect to extract an integer from it. There's none, so in this case we sum 1 with the default 2.

ghci> 1 + fromMaybe 2 (Nothing :: Maybe Integer) 3 it :: Integer 

Same here, to double check. We force Nothing to have the concrete type we assumed it had before in the same expression.

ghci> 1 + fromMaybe 2 (Nothing :: Maybe Char)  <interactive>:1:15:     No instance for (Num Char)       arising from the literal `2'     Possible fix: add an instance declaration for (Num Char)     In the first argument of `fromMaybe', namely `2'     In the second argument of `(+)', namely       `fromMaybe 2 (Nothing :: Maybe Char)'     In the expression: 1 + fromMaybe 2 (Nothing :: Maybe Char) 

To triple-check, if we force it to assume another concrete type, as you see its value will be completely different, resulting in a type error (unlike C, in Haskell Char doesn't act as a number).

like image 182
Riccardo T. Avatar answered Oct 26 '22 22:10

Riccardo T.


Is this not in contradiction with the rule the only concrete types can have values?

Since functions are first-class values in Haskell, this purported rule would mean that polymorphic functions such as map and foldr would be impossible to implement.

There are, in fact, a lot of polymorphic non-function values in Haskell, such as

1 :: Num a => a Nothing :: Maybe a [] :: [a] Left 1 :: Num a => Either a b 

etc. These values exist for every instantiation of a (and b).

like image 33
Fred Foo Avatar answered Oct 26 '22 22:10

Fred Foo