tl;dr - 根据您对 的定义Lens
,atraverse
不能是 a Lens
,因为traverse
不适用于所有Functor
s。
让我们看看你的类型:
λ :set -XRankNTypes
λ :m +Control.Applicative Data.Traversable
λ type Lens s a = Functor f => (a -> f a) -> s -> f s
λ :t traverse
traverse
:: (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b)
现在在这一点上,我们可以看到traverse
,在某种程度上,它比我们的Lens
类型稍微更通用 - 它可以从a -> f b
我们的镜头只能从a -> f a
.
把它限制在那种情况下是没有问题的,所以我们可以说
λ :t traverse :: (Traversable t, Applicative f) => (a -> f a) -> t a -> f (t a)
traverse :: (Traversable t, Applicative f) => (a -> f a) -> t a -> f (t a)
:: (Applicative f, Traversable t) => (a -> f a) -> t a -> f (t a)
所以现在很明显 if traverse
is 是 a Lens
,它必须是 a Lens (t a) a
,因为这是使类型变量对齐的唯一方法。
所以让我们试试看。
λ :t traverse :: Lens (t a) a
<interactive>:1:1:
Could not deduce (Traversable t1) arising from a use of `traverse'
from the context (Functor f)
bound by the inferred type of
it :: Functor f => (a -> f a) -> t a -> f (t a)
at Top level
or from (Functor f1)
bound by an expression type signature:
Functor f1 => (a1 -> f1 a1) -> t1 a1 -> f1 (t1 a1)
at <interactive>:1:1-24
Possible fix:
add (Traversable t1) to the context of
an expression type signature:
Functor f1 => (a1 -> f1 a1) -> t1 a1 -> f1 (t1 a1)
or the inferred type of
it :: Functor f => (a -> f a) -> t a -> f (t a)
In the expression: traverse :: Lens (t a) a
哎呀,它不喜欢那样。哦,等等,为了使用traverse
我们的类型t
has to be Traversable
,所以让我们添加这个限制。(就像“可能的修复”)建议:
λ :t traverse :: Traversable t => Lens (t a) a
<interactive>:1:1:
Could not deduce (Applicative f1) arising from a use of `traverse'
from the context (Functor f, Traversable t)
bound by the inferred type of
it :: (Functor f, Traversable t) => (a -> f a) -> t a -> f (t a)
at Top level
or from (Traversable t1, Functor f1)
bound by an expression type signature:
(Traversable t1, Functor f1) =>
(a1 -> f1 a1) -> t1 a1 -> f1 (t1 a1)
at <interactive>:1:1-41
Possible fix:
add (Applicative f1) to the context of
an expression type signature:
(Traversable t1, Functor f1) =>
(a1 -> f1 a1) -> t1 a1 -> f1 (t1 a1)
or the inferred type of
it :: (Functor f, Traversable t) => (a -> f a) -> t a -> f (t a)
In the expression: traverse :: Traversable t => Lens (t a) a
好的,所以现在的问题是它不能推断那f
是Applicative
(也需要使用traverse
),只是它是一个Functor
(它从 的定义中得到Lens
)。
但是我们不能添加Applicative f
到上下文中 -f
是隐藏的。当我们说 时type Lens s a = Functor f => (a -> f a) -> s -> f s
,我们说的是Lens
必须为所有 Functor
s 工作。
但traverse
仅适用于也是Functor
s的子集Applicative
。因此,通过这种方式,类型的类型比 es 允许的traverse
类型更具体。Lens