14

¿Puedo unsugar lista por comprensión en esta expresión:Extracción de azúcar sintáctico: lista de comprensión Haskell

[(i,j) | i <- [1..4], j <- [i+1..4]] 

Ésta es la salida:

[(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)] 

cómo podré, con el mapa, filtro, etc. , escribe esa pieza de código?

edición

Aquí otro:

[(i,j,k) | i <- [1..6], j <- [i+1..6],k <- [j+1..6]] 

Ésta es la salida:

[(1,2,3),(1,2,4),(1,2,5),(1,2,6),(1,3,4),(1,3,5),(1,3,6),(1,4,5),(1,4,6),(1,5,6),(2,3,4),(2,3,5),(2,3,6),(2,4,5),(2,4,6),(2,5,6),(3,4,5),(3,4,6),(3,5,6),(4,5,6)] 

Respuesta

23

listas por comprensión (de hecho, comprensiones Monad) se pueden desazucaradas en do notación.

do i <- [1..4] 
    j <- [i+1..4] 
    return (i,j) 

Cuál puede ser Desazucarado como de costumbre:

[1..4] >>= \i -> 
[i+1..4] >>= \j -> 
return (i,j) 

Es bien sabido que a >>= \x -> return b es lo mismo que fmap (\x -> b) a. Así un paso desugaring intermedio:

[1..4] >>= \i -> 
fmap (\j -> (i,j)) [i+1..4] 

Para listas, (>>=) = flip concatMap, y fmap = map

(flip concatMap) [1..4] (\i -> map (\j -> (i,j) [i+1..4]) 

flip simplemente cambia el orden de las entradas.

concatMap (\i -> map (\j -> (i,j)) [i+1..4]) [1..4] 

Y así es como terminas con la respuesta de Tsuyoshi.


La segunda forma similar se puede Desazucarado en:

concatMap (\i -> 
    concatMap (\j -> 
    map  (\k -> 
     (i,j,k)) 
    [j+1..6]) 
    [i+1..6]) 
[1..6] 
1
concatMap (\i -> map (\j -> (i, j)) [i+1 .. 4]) [1 .. 4] 
+0

Gracias por su respuesta :) – Carlochess

2

El código Desazucarado es:

concatMap (\i -> concatMap (\j -> (i, j) : []) [i+1..4]) [1..4] 

Que se puede refactorizar a la respuesta de Tsuyoshi Ito.

2

Existe otro esquema de traducción, que se debe a Wadler, por lo que yo sé.

Esto daría:

let 
    lc_outer (x:xs) = let lc_inner (y:ys) = (x,y) : lc_inner ys 
          lc_inner []  = lc_outer xs 
         in lc_inner [x+1.. 4] 
    lc_outer [] = [] 
in lc_outer [1..4] 

Esta traducción se evita la construcción innecesaria de listas simples en el nivel más interno que tendría que obtener aplanado con concatMap más tarde.

Cuestiones relacionadas