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)
这正好符合我上面给出的示意图形式,x
和y
等于Double
,z
等于函数类型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
在 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)
这正好符合我上面给出的示意图形式,x
和y
等于Double
,z
等于函数类型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