14

Mogę unsugar listowych w tym wyrażeniu:Usuwanie cukier syntaktyczny: rozumienie listy w Haskell

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

To wyjście:

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

Jak mogę, z mapą, filtr i tak dalej , napisz ten fragment kodu?

edit

tutaj jakiś inny:

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

To wyjście:

[(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)] 

Odpowiedz

23

Wyliczenia listy (w rzeczywistości wyrażenia Monady) można odczytywać w notacji do.

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

który można odcukrzona jak zwykle:

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

Powszechnie wiadomo, że a >>= \x -> return b jest taka sama jak fmap (\x -> b) a. Więc etap pośredni desugaring:

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

Na listach, (>>=) = flip concatMap i fmap = map

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

flip prostu przełącza kolejność wejść.

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

I tak kończy się odpowiedź Tsuyoshi.


Drugim może być podobnie odcukrzona do:

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

Dzięki za odpowiedź :) – Carlochess

2

Kod Odcukrzony jest:

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

Który może być refaktoryzowany do odpowiedzi Tsuyoshi Ito.

2

Jest jeszcze inny schemat tłumaczenie, że jest to spowodowane Wadler, o ile wiem.

Dałoby:

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] 

To tłumaczenie unika niepotrzebnych budowę pojedynczych list w najgłębszym poziomie, który trzeba uzyskać spłaszczone z concatMap później.

Powiązane problemy