我正在尝试找出 Haskell 中 f x y = 3 + y/x
的点自由形式。我认为它会是 f = (3.0+) 。翻转 (/)
,但答案是 f2 = curry $ (3.0+) 。 (uncurry $ Flip (/))
,与 f1 = curry ((3.0+) . (uncurry (flip (/))))
相同,例如我得到的答案是在翻转之前先进行 curry ,然后在开始时进行 curry 。
我知道该版本是如何工作的,但我不确定为什么需要 curry 和 uncurry 函数,以及为什么我的版本不起作用? (3.0+)
的类型是 a -> a
,我认为如果您使用结果形式 flip (/)
通过函数组合,但是 (3.0+) 。 Flip (/) 2 10
会导致错误(为什么?)并且不会产生 8。先 curry 然后再次 curry 不是多余的吗?
最佳答案
.
的类型签名为 (.)::(b -> c) -> (a -> b) -> a -> c
。正如您所看到的,只有当第二个函数(在您的答案中flip (/)
)有一个参数时,这才有效。如果它有两个参数,我们可以使用“owl 运算符” (.) 。 (.)
,其类型为:
(.) . (.) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c
或者我们可以使用柯里化(Currying)。通过在 flip (/)
部分使用 uncurry::(a -> b -> c) -> (a, b) -> c
,我们构造了一个函数:
uncurry (flip (/)) :: Fractional c => (c, c) -> c
所以现在我们使用一个单个元组(因此有一个参数),然后我们使用curry::((a, b) -> c) -> a -> b -> c
再次“解压”生成的第一个参数元组。
替代方案
正如之前所讨论的,我们可以使用owl运算符:
<b>((.) . (.))</b> (3.0+) (flip (/))
-- ^ owl ^
或者我们可以使用语法上更复杂的 owl 运算符版本:
((3 +) .) . flip (/)
关于haskell - f x y = 3 + y/x(点自由形式),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44288658/