Haskell - узнайте подпись типа

Я новичок в Haskell и функциональном программировании, и я не могу понять, почему подпись типа

t2 = (\x y z a -> ((x.y) z, (y.x) z))

выглядит так:

t2 :: (a -> a) -> (a -> a) -> a -> b -> (a,a)

Подскажите, пожалуйста, как это работает?

С уважением


person pichlbaer    schedule 02.03.2014    source источник
comment
Это действительно должно быть много отдельных вопросов о каждой части синтаксиса и вывода типов, которые вас сбивают с толку. Лямбда-нотация (\a -> b) отличается от приложения функции (f x) и композиции функции (x . y, которая на самом деле является просто типом приложения функции) вместе с чтением функции, уменьшенной по эталону (plus = (+) vs plus a b = a + b).   -  person Thomas M. DuBuisson    schedule 03.03.2014


Ответы (2)


(.) - функция композиции, ее тип -

(.) :: (b -> c) -> (a -> b) -> (a -> c)

Итак, мы знаем, что, поскольку вы составляете x и y, они должны быть функциями и иметь такие типы:

x :: a -> b
y :: a' -> b'

Обратите внимание, что когда вы составляете две функции, тип вывода функции справа должен совпадать с типом ввода функции слева. Следовательно, когда вы делаете x . y, мы можем сделать вывод, что b' и a относятся к одному типу. Точно так же мы можем сделать вывод, что a' и b относятся к одному типу. Это дает нам следующее:

(y . x) :: a -> a
(x . y) :: b -> b

Однако затем вы применили обе эти функции к z, что означает, что a и b должны быть одного и того же типа, а именно типа z, поэтому мы можем сделать вывод, что

(y . x) :: a -> a
(x . y) :: a -> a
z :: a

Наконец, переменная a - это просто фиктивная переменная, которая фактически не используется в определении функции, поэтому она получает переменную другого типа.

person Emil    schedule 02.03.2014

Из лямбда-выражения мы видим, что t2 принимает 4 аргумента x, y, z и a. А затем возвращает кортеж. . в - для композиции. Таким образом, мы можем видеть, что x и y являются функциями, а не просто значениями. Затем мы видим, что у нас есть и x . y, и y . x. Это означает, что тип возвращаемого значения x должен быть типом аргумента y и наоборот. Итак, мы знаем, что x и y должны иметь один и тот же тип, поэтому a -> a - это тип для них обоих. Таким образом, x . y :: a -> a и y . x :: a -> a, поэтому мы знаем, что z должны иметь тип a. Наконец, a, переменная никогда не используется, поэтому она может быть любого типа, потому что мы не можем узнать больше о ней.

person DiegoNolan    schedule 02.03.2014