gpt4 book ai didi

Haskell 元组列表与元组比较

转载 作者:行者123 更新时间:2023-12-05 01:25:51 25 4
gpt4 key购买 nike

我正在玩我的第一个非平凡的(在我看来)尝试在 Haskell 中的东西。我可能会问关于每个部分的问题,以比较我与 C 类语言建立长期关系的尝试与您作为经验丰富的函数式程序员可能会做的事情。幸运的是,Haskell 很难退回到直接的 c 到 haskell 代码转换。您必须学习如何正确地做事 - 我想这样做。

对于这部分,我有一个 [2uple] 和一个 2uple。我想知道 2uple 中的任何项目是否在 [2uple] 中的任何项目中。

hasmatch tlst tupm = foldr (\tup acc -> 
let tmatch (a,b) (c,d) = a==c || b==c || a==d || b==d in
if tmatch tup tupm
then (Just True) -- short out
else acc -- do nothing, keep looping
) Nothing tlst

-- hasmatch [(1,2), (3,4), (5,6)] (5,3) ==> Just True
-- hasmatch [(1,2), (9,4), (7,6)] (5,3) ==> Nothing

我更愿意返回一个普通的 Bool,但没什么大不了的。

我敢肯定,还有另一种方法我需要仔细研究一段时间才能理解。那很好。寻找接受者。

谢谢

最佳答案

让我们从您的代码开始。

hasmatch tlst tupm =
foldr (\tup acc ->
let tmatch (a,b) (c,d) = a==c || b==c || a==d || b==d in
if tmatch tup tupm
then (Just True) -- short out
else acc -- do nothing, keep looping
) Nothing tlst

既然你说你更喜欢 bool 结果,我们可以切换到那个。事实上, bool 值会更好,因为在上面的代码中我们从不返回 Just False

hasmatch tlst tupm =
foldr (\tup acc ->
let tmatch (a,b) (c,d) = a==c || b==c || a==d || b==d in
if tmatch tup tupm
then True -- short out
else acc -- do nothing, keep looping
) False tlst

现在,if x then True else y 就是 x || y.

hasmatch tlst tupm =
foldr (\tup acc ->
let tmatch (a,b) (c,d) = a==c || b==c || a==d || b==d in
tmatch tup tupm || acc
) False tlst

如果您想知道,当我们找到匹配项时,|| 不会评估 acc。这是与 C 短路相同的惰性语义。与 C 相比,主要区别在于 bool 变量 acc 可以表示未计算的 bool 结果,而在 C 中它始终是完全计算的 bool 值。

现在,tmatch 使用相同的第二个参数,tupm,因此我们可以内联它,并尽早进行模式匹配:

hasmatch tlst (c,d) =
foldr (\tup acc ->
let tmatch (a,b) = a==c || b==c || a==d || b==d in
tmatch tup || acc
) False tlst

我们甚至可以将 let 移到外面以提高可读性。

hasmatch tlst (c,d) =
let tmatch (a,b) = a==c || b==c || a==d || b==d
in foldr (\tup acc -> tmatch tup || acc) False tlst

我们也可以在这里使用where:

hasmatch tlst (c,d) = foldr (\tup acc -> tmatch tup || acc) False tlst
where tmatch (a,b) = a==c || b==c || a==d || b==d

最后,我们可以利用一个库函数:any。调用 any p list 计算结果为 True 当且仅当 list 中有任何元素满足属性 p。我们的代码变成:

hasmatch tlst (c,d) = any tmatch tlst
where tmatch (a,b) = a==c || b==c || a==d || b==d

就是这样。

请注意,上述方法还有其他替代方法。可以将元组列表 [(a,b), (c,d), ... 转换为所有组件列表 [a,b,c,d, ...,并与之合作。

hasmatch tlst (c,d) = any tmatch [ x | (a,b) <- tlst, x <- [a,b]]
where tmatch x = x==c || x==d

关于Haskell 元组列表与元组比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70660789/

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