Laziness/strictness between data and newtype

后端 未结 2 1202
无人共我
无人共我 2021-02-07 09:33

I\'m struggling to understand why these two snippets produce different results under the so-called \"poor man\'s strictness analysis\".

The first example uses data

2条回答
  •  礼貌的吻别
    2021-02-07 10:20

    As you probably know, the main difference between data and newtype is that with data the data constructors are lazy while with newtype the data constructors are strict, i.e. given the following types

    data    D a = D a 
    newtype N a = N a
    

    then D ⊥ `seq` x = x, but N ⊥ `seq` x = ⊥.(where stands for "bottom", i.e. undefined value or error)

    What is perhaps less commonly known, however, is that when you pattern match on these data constructors, the roles are "reversed", i.e. with

    constD x (D y) = x
    constN x (N y) = x
    

    then constD x ⊥ = ⊥ (strict), but constN x ⊥ = x (lazy).

    This is what's happening in your example.

    Parser f <*> Parser x = Parser h where ...
    

    With data, the pattern match in the definition of <*> will diverge immediately if either of the arguments are , but with newtype the constructors are ignored and it is just as if you'd written

    f <*> x = h where
    

    which will only diverge for x = ⊥ if x is demanded.

提交回复
热议问题