Haskell 应用性、可折叠性和可遍历性之间的关系是什么?
我试图从Haskell 应用性、可折叠性和可遍历性之间的关系是什么?,haskell,Haskell,我试图从Applicative界面了解执行任何遍历所需的具体内容。我被卡住了,因为它们没有在默认实现中使用,就好像约束要严格一样。Haskell的类型系统是否太弱,无法描述实际需求 -- | Map each element of a structure to an action, evaluate these actions -- from left to right, and collect the results. For a version that ignores -- the res
Applicative
界面了解执行任何遍历所需的具体内容。我被卡住了,因为它们没有在默认实现中使用,就好像约束要严格一样。Haskell的类型系统是否太弱,无法描述实际需求
-- | Map each element of a structure to an action, evaluate these actions
-- from left to right, and collect the results. For a version that ignores
-- the results see 'Data.Foldable.traverse_'.
traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
traverse f = sequenceA . fmap f
-- | Evaluate each action in the structure from left to right, and
-- and collect the results. For a version that ignores the results
-- see 'Data.Foldable.sequenceA_'.
sequenceA :: Applicative f => t (f a) -> f (t a)
sequenceA = traverse id
一个可能相关的附带问题是,为什么sequenceA\ucode>在可折叠中定义?遍历和sequenceA
都需要处理可遍历为空时发生的情况。然后,在应用程序
上下文中就不会有任何元素可用于将其他内容添加到其上,因此需要纯
你给出的定义有点误导,因为正如你所指出的,它们是相互依赖的。当您实际实现其中一个时,您将遇到空集合问题。您将需要
,因为Functor
没有为某些Functorf
提供聚合不同fa
值的工具
因此,存在Applicative
约束,因为对于大多数类型,为了实现traverse
或sequenceA
您需要Applicative
提供的工具
也就是说,有些类型不需要纯或不需要
。如果您的收藏不能为空,则不需要纯
,例如非空
。如果您的收藏从未包含多个元素,则不需要
,例如可能。有时您不需要任何一个,您只需要fmap
,例如元组部分,如(a,)
)
Haskell可以有一个更细粒度的typeclass层次结构,它将Applicative
分解为更细粒度的部分,分别为pure
和
创建不同版本的可遍历的。Edward Kmett的库semigroupoids
朝着这个方向发展,尽管它并不完美,因为它不能向基类添加实际的超类。它有Apply
,它是Applicative
,但没有pure
,还有Traversable1
,它是Traversable1
的变体,它使用Apply
而不是Applicative
,因此要求其类型永远不能为空
注意,其他生态系统选择了更细粒度的类型类层次结构(参见Scala的cats
或scalaz
库)。我个人认为这样的区分偶尔有用,但并非绝对有用
至于你的第二个问题,如果你所知道的只是拆掉一些东西,你仍然可以在这一过程中执行效果,但你不一定能恢复原来的结构。因此,为什么sequenceA\uuu
是可折叠的。它的功能远远不如sequenceA
第二个问题的可能重复似乎与第一个问题完全无关。但答案很简单:Foldable
足够强大,可以实现sequenceA_
“Haskell可以有一个更细粒度的typeclass层次结构,它将Applicative
分解为更细粒度的部分,为pure
和
提供单独的类--PureScript有这一点,定义Apply
(
)和Applicative
(pure
)作为单独的类型类。