困惑于Haskell中的功能组合

时间:2014-11-01 09:32:31

标签: function haskell functional-programming composition

我知道(.) f g x = f (g x)。假设f的类型为Int -> Intg的类型为Int -> Int -> Int。现在让hh x y = f (g x y).定义以下哪个陈述为真,为什么(为什么不)?

一个。 h = f . g

h x = f . (g x)

℃。 h x y = (f . g) x y

据说,只有b。是真的,而其他人都是假的。我想是的。和b。相当于......说两个功能是平等的。只有当我将参数添加到双方的末尾时,两个函数才相等,它仍然是相等的。所以我得到h x = f . g x。现在(.)是一个运算符,因此功能应用程序优先于它,所以f . g x = f . (g x),即b。

2 个答案:

答案 0 :(得分:4)

这看起来像是一个作业,所以我不会给出哪一个是正确的答案。

您认为ab错误相同。如果将f . g应用于x,则会获得(来自(.)的定义)

(f . g) x = f (g x)

bf . (g x),不会扩展为f (g x)。如果您通过使用b的定义来关注(.),您会在其他人的评论中看到这种感觉。

答案 1 :(得分:0)

函数组合的初始定义有点令人困惑,所以我将以不同的方式编写它:

f . g = \a -> f (g a)

这意味着f . g返回一个函数,该函数首先将参数应用于g,然后将结果应用于f。这在类型签名中也很清楚:

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

现在对于你的函数h,它有类似h :: a -> a -> a的类型。请记住,->是右关联的,因此类型可以写为h :: a -> (a -> a)。基本上,h :: a -> b,虽然此类型会导致错误,因为ba是无法解决的。 (.)只允许将一个参数应用于第一个函数,所以:

-- One could write,
h x y = f (g x y)
-- But One could also write
h x = f . g x
-- Or, more clearly:
h x = (f) . (g x)

这是因为Haskell函数是 curried ,因此我们可以在不对其进行全面评估的情况下将一些参数应用于g

如果我们想象如果我们在视觉上应用(.)会发生什么,然后简化,我们可以看到它是如何工作的:

h x = \a -> f ((g x) a)
h x = \a -> f (g x a)
h x a = f (g x a)

所以是的,b就是答案。这是因为(.)只允许在移动到下一个函数之前将一个参数应用于第一个函数。

现在,你可以通过简化我的工作来解决其他不正确的解决方案。这不是太难。