2016-06-29 16 views
2

Hier ist meine Art:Wie "Iso" zu komponieren?

newtype SaneDate = SaneDate UniversalTime 
    deriving (Show, Eq, Typeable, Generic) 
makeWrapped ''SaneDate 

Jetzt brauche ich ein ISO mit dieser Art:

reprBuild :: Iso' (Maybe UniversalTime) (Fist SaneDate) 

ich dies tat:

reprBuild = iso 
    (\ t -> First (SaneDate <$> t)) 
    (\ sane_first -> fmap (^. _Wrapped) $ getFirst sane_first ) 

Aber ich habe den Eindruck, ich arbeite extra schwer. Gibt es eine (kürzere) Möglichkeit, die reprBuild iso als eine Zusammensetzung der Dinge zu schreiben?

Antwort

3

Mit safe coercions:

import Data.Coerce 

reprBuild2 :: Iso' (Maybe UniversalTime) (First SaneDate) 
reprBuild2 = iso coerce coerce 

Es prüft geben - keine weiteren Tests durchgeführt wurden.

+0

Ok, das kompiliert und die Tests bestehen. – dsign

4

Die mapping combinator können Sie ein Iso über jeden Funktor (in diesem Fall die Maybe Funktors) heben:

reprBuild' :: Iso' (Maybe UniversalTime) (Maybe SaneDate) 
reprBuild' = mapping _Unwrapped 

Wir können auch die Tatsache nutzen, dass First hat eine Wrapped Beispiel die ISO Sie erhalten möchten:

reprBuild :: Iso' (Maybe UniversalTime) (First SaneDate) 
reprBuild = mapping _Unwrapped . _Unwrapped 

Sie können auch den Zwang Isomorphismus verwenden: coerced aber dies wird nur newtype-Wrapper über und braucht ghc> = 7.10.