Sostituzione sostituibile e pieghevole per Uniplate?

0

Ho una sorta di linguaggio minimale (una sorta di parser per CLI simile a CISCO) con parser descritto di seguito. Il parser dovrebbe essere serializzabile su JSON, ecco perché non Parsec o Attoparsec.

Ho bisogno di una sorta di albero di completamento per quei comandi, cioè per ogni prefisso ci dovrebbero essere tutti i possibili comandi secondari. Il tipo Cp descrive la struttura di comando di base, cioè l'intera lingua ha tipo [Cp] .

Per costruire un albero di completamento devo attraversare ricorsivamente il tipo Cp e costruire tutte le possibili coppie (Prefix, [Completion]) .

So come farlo manualmente. So come farlo con uniplate (para dovrebbe funzionare). La domanda è: sono un sostituto moderno pieghevole / attraversabile per Uniplate, dovrei implementarlo usando uno di questi?

Per me sembra che i tipi di Traversable non corrispondano al mio caso. Che dire di Foldable ? Dovrei usarlo o uniplate è ancora attuale e soluzione per casi come questo?

type Str = Text

data Command = Command Prefix CmdArgs
               deriving Show

type Prefix  = [Str]
type CmdArgs = [CmdArg]
type CmdArg  = (Str,Str)

data Cp =  P Str              -- single token prefix
         | Arg Str            -- arbitrary string or atom
         | B Cp Cp            -- branch: first or second
         | S Cp Cp            -- non-empty sequence of items
         | O Cp               -- optional sequence
         | Discard Cp         -- discards result of nested parser
         | N                  -- null parser, parses nothing
         deriving (Generic,Show)
    
posta voidlizard 05.08.2016 - 05:56
fonte

1 risposta

1

Dopo aver esaminato il tuo codice, ora dubito che sia Pieghevole o Traversabile ti aiuteranno.

Come ho detto nei commenti, entrambe sono classi sul tipo costruttori - cioè tipi di tipi * -> * , così faresti aggiungere un parametro di tipo a data Cp , cioè:

data Cp a =  P a
          |  Arg a
          |  B (Cp a) (Cp a)
          ...

Ma anche se lo facessi, nessuna delle due classi si adatta al tuo problema.

I metodi in Travesable restituiscono un altro contenitore dello stesso genere. (Presumibilmente il contenitore restituito ha la stessa forma.)

I metodi in Pieghevoli sembrano più promettenti, ma non lo sono lavoro perché la tua funzione di piegatura non è fornita contesto da cui proviene il a . Cioè, non lo farà ti viene detto se proviene da un costruttore P o Arg costruttore.

Come menzionato nei documenti per foldr , abbiamo questa "legge" per foldr :

foldr f z = foldr f z . toList

Il foldr sul LHS proviene dalla classe Pieghevole mentre il foldr sul RHS è quello per le liste. Quindi un foldr su Cp Str è equivalente a un foldr su [Str] che mostra chiaramente che non puoi trattare un Str che proveniva da P Str in modo diverso da uno proveniente da Arg Str .

    
risposta data 05.08.2016 - 14:46
fonte

Leggi altre domande sui tag