我正试图弄清楚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.是不是多余的,不再发生,然后再次咖喱?
答案 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 (/)