TL;博士 - 根據您的Lens
定義,traverse
不能是Lens
因爲traverse
並不適用於所有Functor
的工作。
讓我們來看看你的類型:
λ :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)
所以,現在很明顯,如果traverse
是成爲Lens
,它必須是一個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
型號必須是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
的子集也是Applicative
。因此,traverse
的類型是更具體的比Lens
es允許的類型。
很好的回答。非常感謝你爲這個問題提供了一個明智的解決方案。我確實有一個問題:'view'的類型簽名不會變成'((a - > Const a a) - > s - > Const a s) - > s - > a'? – 2014-09-11 02:29:54
@AaditMShah哦,你說得對。我會糾正這一點 – bennofs 2014-09-11 14:39:04