Reputation: 4609
I have a function that I believe is stricter than lens because of Applicative f
context.
Prelude Text.XML.Lens Data.Maybe Data.String Text.XML> :t f
f :: Control.Applicative.Applicative f =>
(Element -> f Element) -> Document -> f Document
This is because I obtained it from some Traversal
.
Prelude Text.XML.Lens Data.Maybe Data.String Text.XML> let f = root ./ ell "parent"
I want to pass it to a function that expects a monomorphic ALens
:
Prelude Text.XML.Lens Data.Maybe Data.String Text.XML> :t textFrom
textFrom
:: Data.Text.Internal.Text
-> s -> ALens s s Element Element -> Maybe Data.Text.Internal.Text
Prelude Text.XML.Lens Data.Maybe Data.String Text.XML> textFrom "groupId" pom f
But I don't really understand why this Applicative
instance is needed. I must be using this API incorrectly. What am I doing wrong?
No instance for (Control.Applicative.Applicative
(Control.Lens.Internal.Context.Pretext (->) Element Element))
arising from a use of ‘f’
In the third argument of ‘textFrom’, namely ‘f’
In the expression: textFrom "groupId" pom f
In an equation for ‘it’: it = textFrom "groupId" pom f
Prelude Text.XML.Lens Data.Maybe Data.String Text.XML> :t f
f :: Control.Applicative.Applicative f =>
(Element -> f Element) -> Document -> f Document
Prelude Text.XML.Lens Data.Maybe Data.String Text.XML> :t textFrom
textFrom
:: Data.Text.Internal.Text
-> s -> ALens s s Element Element -> Maybe Data.Text.Internal.Text
Prelude Text.XML.Lens Data.Maybe Data.String Text.XML> textFrom "groupId" pom f
<interactive>:68:24:
No instance for (Control.Applicative.Applicative
(Control.Lens.Internal.Context.Pretext (->) Element Element))
arising from a use of ‘f’
In the third argument of ‘textFrom’, namely ‘f’
In the expression: textFrom "groupId" pom f
In an equation for ‘it’: it = textFrom "groupId" pom f
Upvotes: 1
Views: 128
Reputation: 24166
f
isn't a Lens
, so can't be used as ALens
. When you see ALens
as an argument to a function, it expects a Lens
.
A polymorphic value that requires an Applicative
instance can be used fewer places than a value that only requires a Functor
.
Applicative f => (Element -> f Element) -> Document -> f Document -- :t f
Functor f => (Element -> f Element) -> Document -> f Document -- :t Lens' Element Document
You'd like to pass f
in place of an ALens s s Element Element
. I'm going to work through what that type is. I'll use E
in place of Element
to keep this short
type ALens s t a b = LensLike (Pretext (->) a b) s t a b
ALens s s E E = Lenslike (Pretext (->) E E) s s E E
The type gets really long when we substitute for LensLike
. The only thing that's going on here is Pretext (->) E E
is taking the place of f
everywhere.
type LensLike f s t a b = (a -> f b) -> s -> f t
LensLike (Pretext (->) E E) s s E E = (E -> (Pretext (->) E E) E) -> s -> (Pretext (->) E E) s
Comparing this to the type of f
we have (I'm going to use D
in place of Document
to keep this short`.
Applicative f => (E -> f E) -> D -> f D -- :t f
(E -> (Pretext (->) E E) E) -> s -> (Pretext (->) E E) s -- ALens s s E E
In order to use a value of the first type where the second is needed there must be an Applicative
instance for Pretext (->) E E
, but a Pretext
only has a Functor
instance. If f
were actually a Lens
and was defined for any Functor
instead of any Applicative
it would work here. That's the source of the error you are getting.
Upvotes: 2