gpt4 book ai didi

haskell - 模式匹配比 Haskell 中的 case 表达式更可取的现实示例?

转载 作者:行者123 更新时间:2023-12-03 15:10:07 35 4
gpt4 key购买 nike

所以一直忙于真实世界的 Haskell 书,我做了最后一个ButOne练习。我想出了两种解决方案,一种是模式匹配

lastButOne :: [a] -> a
lastButOne ([]) = error "Empty List"
lastButOne (x:[]) = error "Only one element"
lastButOne (x:[x2]) = x
lastButOne (x:xs) = lastButOne xs

还有一个使用 case 表达式
lastButOneCase :: [a] -> a
lastButOneCase x =
case x of
[] -> error "Empty List"
(x:[]) -> error "Only One Element"
(x:[x2]) -> x
(x:xs) -> lastButOneCase xs

我想知道的是,模式匹配何时比 case 表达式更受欢迎,反之亦然 .这个例子对我来说不够好,因为看起来虽然这两个功能都按预期工作,但它并没有让我选择一个实现而不是另一个实现。所以乍一看,选择“似乎”是优惠的?

那么通过源代码是否有很好的案例,无论是在haskell自己的源代码还是github或其他地方,都可以看到何时首选哪种方法?

最佳答案

首先是一个简短的术语转移:我将这两个称为“模式匹配”。我不确定是否有一个好的术语来区分模式匹配通过案例和模式匹配通过多重定义。

两者之间的技术区别确实很轻。您可以通过要求 GHC 转储它为这两个函数生成的核心来自己验证这一点,使用 -ddump-simpl旗帜。我在几个不同的优化级别上尝试了这个,在所有情况下,核心的唯一区别是命名。 (顺便说一句,如果有人知道 Core 的一个好的“语义差异”程序——它至少知道 alpha 等价——我很想听听它!)

不过,有一些小问题需要注意。您可能想知道以下是否也等效:

{-# LANGUAGE LambdaCase #-}
lastButOne = \case
[] -> error "Empty List"
(x:[]) -> error "Only One Element"
(x:[x2]) -> x
(x:xs) -> lastButOneCase xs

在这种情况下,答案是肯定的。但是考虑一下这个看起来相似的:
-- ambiguous type error
sort = \case
[] -> []
x:xs -> insert x (sort xs)

突然之间,这是一个类型类多态 CAF,等等旧 GHC,这将触发单态限制并导致错误,而具有显式参数的表面相同版本不会:
-- this is fine!
sort [] = []
sort (x:xs) = insert x (sort xs)

另一个小区别(我忘记了——感谢 Thomas DuBuisson 提醒我)是处理 where 子句。由于 where 子句附加到绑定(bind)站点,它们不能在多个方程式之间共享,但可以在多个情况下共享。例如:
-- error; the where clause attaches to the second equation, so
-- empty is not in scope in the first equation
null [] = empty
null (x:xs) = nonempty
where empty = True
nonempty = False

-- ok; the where clause attaches to the equation, so both empty
-- and nonempty are in scope for the entire case expression
null x = case x of
[] -> empty
x:xs -> nonempty
where
empty = True
nonempty = False

你可能会认为这意味着你可以对方程做一些你不能用 case 表达式做的事情,也就是说,两个方程中的同一个名字有不同的含义,就像这样:
null [] = answer where answer = True
null (x:xs) = answer where answer = False

然而,由于 case 的模式表达式是绑定(bind)站点,这可以在 case 中模拟表达方式:
null x = case x of
[] -> answer where answer = True
x:xs -> answer where answer = False

是否 where条款附加到 case的模式或等式当然取决于缩进。

关于haskell - 模式匹配比 Haskell 中的 case 表达式更可取的现实示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34075047/

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