Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

haskell

Here are two equivalent partial functions:

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

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)

like image 500
rampion Avatar asked May 31 '19 18:05

rampion


1 Answers

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.

like image 99
Li-yao Xia Avatar answered Nov 11 '22 20:11

Li-yao Xia