如何使用id更改类型进行组合

时间:2014-05-30 19:57:53

标签: haskell function-composition

如果foldr的类型是

> :t foldr
forall a b. (a -> b -> b) -> b -> [a] -> b

> :t id
forall a. a -> a

然后我希望foldr (.) idfoldr具有相同的类型,而不是

> :t foldr (.) id
forall b. [b -> b] -> b -> b

看来我错误地认为合成是如何运作的,因为我认为对于f f . id会给f(id(x)) == f(x)的函数f,保留foldr (.) id的类型。我误解的是什么会更加笼统地阐明{{1}}和作文的含义?

3 个答案:

答案 0 :(得分:11)

这是{em>不与id的合成,因为你来自foldr . id(注意没有parens)。这确实只相当于foldr,也许是类别理论中最重要的等价物,因此也是Haskell的基础。

相反,您在那里所做的是,将(.)id作为参数传递给foldr:放置.在parens使它只是另一个表达式,所以普通的Haskell函数解析适用,即贪婪地使用连续的术语作为第一个的参数。你很幸运,这使得一个好的类型,例如succ (.) id会给出荒谬的签名Enum ((c -> c) -> (a -> c) -> a -> c) => (a -> c) -> a -> c

通过编写

可以看出它与foldr的完全一致
 (.) :: (y->z) -> (x->y) -> (x->z)

统一(x->y) = (x->z)foldr的论据一样,即y = z

 (.) :: (y->y) -> (x->y) -> (x->y)

 foldr (.) :: (x->y) -> [y->y] -> (x->y)

然后id还需要x = y

 foldr (.) id :: [x->x] -> (x->x)

答案 1 :(得分:6)

您没有使用foldr撰写id。那将是foldr . id。您实际执行的操作是 foldr应用于(.),然后将此类应用的结果应用于id

答案 2 :(得分:1)

你在这里说的是你将要编写一个所有类型相同的函数列表(因为它们在列表中)。 id是您要折叠的初始功能。完成所有这些操作后,您将获得一个功能。可能更容易将结果类型视为[b -> b] -> (b -> b)

顺便说一下,当您在Haskell中使用运算符并且想要中继它时,省略了parantheses。只有当你将它作为任何其他功能使用时才包括parantheses。