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

bea*_*rdc 4 haskell function-composition

如果类型foldr

> :t foldr
forall a b. (a -> b -> b) -> b -> [a] -> b
Run Code Online (Sandbox Code Playgroud)

> :t id
forall a. a -> a
Run Code Online (Sandbox Code Playgroud)

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

> :t foldr (.) id
forall b. [b -> b] -> b -> b
Run Code Online (Sandbox Code Playgroud)

看来我错了有关成分是如何工作的,因为我原本以为,对于一个功能ff . id将给予f(id(x)) == f(x),保持的类型f.我foldr (.) id更容易误解的是如何更普遍地澄清其含义和构成?

lef*_*out 11

正如你所得到的那样,这不是构成(注意没有parens).这确实等同于单独的,也许是类别理论中最重要的等同性,因此也是Haskell的基础.idfoldr . idfoldr

取而代之的是,你是做什么就有什么,通过双方(.)id作为参数foldr:将.在括号使得它只是另一种表达方式,以便普通的Haskell函数解析适用,即贪婪地用连续两届作为参数传递给第一个.你很幸运,因为这会产生一个好的类型,例如succ (.) id会给出荒谬的签名Enum ((c -> c) -> (a -> c) -> a -> c) => (a -> c) -> a -> c.

foldr通过写作可以看出它的工作原理

 (.) :: (y->z) -> (x->y) -> (x->z)
Run Code Online (Sandbox Code Playgroud)

统一(x->y) = (x->z)作为foldr"的说法,即y = z,

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

 foldr (.) :: (x->y) -> [y->y] -> (x->y)
Run Code Online (Sandbox Code Playgroud)

然后id还需要x = y,

 foldr (.) id :: [x->x] -> (x->x)
Run Code Online (Sandbox Code Playgroud)


pyo*_*yon 6

你是不是构成foldrid.那就是foldr . id.什么你实际上做的是应用 foldr(.),然后将这种应用程序的结果id.