Требуется помощь функции высшего порядка Haskell - PullRequest
1 голос
/ 05 февраля 2012

В чем проблема с этим кодом?

addNum :: Int->Int-> Int
addNum a b = a+b

divideby :: ( Int->Int -> Int ) -> Int  ->float
divideby  f  z  =  f /z

Я хочу взять функцию addNum в качестве входа для divideby с делителем и затем вывести ответ.Таким образом, функция divideby должна действовать как функция более высокого порядка.

В чем проблема с этим кодом?Выдает следующую ошибку:

*** Expression     : f / z
*** Term           : f
*** Type           : Int -> Int -> Int
*** Does not match : Int

Ответы [ 3 ]

6 голосов
/ 05 февраля 2012

Это означает именно то, что говорит ошибка.Вы указали, что тип вашей функции

divideby :: ( Int->Int -> Int ) -> Int  ->float

Это означает, что первый аргумент должен быть функцией с типом Int->Int -> Int, а второй вход должен быть Int, а затемэто произведет float.Естественно, Haskell не знает, как разделить функцию на Int, что вы и говорите ей делать с выражением f / z.


В ответ на комментарий: нет.Это не функция высшего порядка, но она близка.Посмотрите:

addNum :: Int -> Int -> Int
addNum a b = a + b

divideBy :: Int -> Int -> Int -> Int
divideBy a b c = (addNum a b) `div` c

divideBy - это функция, которая принимает 3 Int с в качестве ввода и выдает Int.Поскольку его входные данные просто Int, это , а не функция высшего порядка.Однако вы можете абстрагироваться от использования addNum на входе, тем самым сделав его функцией более высокого порядка.addNum имеет тип (Int -> Int -> Int), поэтому, в дополнение к уже имеющимся входам, мы сделаем так, чтобы тип нашего первого входа

divideBy :: (Int -> Int -> Int) -> Int -> Int -> Int -> Int
divideBy f a b c = (f a b) `div` c

Этот был вышефункция порядка, которая также правильно компилируется и имеет значение.:) Вы можете передать addNum в качестве входа для этой функции.

ghci> divideBy addNum 2 4 6 -- (2 + 4) / 6
1
1 голос
/ 05 февраля 2012

Я хочу взять функцию addNum в качестве функции Входа для деления с коэффициентом деления, а затем вывести ответ.

Прежде всего, функция divideby - это функция, которая принимает 2 числа f и z и возвращает f/z. Как сказал Дэн Бертон, если функция divideby возвращает деление двух значений Int, она не может получить функцию Int -> Int -> Int в качестве аргумента.

Так это может выглядеть так:

divideby :: Int -> Int -> Float
divideby  f z  =  (fromIntegral f) / (fromIntegral z)

Если вы хотите построить некоторую функцию как суперпозицию divideby и addNum, например, принимая результат addNum в качестве первого аргумента divideby, вы можете сделать это следующим образом:

newFunction :: Int -> Int -> Float
newFunction a b = divideby (addNum a b) b

Что на самом деле равно (a+b)/b.

1 голос
/ 05 февраля 2012

Существует разница между float и Float ... первая - переменная типа, вторая - конкретный тип (для которого вы почти наверняка хотите Double).

Это связано с ответом Дэна Бертона.

...