2014-12-24 9 views
5

Ich bin neu in Haskell und habe mit Arrows herumgespielt. Ich möchte ein Werkzeug schreiben, das programmatisch einen zuvor erstellten Pfeil "zerlegen" kann. Als mögliche Anwendung vorstellen, eine Funktion, die einen gerichteten Graphen in einem Pfeil und zurücknimmt, die alle Verkettungen, Splits, Fan-outs darstellt usw.Dekonstruieren von Pfeilen in Haskell

Eg, (f & & & g) >>> h Ausbeuten so etwas wie

----- f ---- 
---|   |--- h ----- 
    ----- g ---- 

ich zunächst dachte, ich könnte diese Anpassung über Muster tun, wie in den einfachen unten (angepasst von haskell.org Pfeil Tutorial), aber es hat nicht funktioniert.

module Main(main) where 

import Control.Arrow 
import Control.Category 
import Prelude hiding (id, (.)) 

newtype SimpleFunc a b = SimpleFunc {runF :: (a -> b)} 

instance Arrow SimpleFunc where 
    arr f = SimpleFunc f 
    first (SimpleFunc f) = SimpleFunc (mapFst f) where 
     mapFst g (a,b) = (g a, b) 
    second (SimpleFunc f) = SimpleFunc (mapSnd f) where 
     mapSnd g (a,b) = (a, g b) 

instance Category SimpleFunc where 
    (SimpleFunc g) . (SimpleFunc f) = SimpleFunc (g . f) 
    id = arr id 


f,g :: SimpleFunc Int Int 
f = arr (\x -> x - 5) 
g = arr (\x -> 3*x + 1) 

h1 :: SimpleFunc Int Int 
h1 = f >>> g 

h2 :: SimpleFunc Int (Int, Int) 
h2 = f &&& g 

# It would be great if I something like this worked 
is_split :: SimpleFunc a b -> Bool 
is_split (a1 >>> a2) = False 
is_split (a1 &&& a2) = True 
.... 

is_split h2 -- evaluates to True 
is_split h1 -- evaluates to False 

All meine Versuche, dies zu tun, meine eigene Art durch die Definition (das heißt, ein parametrisierte Typ, als auch Arten der konstituierenden Kinder umfasst) ist ebenfalls gescheitert.

Gibt es eine Möglichkeit, die Komponenten eines Pfeils "auseinander zu ziehen", nachdem er konstruiert wurde?

Antwort

5

Sie können einen freien Pfeil erstellen, der wie ein Baum ist, damit Sie seine Struktur überprüfen können. Oder senken Sie es auf den darunter liegenden Pfeil. Ein Beispiel ist in der anderen SO Frage: Useful operations on free arrows

+0

Danke für den Tipp. Ich habe nicht viel Erfahrung mit freien Monaden (viel weniger freie Pfeile), aber was Sie vorschlagen, klingt vielversprechend. – jadaska

1

Die Antwort wird im Allgemeinen nein sein, weil Fanout und Zusammensetzung und die anderen Pfeiloperatoren Funktionen, nicht Konstruktoren sind. Sie können "auseinander ziehen", sagen wir, einen Baum, weil das Konstruieren von Bäumen aus anderen Bäumen die Konstruktoren beibehält, die zum Ausführen der Komposition verwendet werden, und dann kann Haskell Mustervergleiche auf ihnen vornehmen. Es gibt jedoch keine Garantie dafür, dass die Kompositionspfeile die Fanouts und Kompositionen beibehalten, die für die Komposition verwendet wurden. Es ist wie 2 + 3 und dann versuchen, die 5 später auseinander zu ziehen.

+0

... es sei denn, jemand entfernt das Pfeil (~>) => (a -> b) -> (a ~> b) 'Unsinn von Arrow-Instanz-Definition. –

Verwandte Themen