В этом случае используется неопровержимый шаблон (часть ~). Необычные шаблоны всегда "совпадают", поэтому это печатает hello.
foo ~(Just x) = x
main = putStrLn $ foo Nothing
Теперь шаблон все еще совпал, но когда мы пытались использовать x, когда на самом деле там не было, мы получили неопровержимую ошибку соответствия шаблона:
Irr.hs: /tmp/Irr.hs:2:1-17: Irrefutable pattern failed for pattern (Data.Maybe.Just x)
Это тонко отличается от ошибки, которую вы получаете, когда нет соответствующего шаблона:
foo (Just x) = x
main = putStrLn $ foo Nothing
Выводит
Irr.hs: /tmp/Irr.hs:2:1-16: Non-exhaustive patterns in function foo
Конечно, это несколько надуманный пример. Более вероятным объяснением является то, что он исходил из шаблона в привязке let, как предлагалось chrisdb.
Ответ 3
Чтобы добавить то, что сказали другие, вы можете технически получить его, если вы отключите список, который меньше, чем вы планируете. Например (в GHCi):
Prelude> let l = [1,2,3]
Prelude> let (x:x1:xs) = l
Prelude> x
1
Работает нормально, но если вы это сделали:
Prelude> let l2 = [1]
Prelude> let (x:x1:xs) = l2
Prelude> x
*** Exception: <interactive>:294:5-18: Irrefutable pattern failed for pattern (x : x1 : xs)