Foldable
是Traversable
的超類,與Functor
是Applicative
和Monad
的超類相似。Traversable除了可摺疊還有什麼「獨特方法」?
到Monad
,它是可能的情況類似,基本實現fmap
作爲
liftM :: Monad m => (a->b) -> m a -> m b
liftM f q = return . f =<< q
我們也可以使用Monoid m => (,) m
單子效仿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))
。所以超類和方法的結合在兩種情況下都有一定的冗餘。
在單子的情況下,可以說,該類型的類的「好」的定義是(我將跳過應用性/ monoidal)
class (Functor m) => Monad m where
return :: a -> m a
join :: m (m a) -> m a
至少這是什麼範疇論使用。這個定義沒有使用Functor
超類,而不是許可liftM
,所以它沒有這個冗餘。
對於Traversable
類可能有類似的轉換嗎?
爲了澄清:我後是一個重新定義,讓我們叫它,
class (Functor t, Foldable t) => Traversable t where
skim :: ???
這樣,我們可以使實際Traverse
方法頂級功能
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
VS Functor
:雖然>>=
比join
日常哈斯克爾編程方便多了(因爲你通常需要正是這種組合fmap
和join
),後者可以更容易把握一個單子是什麼。
不同的方法是「遍歷」。你不能用'Foldable'來實現它。 –
當然不是,但是你可以用'遍歷'來實現'Foldable'。 – leftaroundabout
......這就是爲什麼'Foldable'是'Traversable'的超級類。一個超級類應該可以在子類中實現。 –