f x y = 3 + y / x,无自由形式

时间:2017-05-31 15:19:13

标签: haskell currying pointfree

我正试图弄清楚Haskell中f x y = 3 + y/x的点自由形式。我认为它是f = (3.0+) . flip (/),但答案是f2 = curry $ (3.0+) . (uncurry $ flip (/)),与f1 = curry ((3.0+) . (uncurry (flip (/))))相同,例如我得到的答案,但在开头翻转和咖喱之前没有问题。

我看到该版本是如何工作的,但我不确定为什么需要curry和uncurry函数,为什么我的版本不起作用? (3.0+)的类型为a -> a,如果您通过函数组合使用结果格式flip (/)来提供该函数,我认为该方法可行,但(3.0+) . flip (/) 2 10会导致错误(为什么?)并且不会产生8.是不是多余的,不再发生,然后再次咖喱?

1 个答案:

答案 0 :(得分:5)

.的类型签名是(.) :: (b -> c) -> (a -> b) -> a -> c。如您所见,这仅适用于第二个功能(在您的回答flip (/)中)一个参数。如果它有两个参数,我们可以使用" owl运算符" (.) . (.),其类型为:

(.) . (.) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c

或者我们可以使用currying。通过在uncurry :: (a -> b -> c) -> (a, b) -> c部分使用flip (/),我们构建了一个函数:

uncurry (flip (/)) :: Fractional c => (c, c) -> c

所以现在我们使用单个元组(因此一个参数),然后我们使用curry :: ((a, b) -> c) -> a -> b -> c来"解包"由此产生的第一个参数元组。

替代

如前所述,我们可以使用 owl运算符

   ((.) . (.)) (3.0+)  (flip (/))
-- ^   owl   ^

或者我们可以使用一个语法更复杂的owl运算符版本:

((3 +) .) . flip (/)