首页 > 解决方案 > Haskell 中缀符号在左边有 2 个参数

问题描述

在 Haskell 中,中缀表示法允许我们执行以下操作:

divide :: Double -> Double -> Double
divide x y = x / y

foo = divide 10.0 3.0
bar = 10.0 `divide` 3.0 -- infix
-- foo and bar are equivalent

是否可以使用/定义左侧带有 2 个参数的中缀表示法?

sumAndDivideBy :: Double -> Double -> Double -> Double
sumAndDivideBy x y z = (x + y) / z

foo2 = sumAndDivideBy 3.0 5.0 2.0
bar2 = 3.0 `sumAndDivideBy` 5.0 $ 2.0 -- works but not what I wan't
bar3 = 3.0 5.0 `sumAndDivideBy` 2.0   -- does not work - impossible?

标签: haskellinfix-notation

解决方案


简短的回答是,不,你不能按照你的要求去做。

据我了解,如果你有一个函数f :: x -> y -> z. 那么你可以用任何一种形式编写它的应用程序

f x0 y0

或者

x0 `f` y0

他们的意思完全一样。

在你的 function 的情况下sumAndDivideBy :: Double -> Double -> Double -> Double,因为柯里化相当于Double -> (Double -> (Double -> Double))我们完全明确。让我以介于两者之间的形式来写:

sumAndDivideBy :: Double -> Double -> (Double -> Double)

这完全符合我上面给出的示意图形式,具有xy等于Double和等于z函数类型Double -> Double。这意味着您确实可以sumAndDivideBy以中缀形式使用,就像您在示例的倒数第二行中所做的那样。一般来说,您可以使用超过 2 个参数的任何函数来执行此操作,但“中缀”形式仅在它位于第一个和第二个参数之间时才有效。

当然,由于再次使用柯里化,您可以意识到它sumAndDivideBy 3.0本身就是一个函数Double -> Double -> Double,您可以以中缀形式使用它,在您希望它所处的完全相同的“位置”中使用它。所以您可以这样做:

sumWithThreeAndDivide = sumAndDivideBy 3.0
foo = 5.0 `sumWithThreeAndDivide` 2.0

但它确实需要为部分应用的函数定义一个名称,我想这会限制你正在考虑的那种事情的使用。

不过,我不确定您的目标到底是什么,因为您的示例可以非常自然地呈现,并使用divide您展示的功能,如

(3.0 + 5.0) `divide` 2.0

或者,当然,因为divide与 相同,就像我假设你自然会(/)做的那样。3.0 + 5.0 / 2.0


推荐阅读