gpt4 book ai didi

Haskell 元组与函数参数不匹配

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

我是 Haskell 的新手,所以这可能很明显,但我广泛使用了 Prolog,所以我对此感到困惑......

在使用GHCi时,我创建了如下函数(1):

Prelude> let find k t = head [v | (k',v) <- t, k == k'] -- Definiton of find
find :: Eq a1 => a1 -> [(a1, a)] -> a

Prelude> find 2 [(1,11),(2,22)] -- Invocation of find
22

这是预期的。然后我尝试从定义中删除 k':

Prelude> let find2 k t = head [v | (k,v) <- t]
find2 :: t -> [(t1, a)] -> a

Prelude> find2 2 [(1,11),(2,22)]
11

然后我很惊讶地看到值 2 实际上与 1 匹配。为了确定我不是希望不可能的事情发生,我还尝试了以下操作,以确认在 Haskell 中可以进行部分匹配,看起来确实如此:

Prelude> head [v | (2,v) <- [(1,11),(2,22)]]
22

我还注意到函数声明的差异。我添加了所需的信息,因此 findfind2 的声明看起来完全一样。但是结果还是坏了 (2,_) matchnig (1,11):

Prelude> let find2 :: Eq a1 => a1 -> [(a1, a)] -> a; find2 k t = head [v | (k,v) <- t]
find2 :: Eq a1 => a1 -> [(a1, a)] -> a

Prelude> find2 2 [(1,11),(2,22)]
11

2 如何匹配1

(1) 以上函数来自优秀书籍《Programming in Haskell》p.93

最佳答案

是的,Haskell 模式匹配从根本上不同于 Prolog 模式匹配。

在 Haskell 中,模式中的变量指的是将被匹配绑定(bind)的新变量,而不是必须匹配的现有变量。所以,表达式:

let x = 5 in case (1,2) of (x,y) -> "matched!"   -- gives "matched!"

将始终评估为“匹配!”。那是因为 x(x,y)刚绑定(bind)到 1 , 不与 x 的“现有”外部定义的值进行比较,正如您在这里看到的:

let x = 5 in case (1,2) of (x,y) -> x     -- gives "1"

数字常量的行为不同:

case (1,2) of (5,y) -> "matched!"    -- match fails

对于其他构造函数:

case (True,2) of (False,y) -> "match!"   -- match fails

它们不是“重新绑定(bind)”的,而是必须匹配才能使模式匹配成功。这是字母数字构造函数以大写字母开头的众多原因之一:否则,将非常难以确定模式是涉及匹配现有构造函数还是重新绑定(bind)到新变量。

这适用于任何上下文中的模式匹配,无论是上面的 case 表达式还是像这样的函数定义:

let x = 5
f x = "hi" -- defines `f` for any `x`, not just `f 5`

或像您的示例一样列出推导式。在表达式中:

[v | (k,v) <- [(1,2),(3,4)]]    -- gives [(1,2),(3,4)]

变量 kv将永远是新鲜的,因此将绑定(bind)到任何元组尽管 k 的任何外部现有定义或 v .如果您使用 -Wall 打开警告(特别是 -Wname-shadowing ),这将提醒您注意阴影绑定(bind)。如果替换 k对于常量(或其他构造函数),它的行为不同:

[v | (3,v) <- [(1,2),(3,4)]]    -- only gives [(3,4)]

你可能不喜欢它,但这就是 Haskell 的工作方式。

关于Haskell 元组与函数参数不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46623123/

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