trovo che amplia l'elenco di comprensione rende più facile da leggere:
[ m | n <- [1..5], m <- [2*n,3*n] ]
Potrebbe essere utile esaminare esattamente cosa fa e in che modo si riferisce ad altre soluzioni. Definiamo come una funzione:
mult lst = [ m | n <- lst, m <- [2*n,3*n] ]
Dopo un modo, questo desugars a
mult' lst =
concatMap (\n -> concatMap (\m -> [m]) [2*n,3*n]) lst
L'espressione concatMap (\m -> [m])
sta avvolgendo m
in un elenco per appiattire immediatamente — è equivalente a map id
.
confrontare questo a @ di FunctorSalad risposta:
mult1 lst = concatMap (\n -> [n*2,n*3]) lst
Abbiamo ottimizzato via concatMap (\m -> [m])
.
Ora @ risposta di Vili:
mult2 lst = concat [ [(n*2),(n*3)] | n <- lst]
Questo desugars a:
mult2' lst = concat (concatMap (\n -> [[2*n,3*n]]) lst)
Come nella prima soluzione di cui sopra, stiamo inutilmente creando una lista di liste che dobbiamo concat
via.
Non penso che ci sia una soluzione che utilizza le list comprehensions, ma desugars su mult1
. La mia intuizione è che i compilatori Haskell sono in genere abbastanza intelligenti da non importare (o, in alternativa, che gli inutili concat
s sono economici a causa di una valutazione lenta (mentre sono letali in lingue volgari)).
Per 'istanza Monad []', '(>> =) == flip concatMap' ... sembra che la risposta di Chris abbia sorvolato quella parte, ma questa risposta è un sottoinsieme di quello sopra. – ephemient