Kombinatoren
|
in Typklassen definieren: Control.Arrow
|
Arrow
|
class Arrow a where
arr :: (b -> c) -> a b c
(>>>) :: a b c -> a c d -> a b d
(***) :: a b c -> a b' c' -> a (b, b') (c, c')
(&&&) :: a b c -> a b c' -> a b (c, c')
first :: a b c -> a (b, d) (c, d)
second :: a b c -> a (d, b) (d, c)
|
| |
|
arr macht aus einer Funktion einen Arrow,
analog zu return bei Monaden
|
|
eigene Funktionstypen mit newtype definieren und geeignete Instanzen definieren
|
|
(->) ist eine Instanz von Arrow
|
|
Zu jeder Monade kann ein gleichwertiger Arrow konstruiert werden
|
|
Es gibt Arrows, zu denen es keine entsprechende Monade gibt
|
|
Arrows verwenden die gleiche Schnittstelle wie reine Funktionen
|
Beispiel
|
Funktionen mit mehreren Resultaten
|
List Arrow
|
newtype LA a b = LA { runLA :: a -> [b] }
instance Arrow LA where
arr f = LA $
\ x -> [f x]
LA f >>> LA g = LA $
\ x -> concat [ g y | y <- f x ]
LA f *** LA g = LA $
\ (x1, x2) -> [ (y1, y2) | y1 <- f x1
, y2 <- g x2
]
LA f &&& LA g = LA $
\ x -> [ (y1, y2) | y1 <- f x
, y2 <- g x
]
first (LA f) = LA $
\ (x1, x2) -> [ (y1, x2) | y1 <- f x1 ]
second (LA g) = LA $
\ (x1, x2) -> [ (x1, y2) | y2 <- g x2 ]
|
| |
|
Wie bei Monaden gibt es bei Arrows weitere Klassen (ArrowZero, ArrowPlus, ...)
|
ArrowZero,
ArrowPlus
|
class Arrow a => ArrowZero a where
zeroArrow :: a b c
class ArrowZero a => ArrowPlus a where
(<+>) :: a b c -> a b c -> a b c
|
| |
Instanzen
|
für Listen Arrows
|
|
instance ArrowZero LA where
zeroArrow = LA $ const []
instance ArrowPlus LA where
LA f <+> LA g = LA $ \ x -> f x ++ g x
|
| |
Beispiel |
|