简体   繁体   中英

What is the type of Nothing in Haskell?

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.

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. Eg:

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).

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 ).

In some sense, you're right. There are no values of type forall a.Maybe a . Every Maybe value you construct will actually have some definite type Maybe tau , where tau may be known or not, but is some definite type.

The notation Nothing :: forall a.Maybe a just tells us that whenever we use the expression Nothing , it will construct a value of the expected Maybe type.

The Maybe type has two constructors: Nothing and Just a, where a is a type variable. Nothing itself does not determine (constrain) the type, but in any reasonable context you'll find something like (I do not claim it to be syntactically correct Haskell but something I would have written 10 years ago):

if (foo == 5)
then Nothing
else Just 5

And then type inference will tell you that (assume 5 was an argument to this code snippet 'foo' of type Int) that foo has type:

foo :: Int -> Maybe Int

But as the previous poster pointed out, Maybe a is a perfectly good type. You'll find the same non-issue with [] ie the list type with [] (the constructor for an empty list).

This talk at 26:00 answers the question: "what is the type of [ ] ?" which is a related question to "what is the type of Nothing ?".

Also Hudak's book has a nice paragraph on this :

在此输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM