What is the role of 'bottom' (⊥) in Haskell function definitions?

后端 未结 4 1290
醉酒成梦
醉酒成梦 2021-02-05 07:35

I don\'t understand the role played by bottom ( or _|_) in Haskell function definitions.

The definition of zip for example describes it as \"r

4条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-02-05 08:06

    I think the OP already realises this, but for the benefit of others who come here with the same confusion: zip [] _|_ = [] is not actual code!

    The symbol _|_ (which is just an ascii-art rendering of the mathematical symbol ) means bottom1, but only when we're talking about Haskell. In Haskell code it does not have this meaning2.

    The line zip [] _|_ = [] is a description of a property of the actual code for zip; that if you call it with first argument [] and pass any bottom value as the second argument, the result is equal to []. The reason they would want to say exactly this is because the technical definition of what it means for a function f to be non-strict is when f ⊥ is not .

    But there is no role of _|_ (or , or undefined, or the concept of bottom at all) in defining Haskell functions (in code). It has to be impossible to pattern match on an argument to see whether it is , for a number of reasons, and so there is no actual symbol for in Haskell code3. zip [] _|_ = [] is documentation of a property that is a consequence of the definition of zip, not part of its definition.

    As a description of this property zip [] _ = [] is a less specific claim; it would be saying that whatever you call zip [] on, it returns []. It amounts to exactly the same thing, since the only way zip [] ⊥ can return something non-bottom is if it never examines its second argument at all. But it's speaking less immediately to the definition of non-strict-ness.

    As code forming part of the definition of the function zip [] _ = [] can't be compared and contrasted to zip [] _|_ = []. They're not alternatives, the first is valid code, and the second is not.


    1 Which is the "value" of an expression that runs forever, throws an exception, or otherwise falls to evaluate to a normal value.

    2 It's not even a valid Haskell identifier, since it contains both "namey" characters (_) and "operator" characters (|). So it can't actually be a symbol meaning anything at all in Haskell code!

    3 undefined is often used for , but it's more of a variable referring to a value than the actual thing itself. Much like if you have let xs = [1, 2, 3] you can use xs to refer to the list [1, 2, 3], but you can't use it as a pattern to match some other list against; the attempted pattern match would just be treated as introducing a new variable named undefined or xs shadowing the old one.

提交回复
热议问题