rampion
rampion

Reputation: 89093

Control.Exception.evaluate treats thunks generated by equivalent functions differently

Here are two equivalent partial functions:

Applying either to False should raise a PatternMatchFail exception.

When I use Control.Exception.evaluate to force a thunk made from the former to WHNF, it forces the PatternMatchFail exception:

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

When I use the latter form, it doesn't:

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

Why not?

(on GHC-8.0.1)

Upvotes: 7

Views: 68

Answers (1)

Li-yao Xia
Li-yao Xia

Reputation: 33519

From the Haskell 2010 report:

The following identity holds:

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

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

So \True () -> e desugars to \x y -> case (x, y) of (True, ()) -> e, which after partial application to False is \y -> case (False, y) of ... i.e., a function abstraction, so that's not bottom.

In contrast, \True -> f (where f = \() -> e) desugars to \x -> case x of True -> ..., and there's the exception.

Upvotes: 7

Related Questions