Haskell 中缀符号在左边取 2 个参数

Haskell infix notation taking 2 arguments on the left

在 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

是否可以 use/define 中缀表示法,在左边接受 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?

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

据我了解,如果你有一个函数f :: x -> y -> z。那么你可以用

的形式编写它的应用程序
f x0 y0

x0 `f` y0

它们的意思完全一样。

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

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

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

当然,由于再次柯里化,你可以意识到sumAndDivideBy 3.0本身就是一个函数Double -> Double -> Double,你可以用中缀形式使用它,和你"position"完全一样希望它在。所以你可以这样做:

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

为什么不作弊?

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

在 ghci 中:

> (3,5) `sumAndDivideBy` 2
4.0