Conosco un po 'di Prolog e ho appena iniziato un po' di studio individuale in Haskell. Ho lavorato attraverso lo 99 Problems for Haskell, imparando molto lungo la strada e godendo davvero Haskell. A volte cerco di chiarire la mia comprensione di uno spazio problematico codificando qualcosa in Prolog e poi pensando a come quella soluzione potrebbe riguardare un approccio funzionale in Haskell. Stasera, mentre lavoravo sui problemi relativi alla logica (problemi 47 e 48), mi sono distratto nel tentativo di realizzare il semplice compito di creare un elenco degli elenchi di tutte le combinazioni di valori di verità con n valori. Voglio una funzione tValues :: Int -> [[Bool]]
. Questo problema può essere risolto in modo molto semplice e dichiarativa in Prolog, es .:Pensare al Prolog e ad Haskell - Generare liste di combinazioni di valori di verità
combinations_of_n_truth_values(N, AllValues) :-
findall(Values, n_truth_values(N, Values), AllValues).
n_truth_values(N, TruthValues) :-
length(TruthValues, N),
maplist(truth_value, TruthValues).
truth_value(true).
truth_value(false).
Quando usato, la variabile AllValues
sarà unificare con l'elenco desiderato di elenchi di valori di verità. Mi piacerebbe sapere come un esperto programmatore Haskell dovrebbe risolvere questo stesso problema. Mi aspetto che ci sia una soluzione altrettanto semplice e dichiarativa, ma non riesco a far funzionare il mio cervello di Haskell nel modo giusto.
ho giocherellava con alcuni semi-analoghi utilizzando list comprehension, come ad esempio il seguente:
tValues:: Int -> [[Bool]]
tValues 0 = []
tValues n = [v:vs | v <- tValue
, vs <- tValues (n-1) ]
tValue :: [Bool]
tValue = [True, False]
ma tValues
restituisce solo []
. Penso di aver bisogno solo di un impegno da uomo a uomo per aiutare a scuotere la mia mente in modo chiaro e magari a darmi una visione più profonda.
Molte grazie.
Grazie per la risposta! Penso che questo chiarisca alcuni problemi che stavo riscontrando quando cercavo di lavorare con le list comprehensions. È anche incoraggiante sapere che stavo trascurando un dettaglio minore, piuttosto che fondamentalmente malinteso sulla questione. Apprezzo anche la traduzione in linguaggio naturale, poiché i miei studi in Prolog mi hanno abituato a formulare risposte in semplici dichiarazioni dichiarative e costruire algoritmi su questa base. –
Sareste interessati a valutare la relazione tra questo approccio e gli altri offerti qui? Ad es., C'è una differenza ideologica che motiva l'uso esplicito della lista monad in contrasto con la sintassi list-builder, o è semplicemente una questione di stile/convenienza? In ogni caso, grazie ancora! –
@aBathologist: mi definisco ancora un principiante Haskell, quindi il mio punto di vista probabilmente non è realmente professionale. Per me, è più o meno una questione di convenienza: la sintassi di comprensione delle liste è facile da leggere e può essere compresa dai principianti di Haskell. Può anche essere immediatamente tradotto in una forma monadica: 'do {v <- [True, False]; vs <- tValues (n-1); return (v: vs);} '(i predicati possono essere fatti tramite' guard' da 'Control.Monad'). Questa versione intermedia monadica può aiutarti a trovare quelli eleganti come "flip replicateM [True, False] di m09". Alla fine tocca a te. – Zeta