2016-01-07 1 views
-2

En the exercises j'ai mis en œuvre fmapT:Dans le tutoriel lets-lens, comment refactorisez-vous l'appel à traverser afin de le mettre en œuvre?

-- 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 @[email protected] can be recovered from @[email protected] using @[email protected] 
-- 
-- /Reminder:/ fmap :: Functor t => (a -> b) -> t a -> t b 
fmapT :: 
    Traversable t => 
    (a -> b) 
    -> t a 
    -> t b 
fmapT = 
    error "todo: fmapT" 

Maintenant, comment puis-je mettre over?

-- | Let's refactor out the call to @[email protected] as an argument to @[email protected] 

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

Pouvez-vous fournir quelques explications sur la fonction 'over'? –

+0

ajouter un edit sur la question, et en fait je ne sais pas ce qui est 'over' pour ... – rcmerci

Répondre

0

Vous pouvez mettre en œuvre à l'aide fmapTtraverse comme:

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

maintenant le prochain exercice est de factoriser cette fonction en fournissant traverse comme paramètre plutôt que de coder en dur dans la définition. Si vous choisissez Identity comme constructeur de type applicatif alors le type de traverse est:

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

si vous fournissez cela comme un paramètre à fmapT vous vous retrouvez avec quelque chose comme 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) 

depuis le Traversable la contrainte existe dans traverse il n'est pas requis par over' qui a le type plus général de over donné dans l'exercice c'est-à-dire

over :: ((a -> Identity b) -> (s -> Identity t)) -> (a -> b) -> s -> t 

et

over' = over traverse 
+0

Je dirais' over l f = runIdentity. l (Identité. f) 'est plus clair, ou même (en utilisant' Data.Profunctor.Unsafe') 'sur l f = runIdentity #. l (Identité #. f) '. Cela clarifie que, sur le plan opérationnel, «over» est juste la fonction d'identité. – dfeuer

+0

oui, 'sur l f s = runIdentity (l (Identité f) s)' est ok, mais comme il dit: '- | Refactorisons l'appel de @ traverse @ comme argument de @ fmapT @ .'votre implémentation n'est pas satistfy. – rcmerci

+0

@rcmerci - Voir mise à jour. – Lee