2015-04-26 2 views
4

Если у нас есть две функции: f и g, то в Haskell h = f . g эквивалентно h x = f(g x). То есть функции применяются справа налево на вход. Есть ли какая-то фундаментальная причина, почему это происходит справа налево, а не слева направо? То есть почему они не сделали h = f . g эквивалентом h x = g(f x) вместо этого?Почему точка написана справа налево в Haskell?

РЕДАКТИРОВАТЬ: как другие указали на мои эквивалентные функции, где неправильный путь, поэтому я исправил их.

+3

Я думаю, что вы немного смущены, '.' является правильным ассоциативным, но' h = f. g' действительно эквивалентно 'h x = f (g x)': 'h = (* 3). (+2) '. 'h 2' дает' 12', как вы ожидали бы, если '(+2)' будет оцениваться до – berdario

+0

Кроме того, ассоциативное свойство имеет смысл, если у вас более 1 операции (и, следовательно, более 2 операндов): https : //en.wikipedia.org/wiki/Associative_property – berdario

+2

Почему 'hx = f (gx)', а не 'hx = g (fx)' не является вопросом ассоциативности композиции, а скорее как операнды к ' . обрабатываются. Вопрос об ассоциативности был бы следующим: 'f. г . h' анализируется как f. (g. h) ', а не' (f. g). h', но на самом деле композиция полностью ассоциативна и обе скобки правильны. Композиция такая же, как и добавление в этом смысле. – chepner

ответ

14

Прежде всего, это ошибка в вашем [оригинале, неотредактированный] вопрос:

ч = е. г эквивалентна ч х = г (е) х

- это не так: h = f . g эквивалентно h x = f (g x).

Однако, почему это так, а не наоборот, это, скорее всего, потому, что так оно работает и работает в математике; см http://en.wikipedia.org/wiki/Function_composition:

[...] композит функция обозначается г ∘ F: X → Z, определяется (г ∘ е) (х) = G (F (х)) для всех x в X.

Это также интуитивное из равенства (f . g) x == f (g x) - как вы можете видеть, порядок f и g является одинаковым с обеих сторон.


Кроме того, тривиально создать свой собственный оператор «обратной композиции», если вы желаете его по причинам, например. читаемость:

(.>) = flip (.) 

так что

Prelude> ((+1) .> (*2)) 3 
8 
Prelude> ((+1) . (*2)) 3 
7 

В самом деле, вы можете просто использовать Control.Arrow.(>>>), который делает то же самое для функций, но является более общим и работает для других вещей:

Prelude Control.Arrow> ((+1) >>> (*2)) 3 
8 
+7

Традиционный; интуитивно это не так. Он делает порядок текста противоположным порядку диаграммы, что крайне раздражает. – dfeuer

+0

какая схема? и не могли бы вы тогда сказать, что 'f x' неинтуитивно для начала? по сравнению с 'x.f()', то есть. –

+3

«диаграмма» в стихе теории категорий. То есть: если у вас есть функция 'f: a-> b' и другая' g: b-> c', неестественно писать 'g.f' составляющие стрелки/функции/морфизмы в обратном порядке. – chi

Смежные вопросы