Откуда берутся эти значения в этой функции haskell?
Вопрос
Допустим, у меня есть следующая функция:
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 (+)