What is the type of Nothing in Haskell?

后端 未结 5 964
北恋
北恋 2021-01-01 10:51

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

H

相关标签:
5条回答
  • 2021-01-01 11:35

    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 :

    enter image description here

    0 讨论(0)
  • 2021-01-01 11:39

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

    0 讨论(0)
  • 2021-01-01 11:41

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

    0 讨论(0)
  • 2021-01-01 11:44

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

    0 讨论(0)
  • 2021-01-01 11:51

    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.

    0 讨论(0)
提交回复
热议问题