gpt4 book ai didi

haskell - 当模式匹配失败时,为什么 Haskell 列表推导不会导致错误?

转载 作者:行者123 更新时间:2023-12-03 12:04:34 25 4
gpt4 key购买 nike

我试图了解 Haskell 列表理解在模式匹配方面是如何“在幕后”工作的。以下 ghci 输出说明了我的观点:

Prelude> let myList = [Just 1, Just 2, Nothing, Just 3]
Prelude> let xs = [x | Just x <- myList]
Prelude> xs
[1,2,3]
Prelude>

如您所见,它能够跳过“Nothing”并仅选择“Just”值。我知道 List 是一个单子(monad),定义为(来自 Real World Haskell,第 14 章):
instance Monad [] where
return x = [x]
xs >>= f = concat (map f xs)
xs >> f = concat (map (\_ -> f) xs)
fail _ = []

因此,列表推导基本上为列表推导中选择的每个元素构建一个单例列表并将它们连接起来。如果模式匹配在某个步骤失败,则使用“失败”函数的结果。换句话说,“Just x”模式不匹配,因此 [] 用作占位符,直到调用 'concat'。这就解释了为什么“无”似乎被跳过了。

我不明白的是,Haskell 怎么知道调用“失败”函数?它是“编译器魔法”,还是您可以在 Haskell 中自己编写的功能?是否可以编写以下“选择”函数以与列表理解相同的方式工作?
select :: (a -> b) -> [a] -> [b]
select (Just x -> x) myList -- how to prevent the lambda from raising an error?
[1,2,3]

最佳答案

虽然 Haskell 的实现可能不会在内部直接这样做,但以这种方式考虑它是有帮助的 :)

[x | Just x <- myList]

...变成:
do
Just x <- myList
return x

...这是:
myList >>= \(Just x) -> return x

至于你的问题:

What I don't understand is, how does Haskell know to call the "fail" function?



在 do-notation 中,如果模式绑定(bind)失败(即 Just x ),则调用 fail 方法。对于上面的示例,它看起来像这样:
myList >>= \temp -> case temp of
(Just x) -> return x
_ -> fail "..."

因此,每次您在可能失败的一元上下文中进行模式匹配时,Haskell 都会插入对 fail 的调用。 .用 IO 试试看:
main = do
(1,x) <- return (0,2)
print x -- x would be 2, but the pattern match fails

关于haskell - 当模式匹配失败时,为什么 Haskell 列表推导不会导致错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/649274/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com