2017-09-08 3 views
3

vergleicht ich versuche mit Typ einen Vergleichsoperator greater-than-gleichHaskell Linse Getter, die Werte von zwei Linsen Getter

für zwei lens Getter zu schreiben
(.>=.) :: Ord a => Getting a s a -> Getting a s a -> Getting Bool s Bool 

Ich habe eine Arbeitslösung für ein Getter auf der linken Seite und ein Wert auf der rechten Seite (nicht . auf der rechten Seite des Operators .>=)

ich versuche

left .>=. right = (>=) <$> use left <*> use right 

aber es hat Typ

(.>=.) :: (Ord a, MonadState s f) => Getting a s a -> Getting a s a -> f Bool 

Wie kann ich den gewünschten Rückgabetyp Getting Bool s Bool statt f Bool bekommen?

Antwort

5

Sie sind in der Nähe mit diesem:

λ> left .>=. right = (>=) <$> use left <*> use right 
(.>=.) :: 
    (Ord a, Control.Monad.State.Class.MonadState s f) => 
    Getting a s a -> Getting a s a -> f Bool 

Verwenden Sie zuerst view in statt use; use ist für den Erhalt von Zustand (daher die MonadState Einschränkung), die hier nicht relevant erscheint.

λ> left .>=. right = (>=) <$> view left <*> view right 
(.>=.) :: 
    (Ord a, Control.Monad.Reader.Class.MonadReader s f) => 
    Getting a s a -> Getting a s a -> f Bool 

, dass Sie eine Funktion gibt (MonadReader s f => f Bool spezialisiert auf s -> Bool), so jetzt müssen Sie dies mit to in eine Getting einzuschalten.

λ> left .>=. right = to $ (>=) <$> view left <*> view right 
(.>=.) :: 
    (Ord a, Contravariant f, Profunctor p) => 
    Getting a s a -> Getting a s a -> Optic' p f s Bool 

(Und (Contravariant f, Profunctor p) => Optic' p f s Bool ist spezialisiert auf Getting Bool s Bool, so ist dies, was Sie wollen.)