Pergunta

Vamos dizer que eu tenho a seguinte função:

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

O resultado da sumAll [(1,1),(2,2),(3,3)] será 12.

O que eu não entendo é onde os valores (x,y) estão vindo. Bem, eu sei que eles vêm da variável xs mas eu não entendo como. Quer dizer, fazer o código acima diretamente, sem a palavra-chave onde, seria algo como isto:

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

E eu não consigo entender, no código de topo, como é que a variável f e variáveis ??(x,y) representam a expressão (\(x,y) -> x+y) lambda.

Foi útil?

Solução

Em Haskell, as funções são primeiros tipos de dados de classe.

Isto significa que você pode passar funções em torno de como outros tipos de dados, tais como números inteiros e strings.

Em seu código acima você declarar 'f' para ser uma função, que leva em um Argumenta (a tupla de dois valores (x, y)) e retorna o resultado de (x + y).

foldr é uma outra função, que leva em 3 argumentos, uma função binária (neste caso +) um valor de partida (0) e uma matriz de valores para iteração sobre.

Em suma 'onde f (x, y) = x + y' é apenas escopo abreviação para

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

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

Editar : Se você não tiver certeza sobre como foldr funciona, veja Haskell Zvon Referência Abaixo está um exemplo de implementação de foldl / mapa.

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)

Outras dicas

Esperemos que isto irá ajudar. A chave é que f é aplicado aos elementos da lista, que são pares.

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

Não é uma resposta, mas eu pensei que gostaria de salientar que a sua função f:

f (x, y) = x + y

pode ser expresso como

f = uncurry (+)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top