gpt4 book ai didi

haskell - 如何将两个参数的 Haskell 函数重写为无点样式

转载 作者:行者123 更新时间:2023-12-03 10:33:39 27 4
gpt4 key购买 nike

我在 Haskell 中有以下功能

agreeLen :: (Eq a) => [a] -> [a] -> Int
agreeLen x y = length $ takeWhile (\(a,b) -> a == b) (zip x y)

我正在尝试学习如何编写“惯用的”Haskell,它似乎更喜欢使用 .$而不是括号,并且在可能的情况下更喜欢无点代码。我似乎无法摆脱提及 xy明确地。有任何想法吗?

我认为我会遇到同样的问题,即对两个参数的任何函数进行点释放。

BTW,这只是为了写好代码;不是一些“尽一切可能使它变得毫无意义”的家庭作业。

谢谢。

(添加评论)
感谢您的回答。你已经说服我这个功能不会从 pointfree 中受益。你还给了我一些练习转换表达式的好例子。这对我来说仍然很困难,而且它们对 Haskell 来说似乎就像指针对 C 一样重要。

最佳答案

and also to prefer pointfree code where possible.



不是“在可能的情况下”,而是“在提高可读性(或具有其他明显优势)的地方”。

免积分
agreeLen x y = length $ takeWhile (\(a,b) -> a == b)  (zip x y)

第一步是移动 ($)对,用 (.) 替换你拥有的那个:
agreeLen x y = length . takeWhile (\(a,b) -> a == b) $ zip x y

现在,您可以将其进一步向右移动:
agreeLen x y = length . takeWhile (uncurry (==)) . zip x $ y

在那里你可以立即砍掉一个论点,
agreeLen x = length . takeWhile (uncurry (==)) . zip x

然后您可以将其重写为组合运算符的前缀应用程序,
agreeLen x = (.) (length . takeWhile (uncurry (==))) (zip x)

你可以写

f (g x)

作为
f . g $ x

一般来说,这里有
f = (.) (length . takeWhile (uncurry (==)))

g = zip , 给
agreeLen x = ((.) (length . takeWhile (uncurry (==)))) . zip $ x

论据 x很容易被移除。然后就可以转换 (.)的前缀应用了进入一个部分并得到
agreeLen = ((length . takeWhile (uncurry (==))) .) . zip

但是,这比原来的可读性差,所以我不建议这样做,除非练习将表达式转换为无点样式。

关于haskell - 如何将两个参数的 Haskell 函数重写为无点样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13426417/

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