Из-за лени, foo 1
не будет выполнено, пока вы фактически не попытаетесь напечатать значение n
. По сути, n
привязан к неоцененному thunk foo 1
, а не результату foo 1
.
Довольно неуклюжий способ заставить baz
обработать исключение - использовать seq
; почти наверняка есть более элегантное решение.
baz = let result = foo 1
in seq result (return result) `catch` \(Problem msg) -> return 100
И, благодаря @Alec, это более элегантное решение - просто заменить return
на Control.Exception.evaluate
в исходной функции.
baz :: IO Int
baz =
evaluate (foo 1)
`catch` \(Problem _) -> return 100