Control.Exception.evaluate区别对待等效函数生成的重击

时间:2019-05-31 18:14:56

标签: haskell

这是两个等效的部分函数:

  • \True -> \() -> ()
  • \True () -> ()

将任何一个应用于False都会引发PatternMatchFail异常。

当我使用Control.Exception.evaluate将前者制作的重击强制到WHNF时,它会强制PatternMatchFail异常:

ghci> _ <- evaluate $ (\True -> \() -> ()) False
*** Exception: <interactive>:10:18-35: Non-exhaustive patterns in lambda

当我使用后一种形式时,它不会:

ghci> _ <- evaluate $ (\True () -> ()) False

为什么不呢?

(在GHC-8.0.1上)

1 个答案:

答案 0 :(得分:7)

摘自Haskell 2010报告:

  

以下身份成立:

\ p1 … pn -> e    =   \ x1 … xn -> case (x1, …, xn) of (p1, …, pn) -> e
     

https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-260003.3

因此\True () -> e\x y -> case (x, y) of (True, ()) -> e不利,False在部分应用到\y -> case (False, y) of ...之后就是\True -> f,即函数抽象,所以不是底线。

相反,f = \() -> e(其中\x -> case x of True -> ...)贬低到a is not a constructor,并且是个例外。