Haskell中组合物的组成

时间:2015-02-22 12:24:50

标签: haskell functional-programming functor

我最近正在学习Haskell,而且我正在读“学习你是一个Haskell的Functors”,我才知道

  1. 带有一个参数的函数((->)r)也是一种Functors。
  2. 作文(.)相当于fmap
  3. 所以根据我的理解,fmap有两个参数。首先是要应用的函数,第二个是函子。

    但是,我对这个表达式(.) (.) (.)感到困惑。这是两种组合的组合,类型为(b -> c) -> (a1 -> a2 -> b) -> (a1 -> a2 -> c)

    所以这是我的疑问。第一个(.)有两个参数,第一个是组合函数本身。第二个参数也是组合函数。而组合函数本身并不是算子。那么这是一个有效的表达方式呢?

    我确信我在这里遗漏了一些东西。有人可以填补空白并帮助我了解表达方式是否正确吗?

1 个答案:

答案 0 :(得分:7)

忽略Functor的{​​{1}}个实例;这是无关紧要的。这里只有两个问题:((->) r)的类型,即

(.)

,以及函数应用程序左关联的事实。后者意味着(.) :: (b -> c) -> (a -> b) -> a -> c (.) (.) (.)相同。

让我们首先尝试找到((.) (.)) (.)的类型(最左边的那些,如果你愿意的话)。让我们将第一个(.) (.)的类型写为(.),将第二个类型写为(b1 -> c1) -> (a1 -> b1) -> a1 -> c1。我们将第一个应用于第二个,这使我们(b2 -> c2) -> (a2 -> b2) -> a2 -> c2b1(b2 -> c2)c1。因此我们有

(a2 -> b2) -> a2 -> c2

可以简化为

(.) (.) :: (a1 -> (b2 -> c2)) -> a1 -> ((a2 -> b2) -> a2 -> c2)

现在让我们将其应用到最后一个(.) (.) :: (a1 -> b2 -> c2) -> a1 -> (a2 -> b2) -> a2 -> c2 (最右边的一个,如果你愿意的话)。如果它有签名(.),那么我们会看到(b3 -> c3) -> (a3 -> b3) -> a3 -> c3必须是a1(b3 -> c3)必须是b2(a3 -> b3)必须是{{1} }}。因此,

c2

相同
a3 -> c3

如果您进行重命名,这与您在问题中的内容相同。