什么是“区别方法"?除了可折叠之外,Traversable还具有? [英] What would be the "distinct method" that Traversable has in addition to Foldable?
问题描述
Foldable
是 Functor
是Applicative
和Monad
的超类.
Foldable
is a superclass of Traversable
, similarly to how Functor
is a superclass of Applicative
and Monad
.
类似于Monad
的情况,在该情况下,基本上可以将fmap
实现为
Similar to the case of Monad
, where it is possible to basically implement fmap
as
liftM :: Monad m => (a->b) -> m a -> m b
liftM f q = return . f =<< q
我们也可以将foldMap
模仿为
foldLiftT :: (Traversable t, Monoid m) => (a -> m) -> t a -> m
foldLiftT f = fst . traverse (f >>> \x -> (x,x))
-- or: . sequenceA . fmap (f >>> \x -> (x, x))
使用Monoid m => (,) m
monad.因此,在两种情况下,超类和方法的组合都具有一定的冗余性.
using the Monoid m => (,) m
monad. So the combination of superclass and methods bears in both cases a certain redundancy.
对于单子而言,可以说类型类的更好"定义是(我将跳过适用性/单义性)
In case of monads, it can be argued that a "better" definition of the type class would be (I'll skip applicative / monoidal)
class (Functor m) => Monad m where
return :: a -> m a
join :: m (m a) -> m a
至少这是范畴论中所使用的.此定义在不使用Functor
超类的情况下允许 not 允许liftM
,因此没有这种冗余.
at least that's what's used in category theory. This definition does, without using the Functor
superclass, not permit liftM
, so it is without this redundancy.
Traversable
类是否可以进行类似的转换?
Is a similar transformation possible for the Traversable
class?
要澄清一下:我所追求的是重新定义,我们称它为
To clarify: what I'm after is a re-definition, let's call it,
class (Functor t, Foldable t) => Traversable t where
skim :: ???
这样我们就可以使实际的Traverse
方法成为顶级函数
such that we could make the actual Traverse
methods top-level functions
sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
但 不可能通用
instance (Traversable t) => Foldable t where
foldMap = ... skim ...
data T
instance Traversable T where
skim = ...
我不是问,因为我出于某些特殊需要.这是一个概念性问题,目的是为了更好地理解Foldable
和Traversable
之间的区别.再次类似于Monad
与Functor
:对于日常的Haskell编程,>>=
比join
方便得多(因为您通常需要join
的组合 ),则后者使您更容易掌握单子的含义.
I'm not asking because I need this for something particular; it's a conceptual question so as to better understand the difference between Foldable
and Traversable
. Again much like Monad
vs Functor
: while >>=
is much more convenient than join
for everyday Haskell programming (because you usually need precisely this combination of fmap
and join
), the latter makes it simpler to grasp what a monad is about.
推荐答案
Foldable
是Functor
,而Traversable
是Monad
,即Foldable
和Functor
是Monad
的超类,并且Traversable
(对所有应用/单项提议的噪声取模).
Foldable
is to Functor
as Traversable
is to Monad
, i.e. Foldable
and Functor
are superclasses of Monad
and Traversable
(modulo all the applicative/monad proposal noise).
实际上,已经在代码中
instance Foldable f => Traversable f where
...
因此,尚不清楚还需要什么. Foldable
的特征在于toList :: Foldable f => f a -> [a]
,而Traversable
最终不仅取决于像toList
那样能够像列表一样抽象内容,而且还能够提取形状
So, it's not clear what more there is to want. Foldable
is characterized by toList :: Foldable f => f a -> [a]
while Traversable
depends ultimately on not only being able to abstract the content as a list like toList
does, but also to be able to extract the shape
shape :: Functor f => f a -> f ()
shape = fmap (const ())
然后重新组合它们
combine :: Traversable f => f () -> [a] -> Maybe (f a)
combine f_ = evalStateT (traverse pop f_) where
pop :: StateT [a] Maybe a
pop = do x <- get
case x of
[] = empty
(a:as) = set as >> return a
取决于traverse
.
有关此属性的更多信息,请参见拉塞尔·奥康纳(Russell O'Connor)的这篇博客文章.
For more information on this property see this blog post by Russell O'Connor.
这篇关于什么是“区别方法"?除了可折叠之外,Traversable还具有?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!