如何将第二个参数传递给接受 3 个参数的 Haskell 函数?

How to pass the second parameter to a Haskell function that takes 3 parameters?

提问人:PengHX 提问时间:8/21/2023 最后编辑:chiPengHX 更新时间:8/22/2023 访问量:103

问:

我现在正在学习Haskell,我只是对此感到非常好奇。 例如:

minus :: Int -> Int -> Int -> Int
minus x y z = x - y - z

如果我想先将 y 传递给函数 [minus] 而不是 x,该怎么办?我想要一个函数 [减去 x 5 z] 我不想要这个

minusy10 x z = minus x 10 z

如果我必须定义一个新功能来实现这一点,我觉得它失去了一些“Haskell优雅”。

哈斯克尔 咖喱

评论


答:

12赞 Daniel Wagner 8/22/2023 #1

你是一种非常惯用的方式;通常,它被绑定在一个子句中,这样它就不会使顶级 API 混乱。 也是常见的选择。这两个选项仅适用于填写第二个参数;更一般地说,为了填充第 n个参数,lambda 可以更好地泛化,如 .minus10whereflip minus 10(`minus` 10)\x -> minus x 10

5赞 Enlico 8/22/2023 #2

从根本上说,你是在问如何在不明确命名其参数的情况下写作。而且,显然,您也不想通过将它们移动到 lambda 中来作弊:minusy10

minusy10 = \x z -> minus x 10 z

你要做的是以“无点风格”写作。minusy10

正如另一个答案所建议的那样,在这种情况下,这很容易完成,但在更一般的情况下,您可能希望参考 pointfree.io,这将为您提供一种可能的方法(但可能存在更多)以无点样式编写函数。

在这种特定情况下,它提出了解决方案(这可能不是最易读的解决方案;相反,我更愿意称之为更具可读性)。flip minus 10(`minus` 10)

另一方面,参考你的感觉

如果我必须定义一个新功能来实现这一点,我觉得它失去了一些“Haskell优雅”

值得考虑的是,如果过度使用,无点样式会降低内容的可读性。事实上,即使是非常简单的功能,您也可以在眨眼间阅读和理解,例如这样,

f x y = x + y*y

无点样式可能会导致与可读性相反的东西(实际上甚至更长!

f = (. join (*)) . (+)

所以我想说的是,在无点风格和“满点”(?)风格之间有一个平衡。这种平衡在哪里?在我看来,应该以最大的可读性为目标,这与“解析性”不同。

我的意思是

subtract2 x = x - 2

易于解析,并且相当容易阅读,但是

subtract2 = (-2)

甚至更容易阅读。

在你的原始例子中,无点形式是相当可读的(但我实际上会质疑你给的名字,这让我想到了一个类似二进制的函数,而它是三元的)。(`minus` 10)minus(-)

评论

1赞 PengHX 8/22/2023
谢谢,这很有哲理!
0赞 Enlico 8/22/2023
不知道这是否是一种赞美,但谢谢,啊哈哈哈:D