【问题标题】:f x y = 3 + y/x in point free formf x y = 3 + y/x 无点形式
【发布时间】:2018-04-24 17:16:26
【问题描述】:
我正在尝试找出 Haskell 中 f x y = 3 + y/x 的无点形式。我以为会是f = (3.0+) . flip (/),但答案是f2 = curry $ (3.0+) . (uncurry $ flip (/)),和f1 = curry ((3.0+) . (uncurry (flip (/))))一样,例如我得到的答案,但在翻转之前使用 uncurry 并在开始时使用 curry。
我知道那个版本是如何工作的,但我不确定为什么需要 curry 和 uncurry 函数,为什么我的版本不起作用? (3.0+) 的类型是 a -> a,我认为如果您通过函数组合将结果形式 flip (/) 提供给该函数会起作用,但 (3.0+) . flip (/) 2 10 会导致错误(为什么?)并且不会产生 8。 uncurry 然后再curry 不是多余的吗?
【问题讨论】:
标签:
haskell
currying
pointfree
【解决方案1】:
. 的类型签名是(.) :: (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 再次“解包”生成的第一个参数元组。
替代方案
如前所述,我们可以使用 owl 运算符:
((.) . (.)) (3.0+) (flip (/))
-- ^ owl ^
或者我们可以使用语法更复杂的 owl 运算符:
((3 +) .) . flip (/)