Составление функций в Haskell с функциями арифметического типа

Сейчас я изучаю Haskell и пытаюсь поиграть с композицией функций.

Я написал две функции.

let func1 x y = x + y

let func2 t = t*2

Однако, когда я пытаюсь скомбинировать эти две функции, func2 . func1 1 2 я ожидаю получить 6.

Вместо этого я получаю эту ошибку:

   No instance for (Num (a -> b))
      arising from a use of `func1' at <interactive>:1:8-16
    Possible fix: add an instance declaration for (Num (a -> b))
    In the second argument of `(.)', namely `func1 1 2'
    In the expression: func2 . func1 1 2
    In the definition of `it': it = func2 . func1 1 2

Может кто-нибудь объяснить, почему это не работает?


person CodyBugstein    schedule 13.02.2013    source источник
comment
(func2 .) . func1 или func2 . func1 1. Чтобы составить с функцией, принимающей более одного аргумента, вам нужно больше (.).   -  person Daniel Fischer    schedule 13.02.2013


Ответы (3)


Приложение функции имеет приоритет перед любыми операторами, поэтому ваша композиция анализируется как func2 . (func1 1 2). То есть ваш код пытается составить число, которое является результатом func1 1 2, как если бы это была функция. Обратите внимание, что (func2 . func1) 1 2 тоже не работает, поскольку (.) работает только с унарными функциями.

Вы можете использовать (func2 . func1 1) 2 или использовать (.) несколько раз, что мне лично не очень удобно, если честно. Но, вероятно, в данном конкретном случае лучше вообще не использовать композицию: func2 $ func1 1 2 делает то же самое с меньшим количеством беспорядка.

person Community    schedule 13.02.2013

Из-за удачной ошибки (закон о распределении) вы можете сделать это с помощью Data.Function.on

import Data.Function

func1 x y = x + y
func2 t = t*2

func3 = func1 `on` func2

-- or just func3 = (+) `on` (2*)

В общем, вы должны просто использовать $ для такого рода вещей, поскольку это то, что вы делаете, приложение-функция. Это не совсем работа для композиции, поэтому вы пытаетесь вставить квадратный стержень в круглое отверстие, если используете композицию.

person Wes    schedule 13.02.2013

То, что вы пытаетесь сделать, - это не композиция функций: вы пытаетесь применить func1 1 2 к func2, для чего предназначен оператор $.

func2 $ func1 1 2
person phant0m    schedule 13.02.2013