可穿越结构作为具有内容的形状
如果类型 t 是 Traversable 那么 t a 的值可以分成两部分:它们的形状和它们的内容:
data Traversed t a = Traversed { shape::t (), contents :: [a] }
其中内容与使用 Foldable 实例访问的内容相同。
朝着一个方向,从 t a 到 Traversed t a 除了 Functor 和 Foldable 之外不需要任何东西
break :: (Functor t, Foldable t) => t a -> Traversed t a 
break ta = Traversed (fmap (const ()) ta) (toList ta)
但回去使用 traverse 功能至关重要
import Control.Monad.State
-- invariant: state is non-empty
pop::State [a] a
pop = state $ \(a:as) -> (a, as)
recombine::Traversable t => Traversed t a -> t a
recombine (Traversed s c) = evalState (traverse (const pop) s) c
Traversable 法则要求 break . recombine 和 recombine . break 都是同一性。值得注意的是,这意味着在 contents 中有完全正确的数字元素来完全填充 shape 而没有剩余。
Traversed t 本身就是 Traversable。traverse 的实现通过使用列表的 Traversable 实例访问元素然后将惰性形状重新附加到结果来工作。
instance Traversable (Traversed t) where
    traverse f (Traversed s c) = fmap (Traversed s) (traverse f c)