f x y = 3 + y/x 点自由形式
f x y = 3 + y/x in point free form
我正在尝试找出 Haskell 中 f x y = 3 + y/x
的点自由形式。我以为会是 f = (3.0+) . flip (/)
,但答案是 f2 = curry $ (3.0+) . (uncurry $ flip (/))
,这与 f1 = curry ((3.0+) . (uncurry (flip (/))))
相同,例如我得到的答案是 uncurry before flip 和 curry 在开头。
我知道那个版本是如何工作的,但我不确定为什么需要 curry 和 uncurry 函数,以及为什么我的版本不起作用? (3.0+)
的类型是 a -> a
,如果您通过函数组合将结果形式 flip (/)
提供给该函数,我认为它会起作用,但是 (3.0+) . flip (/) 2 10
会导致错误(为什么?)并且不会产生 8。uncurry 然后再 curry 不是多余的吗?
.
的类型签名是 (.) :: (b -> c) -> (a -> b) -> a -> c
。如您所见,这仅在 second 函数(在您的回答 flip (/)
中)具有 一个参数 时有效。如果它有两个参数,我们可以使用 "owl operator" (.) . (.)
,其类型为:
(.) . (.) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c
或者我们可以使用柯里化。通过在 flip (/)
部分使用 uncurry :: (a -> b -> c) -> (a, b) -> c
,我们构造一个函数:
uncurry (flip (/)) :: Fractional c => (c, c) -> c
所以现在我们使用 单个 元组(因此是一个参数),然后我们再次使用 curry :: ((a, b) -> c) -> a -> b -> c
到 "unpack" 结果的第一个参数元组.
备选方案
如前所述,我们可以使用 owl 运算符:
<b>((.) . (.))</b> (3.0+) (flip (/))
-- ^ owl ^
或者我们可以使用 owl 运算符的语法更复杂的版本:
((3 +) .) . flip (/)
我正在尝试找出 Haskell 中 f x y = 3 + y/x
的点自由形式。我以为会是 f = (3.0+) . flip (/)
,但答案是 f2 = curry $ (3.0+) . (uncurry $ flip (/))
,这与 f1 = curry ((3.0+) . (uncurry (flip (/))))
相同,例如我得到的答案是 uncurry before flip 和 curry 在开头。
我知道那个版本是如何工作的,但我不确定为什么需要 curry 和 uncurry 函数,以及为什么我的版本不起作用? (3.0+)
的类型是 a -> a
,如果您通过函数组合将结果形式 flip (/)
提供给该函数,我认为它会起作用,但是 (3.0+) . flip (/) 2 10
会导致错误(为什么?)并且不会产生 8。uncurry 然后再 curry 不是多余的吗?
.
的类型签名是 (.) :: (b -> c) -> (a -> b) -> a -> c
。如您所见,这仅在 second 函数(在您的回答 flip (/)
中)具有 一个参数 时有效。如果它有两个参数,我们可以使用 "owl operator" (.) . (.)
,其类型为:
(.) . (.) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c
或者我们可以使用柯里化。通过在 flip (/)
部分使用 uncurry :: (a -> b -> c) -> (a, b) -> c
,我们构造一个函数:
uncurry (flip (/)) :: Fractional c => (c, c) -> c
所以现在我们使用 单个 元组(因此是一个参数),然后我们再次使用 curry :: ((a, b) -> c) -> a -> b -> c
到 "unpack" 结果的第一个参数元组.
备选方案
如前所述,我们可以使用 owl 运算符:
<b>((.) . (.))</b> (3.0+) (flip (/))
-- ^ owl ^
或者我们可以使用 owl 运算符的语法更复杂的版本:
((3 +) .) . flip (/)