Come primo passo osserviamo che la definizione
outputList x y = concat . map ($ y) $ map ($ x) [getRow,getColumn,getBlock]
può essere riscritta utilizzando l'operatore composizione funzione (.)
invece dell'operatore dell'applicazione funzione ($)
come segue.
outputList x y = (concat . map ($ y) . map ($ x)) [getRow,getColumn,getBlock]
Successivo notiamo che map
è un altro nome per fmap
nelle liste e soddisfa le fmap
leggi, quindi, in particolare, abbiamo map (f . g) == map f . map g
. Applichiamo questa legge per definire una versione utilizzando una singola applicazione di map
.
outputList x y = (concat . map (($ y) . ($ x))) [getRow,getColumn,getBlock]
Come passo finale che può sostituire la composizione di concat
e map
da concatMap
.
outputList x y = concatMap (($ y) . ($ x)) [getRow,getColumn,getBlock]
Infine, a mio parere, anche se i programmatori Haskell tendono ad usare molti operatori di fantasia, non è una vergogna per definire la funzione da
outputList x y = concatMap (\f -> f x y) [getRow,getColumn,getBlock]
come si esprime chiaramente, ciò che la funzione fa. Tuttavia, l'uso di astrazioni di classe del tipo (come dimostrato nell'altra risposta) può essere una buona cosa in quanto si potrebbe osservare che il problema ha una certa struttura astratta e acquisire nuove conoscenze.
A proposito, ci sono delle statiche quanto tempo ci vuole prima che una domanda riguardante Haskell abbia una risposta? Ho l'impressione che al 90 percento di tutte le domande di Haskell venga data una risposta quasi immediata. Anche se questo non dice nulla sulla qualità delle risposte, a mio parere hanno anche una qualità piuttosto elevata. –
@JanChristiansen: Puoi rispondere usando lo stack exchange data explorer se vuoi. Ho fatto un'approssimazione molto approssimativa (filtro i valori anomali ovvi, ignorare le risposte auto-rispondenti, ecc.), E il tempo tipico (cioè mediano) era di circa 20 minuti fino a quando non è stata pubblicata la prima risposta. –