Haskell currying для удаления переменной аргумента в конце

Я новичок, пытающийся изучить haskell, я пытался найти что-то подобное на других форумах, но не мог найти аналогичный вопрос.

addPoly :: (Num a)=>[[a]]->[a]
addPoly x = map sum $ transpose x

работает отлично

но когда я удаляю x в конце, он выдает ошибки

addPoly :: (Num a)=>[[a]]->[a]
addPoly = map sum $ transpose

ошибки:

Couldn't match expected type `[[Integer]] -> [Integer]'
 with actual type `[Integer]'
In the expression: map sum $ transpose
In an equation for `addPoly': addPoly = map sum $ transpose
Couldn't match expected type `[[Integer]]'
 with actual type `[[a0]] -> [[a0]]'
In the second argument of `($)', namely `transpose'
In the expression: map sum $ transpose
In an equation for `addPoly': addPoly = map sum $ transpose

Не могу понять, чего я здесь не вижу.

Отказ от ответственности: это не проблема домашней работы

2 ответа

$ определяется в Haskell как

f $ x = f x
infixr 0 $

Итак, если вы развернете первый фрагмент кода,

map sum $ transpose x

становится

map sum (transpose x)

который будет работать.

Но второй фрагмент

map sum $ transpose

становится

map sum transpose

и когда вы вызываете это с помощью x, вы получаете

map sum transpose x

которые на самом деле отображают sum по transpose (и вызывают результат с аргументом x, что также не имеет смысла, и вызывает сообщение об ошибке, которое вы получаете, поскольку map вернет List, а не функция), а не над transpose x.

Для этого вам нужно использовать функцию . вместо $, которая определяется как

(.) f g = \x -> f (g x)

Если вы это сделаете, ваш код

map sum . transpose

становится

\x -> map sum (transpose x)

и когда вы вызываете это по некоторому параметру x, он просто становится

map sum (transpose x)

который является (правильным) кодом, с которого мы начали.

Сообщите мне, если что-то неясно.


Правильный код:

addPoly :: (Num a)=>[[a]]->[a]
addPoly = map sum . transpose

Как добраться до него? Помните следующие два правила:

f $ x = f x
f. g $ x == (f.g) x == f (g x) == f $ g x

Таким образом,

addPoly x = map sum $ transpose x

переписывается как

addPoly x = map sum $ transpose $ x

а затем каждый $, но последние заменяются на ..

addPoly x = map sum . transpose $ x

Теперь, поскольку у вас есть только один $, и аргумент находится только справа от $, вы можете переключиться на стиль без ссылок

licensed under cc by-sa 3.0 with attribution.