Откуда берутся эти значения в этой функции haskell?

StackOverflow https://stackoverflow.com/questions/376959

Вопрос

Допустим, у меня есть следующая функция:

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

В результате sumAll [(1,1),(2,2),(3,3)] будет 12.

Чего я не понимаю, так это где (x,y) ценности исходят от.Ну, я знаю, что они приходят из xs переменная, но я не понимаю, как.Я имею в виду, что при выполнении приведенного выше кода напрямую, без ключевого слова where, это было бы что-то вроде этого:

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

И я не могу понять, как в верхнем коде f переменный и (x,y) переменные представляют собой (\(x,y) -> x+y) лямбда-выражение.

Это было полезно?

Решение

В Haskell функции - это типы данных первого класса.

Это означает, что вы можете передавать функции, как и другие типы данных, такие как целые числа и строки.

В приведенном выше коде вы объявляете 'f' функцией, которая принимает один аргумент (кортеж из двух значений (x,y)) и возвращает результат (x + y).

foldr - это еще одна функция, которая принимает 3 аргумента, двоичную функцию (в данном случае +), начальное значение (0) и массив значений для повторения.

Короче говоря, 'где f (x, y) = x + y' - это просто сокращенное обозначение для

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

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

Редактировать:Если вы не уверены в том, как работает foldr, ознакомьтесь Ссылка на Хаскелл Zvon Ниже приведен пример реализации foldl / map.

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)

Другие советы

Надеюсь, это поможет.Ключ в том, что f применяется к элементам списка, которые являются парами.

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

Не ответ, но я подумал, что должен указать, что ваша функция f:

f (x, y) = x + y

может быть выражено как

f = uncurry (+)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top