Haskell lenses: how to make view play nicely with traverse? -
i trying learn lenses implementing in haskell. have implemented view
combinator follows:
{-# language rankntypes #-} import control.applicative import data.traversable type lens s = functor f => (a -> f a) -> s -> f s view :: lens s -> s -> view lens = getconst . lens const
however when try use in conjunction traverse
following error message:
prelude> :load lens.hs [1 of 1] compiling main ( lens.hs, interpreted ) ok, modules loaded: main. *main> :t view traverse <interactive>:1:6: not deduce (applicative f) arising use of ‘traverse’ context (traversable t) bound inferred type of :: traversable t => t -> @ top level or (functor f) bound type expected context: functor f => (a -> f a) -> t -> f (t a) @ <interactive>:1:1-13 possible fix: add (applicative f) context of type expected context: functor f => (a -> f a) -> t -> f (t a) or inferred type of :: traversable t => t -> in first argument of ‘view’, namely ‘traverse’ in expression: view traverse
unfortunately, don't understand error message. please explain means , how may fix it.
as other answers explain, issue view
expects works functor f
, traverse
works if f
applicative
(and there functors not applicative).
in lens
, problem solved making type of view
not take rank2
argument (in fact, functions in lens don't use lens type synonym, use weaker). function, observe view
ever uses f ~ const
. why can change type signature to:
view :: ((a -> const a) -> s -> const s) -> s ->
the implementation can stay same, view
works on traverse
:
view traverse :: (traversable t, monoid a) => t ->
note monoid
constraint. constraint appears because if set f ~ const a
in traverse :: (traversable t, applicative f) => (a -> f a) -> t -> f (t a)
, need instance applicative (const a)
. instance has monoid
constraint on a
though. , makes sense, because traversable might empty or contain more 1 element, need mempty
, mappend
.
Comments
Post a Comment