sequenceA
函数可以反转变量的容器非常棒 - 例如,运行sequence (Just $ Right 3)
将获得Right $ Just 3
。我想展开sequenceA
看看它是如何运作的,但是我被它吸进了......
-- source code of `sequenceA` for reference
traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
traverse f = sequenceA . fmap f
sequenceA :: Applicative f => t (f a) -> f (t a)
sequenceA = traverse id
-- unfold it
> sequenceA (Just $ Right 3)
> (traverse id) (Just $ Right 3)
> (sequenceA . fmap id) (Just $ Right 3)
> sequenceA (fmap id (Just $ Right 3))
> (traverse id) (fmap id (Just $ Right 3))
> (sequenceA . fmap id) (fmap id (Just $ Right 3))
> traverse id . fmap id . fmap id $ Just (Right 3)
-- and so on...
> traverse id . fmap id . fmap id . fmap id $ Just (Right 3)
> traverse id . fmap id . fmap id . fmap id . fmap id $ Just (Right 3)
......
递归基本情况在哪里?
答案 0 :(得分:5)
Traversable
的类型必须至少实现traverse
或sequenceA
中的一个。默认定义是从另一个派生一个功能的方法。
Here’s Maybe
’s Traversable
implementation:
instance Traversable Maybe where
traverse _ Nothing = pure Nothing
traverse f (Just x) = Just <$> f x
现在,您可以将sequenceA (Just (Right 3))
扩展为traverse id (Just (Right 3))
= Just <$> id (Right 3)
= Just <$> Right 3
= Right (Just 3)
。