2014-12-24 21 views
5

Sono nuovo di Haskell e ho giocato con Arrows. Mi piacerebbe scrivere uno strumento che possa "disassemblare" a livello di programmazione una freccia costruita in precedenza. Come un potenziale applicazione, immaginare una funzione che prende in una freccia e restituisce un grafo orientato che rappresenta tutte le concatenazioni, spaccature, fan-out, eccDeconstructing Frecce in Haskell

EG, (f & & & g) >>> h rese qualcosa come

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

inizialmente ho pensato che potrei essere in grado di fare questo tramite il pattern matching, come nel semplice sotto (adattato da haskell.org Freccia tutorial), ma non ha funzionato.

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 

Tutti i miei tentativi di fare questo definendo i miei tipi (vale a dire, un tipo parametrico che include i tipi di bambini costituenti pure) hanno anche fallito.

C'è un modo per "separare" i componenti di una freccia una volta che è stata costruita?

risposta

5

È possibile creare una freccia libera, che è come un albero, in modo da poterne ispezionare la struttura. O abbassalo alla freccia sottostante. Un altro esempio è nell'altra domanda SO: Useful operations on free arrows

+0

Grazie per il suggerimento. Non ho molta esperienza con le monadi libere (molto meno frecce libere), ma ciò che suggerisci sembra promettente. – jadaska

1

La risposta sarà no in generale, perché fanout e composizione e gli altri operatori freccia sono funzioni, non costruttori. Puoi "separare", per esempio, un albero, perché la composizione di alberi da altri alberi preserva i costruttori utilizzati per eseguire la composizione, e in seguito Haskell può eseguire il pattern-match su di essi. Ma non vi è alcuna garanzia che le frecce di composizione conservino i fanouts e le composizioni utilizzate per eseguire la composizione. È come aggiungere 2 + 3 e poi provare a separare il 5 più tardi.

+0

... a meno che qualcuno rimuova quella freccia (~>) => (a -> b) -> (a ~> b) 'assurdità dalla definizione dell'istanza di Arrow. –