2013-10-10 65 views
2

我試圖創建一個getter一個Lens和setter方法是我從另一個Lens有:構建一個相同的鏡頭

import Control.Lens 

idL :: Lens s t a b -> Lens s t a b 
idL l = lens (\s -> view l s) (\s b -> set l b s) 

但是,它未能與一個不起眼的(對我來說)錯誤:

Expected type: Getting a s a 
     Actual type: (a -> Accessor a b) -> s -> Accessor a t 
    In the first argument of `view', namely `l' 

我在做什麼錯?這可能是一些非常基本的東西,但是,唉,我還不知道究竟發生了什麼(Getting,Accessor),以便我自己解開它。

+0

這對我來說很好(啓用了'Rank2:Types'語言雜注)。你是從一個文件加載一個模塊,還是試圖在repl中定義'idL'? –

+0

@ChrisTaylor:啓用了'Rank2Types'的文件。如果有幫助,我也使用lens-3.9.0.3和ghc-7.6.3。 – Artyom

+0

我剛剛在GHCi中運行這個,沒有問題(顯式類型簽名雖然是必要的) – jozefg

回答

2

鏡頭中的view的類型要求參數Lens的類型爲Lens s s a a。 它不適用於一般類型Lens s t a b。這是因爲如果view的類型是一般化的,你需要編寫許多類型簽名。

但你可以做什麼看法呢,不限制類型:

import Control.Lens 
import Control.Applicative -- This imports Const 

idL :: Lens s t a b -> Lens s t a b 
idL l = lens (\s -> getConst $ l Const s) (\s b -> set l b s) 

我用Const代替Accessor類型,這樣的代碼將與鏡頭HEAD工作太(其中除去Accessor NEWTYPE)

+0

什麼版本的鏡頭是'view'簡化了?這不適合我 – jozefg

+0

我使用鏡頭3.9.0.2。 [view](http://hackage.haskell.org/package/lens-3.9.2/docs/Control-Lens-Getter.html#v:view)有一種'view :: Lens'sa'(注意該版本中的')。 – bennofs

+0

啊有趣的是,我似乎混淆了GHC使用不正確的鏡頭版本。哎呦 – jozefg