2014-10-14 7 views
3

Я сделал минимальный пример для тестирования fclabels. Использование объектива для получения «правильного» значения из любого значения. Почему это не удается? Я пропустил что-то?Сбой типа при использовании «левого» объектива из fclabels

module Label where 
import Data.Label 
import Data.Label.Base 

test = get right (Right "test") 

{- Will fail with this message: 
Label.hs:5:12: 
    No instance for (Control.Arrow.ArrowZero Data.Label.Point.Total) 
     arising from a use of `right' 
    Possible fix: 
     add an instance declaration for 
     (Control.Arrow.ArrowZero Data.Label.Point.Total) 
    In the first argument of `get', namely `right' 
    In the expression: get right (Right "test") 
    In an equation for `test': test = get right (Right "test") 
Failed, modules loaded: none. 

-- Tested with fclabels-2.0.2 
-} 

ответ

2

Ошибка довольно туманна, но она становится яснее, когда мы рассмотрим типы и документации get и right:

get :: (f :-> a) -> f -> a 
type :-> f o = Lens Total f o 

right :: (ArrowZero arr, ArrowApply arr, ArrowChoice arr) 
     => Lens arr (Either a b -> Either a o) (b -> o) 

-- Lens pointing to the right value in an Either. (Partial and polymorphic) 

По существу get вы используете только для общей линзы, но right не является полным объективом, так как он не будет работать, если значение было Left. Ошибка говорит о том, что для частичной линзы требуется, чтобы тип несущей был ArrowZero, но что общие линзы не могут этого сделать.

Если вы экспериментируете в ghci, вы получаете эту ошибку только от вызова get right без каких-либо аргументов.

Если вы введете налог с Data.Label на номер Data.Label.Partial, тогда ваш код будет работать. test заканчивается типом Maybe String.