在let-lens教程中,如何重构遍历调用以实现?

时间:2016-01-07 13:50:12

标签: haskell traversal functor lens

the exercises我已实施fmapT

-- Let's remind ourselves of Traversable, noting Foldable and Functor.
--
-- class (Foldable t, Functor t) => Traversable t where
--   traverse ::
--     Applicative f => 
--     (a -> f b)
--     -> t a
--     -> f (t b)

-- | Observe that @fmap@ can be recovered from @traverse@ using @Identity@.
--
-- /Reminder:/ fmap :: Functor t => (a -> b) -> t a -> t b
fmapT ::
  Traversable t =>
  (a -> b)
  -> t a
  -> t b
fmapT =
  error "todo: fmapT"

现在我该如何实施over

-- | Let's refactor out the call to @traverse@ as an argument to @fmapT@.

over ::
  ((a -> Identity b) -> s -> Identity t)
  -> (a -> b)
  -> s
  -> t
over = error "undefined"

1 个答案:

答案 0 :(得分:0)

您可以使用fmapT实施traverse

fmapT f s = runIdentity (traverse (Identity . f) s)

现在,下一个练习是通过提供traverse作为参数来重构此函数,而不是在定义中对其进行硬编码。如果您选择Identity作为适用类型构造函数,则traverse的类型为:

(Traversable t) => (a -> Identity b) -> t a -> Identity (t b)

如果您将此作为fmapT的参数提供,那么您最终会得到类似over的内容:

over' :: Traversable t => ((a -> Identity b) -> t a -> Identity (t b)) -> (a -> b) -> t a -> t b
over' l f s = runIdentity (l (Identity . f) s)

由于Traversable中存在traverse约束,over'并不要求over具有更一般的over :: ((a -> Identity b) -> (s -> Identity t)) -> (a -> b) -> s -> t 类型,即<* p}}。

over' =  over traverse

Point