Как получить тип (.). (.)

Haskell beginner здесь имеет проблему, порождающую тип (.). (.) -

Prelude> :t ((.).(.))
((.).(.)) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c

Вот как я думаю: предположим (.). (.) принимает два аргумента A и B, то

(.).(.) A B = (.).(A.B)

и предположим, что приведенное выше принимает другой аргумент C -

(.).(A.B) C = (.)((A.B) C)

добавление аргумента D к вышесказанному -

(.)((A.B) C) D = ((A.B) C).D

где D, A, B, A.B и ((A.B) C) являются (возвратными) функциями и -

D :: a -> b
(A.B) C :: b -> c
A.B :: d -> b -> c
A :: e -> b -> c
B :: d -> e
C :: d

so (.). (.):: A → B → C → D становится -

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

что на несколько световых лет от правильной сигнатуры типа.

Какой правильный вывод и что не так на моих шагах?

Ответы

Ответ 1

Кажется, моя ошибка исходит от применения трех точек в неправильном порядке.

J. Abrahamson answer отлично, но я не точно следую его шагу -

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

из-за того, что его "смешивает" первый и второй аргументы от второго и третьего типов точек.

Я думаю, что у меня есть ответ после моего первоначального трека мыслей -

(.).(.) A = (.)((.) A)) ==> add arg B ==> (.)((.) A)) B = ((.) A).B ==>
add arg C ==> ((.) A).B C = ((.) A)(B C) ==> add arg D ==> ((.) A)(B C) D

где A, ((.) A), (B C) - функции -

let A :: b -> c
then ((.) A) :: (a -> b) -> a -> c
so B C :: a -> b
B :: a1 -> a -> b
C :: a1
D :: a

и (.). (.) A B C D расширяется до -

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