2017-08-21 5 views
1

なぜGHCiのは、ここで必要なコンテキストの制約を追加ん:GHCIはいつ必要なコンテキストを推測しませんか?

> let f = fmap show 

> :t f 
f :: (Functor f, Show a) => f a -> f String 

しかし、ここにいませんの?

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

> :t _all' 
_all' :: (Applicative f, Eq a) => a -> (a -> f a) -> [a] -> f [a] 

> :t over (_all' 2) 

<interactive>:1:7: error: 
    • Could not deduce (Applicative f) arising from a use of ‘_all'’ 

これら2つのケースに大きな違いはありますか?

+6

['lens'](https://hackage.haskell.org/package/レンズ-4.15.4/docs/Control-レンズ - Setter.html#v:over)ライブラリつまり、 'Lens'は' forall f 'なので、あなたのバージョンは動作しません。ファンクターf => ..'と '_all '2 :: forall f。申請f => ..';言い換えれば、 'over'は' Functor'のために働く関数を要求していますが、 'Applicative'のためだけに機能する関数を提供しています(これは' Functor'が 'Applicative ')。 – user2407038

+0

@ user2407038これは答えです。 – Zeta

+0

右辺の式でのみ明示的な署名が利用可能であると、推論者が左辺の適切な制約を導き出す前に型チェッカを操作するのに十分です。私はそれが必要であるか付随的であるかを理解していないので、これをコメントとして投稿しています。 – sevo

答えて

1

レンズライブラリで定義されたoverのタイプではありません。それは言われて、あなたのバージョンでは動作しませんLensは、言い換えれば

type Lens = forall f. Functor f => (a -> f b) -> s -> f t 

_all' 2 :: forall f. Applicative f => .. 

あるので、overはどのFunctorのために働く機能を要求されていますが、どれを提供してきましたApplicativeFunctorにはより強い制約であり、Applicativeを意味しません)の場合にのみ機能します。

コメント@ user2407038。

コメントに示されているように、タイプシグネチャをoverに固定することで問題を解決できます。それは、どちらかのアイデンティティのタイプはファンクタと応用的の両方であるためlensで複雑な派手なものは分配ファンクタまたは単純

type Setter s t a b = (a -> Identity b) -> s -> Identity t 
over :: Setter s t a b -> (a -> b) -> s -> t 

を使用する必要があり、それはレンズを一元管理とトラバーサル(私はあなたのケースで想定します)。

+0

もっと具体的な質問は、なぜGHCは右辺にあるものから推測できるのかという制約が与えられたときに、式の左辺の文脈を推論しないのですか? – sevo

+0

私は推論がここで問題ではないと思う。 'over(_all '2)'の型チェックにはあまりにも過度に 'over'を定義しているので、方法はありません。 'forall fのための道は決してありません。 Functor f => ... 'を使用して' Applicative f => ... 'とタイプチェックします。 GHCが適切な文脈を推論することはできません。それは不可能な何かを推測するようにあなたに求めてきたことです。 – hao

関連する問題