如何展开sequenceA的定义,以及它的递归基本情况?

时间:2018-03-10 02:58:16

标签: haskell

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)
......

递归基本情况在哪里?

1 个答案:

答案 0 :(得分:5)

Traversable的类型必须至少实现traversesequenceA中的一个。默认定义是从另一个派生一个功能的方法。

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)