Domanda

Diciamo che ho la seguente funzione:

sumAll :: [(Int,Int)] -> Int
sumAll xs = foldr (+) 0 (map f xs)
  where f (x,y) = x+y

Il risultato di sumAll [(1,1),(2,2),(3,3)] sarà 12.

Quello che non capisco è dove i valori (x,y) sono provenienti da. Beh, so che provengono dalla variabile xs ma io non capisco come. Voglio dire, facendo il codice sopra direttamente senza la parola chiave in cui, sarebbe qualcosa di simile:

sumAll xs = foldr (+) 0 (map (\(x,y) -> x+y) xs)

E non riesco a capire, nel codice in alto, come fa la variabile f e le variabili (x,y) rappresentano l'espressione (\(x,y) -> x+y) lambda.

È stato utile?

Soluzione

In Haskell, le funzioni sono tipi di dati di prima classe.

Questo significa che è possibile passare funzioni in giro come gli altri tipi di dati come numeri interi e stringhe.

Nel codice di cui sopra si dichiara 'f' essere una funzione, che prende in un'argumenta (una tupla di due valori (x, y)) e restituisce il risultato di (x + y).

foldr è un'altra funzione che prende in 3 argomenti, una funzione binaria (in questo caso +) un valore iniziale (0) ed una serie di valori di iteratore.

In breve 'dove f (x, y) = x + y' è solo ambito scorciatoia per

sumAll :: [(Int,Int)] -> Int
sumAll xs = foldr (+) 0 (map myFunctionF xs)

myFunctionF :: (Int,Int) -> Int
myFunctionF (x,y) = x + y

Modifica : Se il vostro dubbi su come foldr funziona, controlla Haskell riferimento Zvon Di seguito è riportato un esempio di implementazione foldl / carta.

foldl :: (a -> b -> b) -> b -> [a] -> b
foldl _ x [] = x
foldl fx (y:ys) = foldl f (f y x) ys

map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = (f x) : (map f xs)

Altri suggerimenti

Speriamo che questo vi aiuterà. La chiave è che f viene applicata agli elementi della lista, che sono coppie.

sumAll [(1,1),(2,2),(3,3)] 
      -- definition of sumAll
    = foldr (+) 0 (map f [(1,1),(2,2),(3,3)])
      -- application of map
    = foldr (+) 0 (f (1,1) : map f [(2,2),(3,3)])
      -- application of foldr
    = 0 + foldr (+) (f (1,1)) (map f [(2,2),(3,3)])
      -- application of map
    = 0 + foldr (+) (f (1,1)) (f (2,2) : map f [(3,3)])
      -- application of foldr
    = 0 + (f (1,1) + foldr (+) (f (2,2)) (map f [(3,3)]))
      -- application of f
    = 0 + (2 + foldr (+) (f (2,2)) (map f [(3,3)]))
      -- application of map
    = 0 + (2 + foldr (+) (f (2,2)) (f (3,3) : map f []))
      -- application of foldr
    = 0 + (2 + (f (2,2) + foldr (+) (f (3,3)) (map f [])))
      -- application of f
    = 0 + (2 + (4 + foldr (+) (f (3,3)) (map f [])))
      -- application of map
    = 0 + (2 + (4 + foldr (+) (f (3,3)) []))
      -- application of foldr
    = 0 + (2 + (4 + f (3,3)))
      -- application of f
    = 0 + (2 + (4 + 6))
    = 0 + (2 + 10)
    = 0 + 12
    = 12

Non è una risposta, ma ho pensato che avrei dovuto sottolineare che la funzione f:

f (x, y) = x + y

può essere espresso come

f = uncurry (+)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top