懒惰的模式
懒惰或无可辩驳的模式(用语法~pat
表示)是总是匹配的模式,甚至没有查看匹配的值。这意味着懒惰模式甚至会匹配底部值。但是,随后使用绑定在无可辩驳模式的子模式中的变量将强制进行模式匹配,除非匹配成功,否则将评估为 bottom。
以下函数在其参数中是懒惰的:
f1 :: Either e Int -> Int
f1 ~(Right 1) = 42
所以我们得到了
λ» f1 (Right 1)
42
λ» f1 (Right 2)
42
λ» f1 (Left "foo")
42
λ» f1 (error "oops!")
42
λ» f1 "oops!"
### type mismatch
以下函数是使用惰性模式编写的,但实际上是使用强制匹配的模式变量,因此 Left
参数将失败:
f2 :: Either e Int -> Int
f2 ~(Right x) = x + 1
λ» f2 (Right 1)
2
λ» f2 (Right 2)
3
λ» f2 (Right (error "oops!"))
*** Exception: oops!
λ» f2 (Left "foo")
*** Exception: lazypat.hs:5:1-21: Irrefutable pattern failed for pattern (Right x)
λ» f2 (error "oops!")
*** Exception: oops!
let
绑定是懒惰的,表现为无可辩驳的模式:
act1 :: IO ()
act1 = do
ss <- readLn
let [s1, s2] = ss :: [String]
putStrLn "Done"
act2 :: IO ()
act2 = do
ss <- readLn
let [s1, s2] = ss
putStrLn s1
这里 act1
适用于解析任何字符串列表的输入,而在 act2
中,putStrLn s1
需要 s1
的值,这会强制 [s1, s2]
的模式匹配,因此它仅适用于两个字符串的列表:
λ» act1
> ["foo"]
Done
λ» act2
> ["foo"]
### readIO: no parse