使用遍历实现sequenceA

use*_*457 4 haskell types

sequenceA在Data.Traversable中的实现如下

 sequenceA :: Applicative f => t (f a) -> f (t a)
 sequenceA = traverse id
Run Code Online (Sandbox Code Playgroud)

我无法理解的类型traverse idtraverse的类型为:traverse :: Applicative f => (a -> f b) -> t a -> f (t b)其第一个参数的类型为:(a -> f b)但是对于sequenceA,id函数的类型为(a -> a)。f在哪里?

Wil*_*sem 5

首先让我们说一下,它id具有id :: c -> c使事情变得不那么复杂的类型。将a在函数的类型签名是当地在这个意义上aid :: a -> a什么做用atraverse :: Applicative f => (a -> f b) -> t a -> f (t b)a只是一个类型参数。

现在我们有了表达式:

traverse id
Run Code Online (Sandbox Code Playgroud)

与:

traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
id       ::                   c -> c
Run Code Online (Sandbox Code Playgroud)

我在c -> c零件的同一列上编写了零件,a -> f b以显示Haskell类型系统是如何交互的。现在得出:

a   ~ c
f b ~ c
Run Code Online (Sandbox Code Playgroud)

因此,这意味着a ~ c ~ f b并且既然类型相等,就像每个相等关系一样都是可传递的,因此也意味着a ~ f b。因此,Haskell现在专注traverse id于:

traverse id :: Applicative f => t a -> f (t b)
traverse id :: Applicative f => t (f b) -> f (t b) -- a ~ f b
Run Code Online (Sandbox Code Playgroud)

因此,类型。中的id类型 traverse id type id :: f b -> f b