2015-02-22 3 views
2

я недавно обучения Haskell, и я читал функторы в ЖЖ вам Haskell, из которого я узнал,Состав композиций в Haskell

  1. Функции ((->)r), которые принимают один параметр, также в некотором смысле функторов.
  2. Состав (.) эквивалентно fmap

Итак, что я понял, БПМЖ принимает два параметра. Во-первых, это функция, которую нужно применить, а вторая - функтор.

Однако я смущен этим выражением (.) (.) (.). Это композиция из двух композиций, с типом (b -> c) -> (a1 -> a2 -> b) -> (a1 -> a2 -> c)

Итак, вот мое сомнение возникает. Первый (.) имеет два параметра, первый из которых является самой композиционной функцией. Второй параметр также является композиционной функцией. А композиционная функция как таковая не является функтором. Итак, как это допустимое выражение?

Уверен, что здесь что-то не хватает. Может ли кто-то заполнить пробелы и помочь мне понять, как это выражение правильно?

+3

Здесь есть некоторая путаница. Функция - значение, а функтор - объект уровня, который отображает типы в типы. Приложение '(.) (.) (.)' Можно понять, не задумываясь о функторах. – chi

ответ

7

Игнорировать пример Functor для ((->) r); это не имеет значения. Только два тинги дела здесь: Тип (.), а именно

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

, а также тот факт, что применение функции является левоассоциативно. Последнее означает, что (.) (.) (.) совпадает с ((.) (.)) (.).

Давайте сначала попробуем найти тип (.) (.) (самые левые, если хотите). Напишем тип первого (.) как (b1 -> c1) -> (a1 -> b1) -> a1 -> c1, а второй - (b2 -> c2) -> (a2 -> b2) -> a2 -> c2. Мы применяем первое ко второму, что дает нам, что b1 - (b2 -> c2) и c1 - (a2 -> b2) -> a2 -> c2. Таким образом, мы имеем

(.) (.) :: (a1 -> (b2 -> c2)) -> a1 -> ((a2 -> b2) -> a2 -> c2) 

, который может быть упрощено до

(.) (.) :: (a1 -> b2 -> c2) -> a1 -> (a2 -> b2) -> a2 -> c2 

Давайте теперь применим это к к последнему (.) (в крайнем правом один, если вы будете). Если у него есть подпись (b3 -> c3) -> (a3 -> b3) -> a3 -> c3, тогда мы видим, что a1 должно быть (b3 -> c3), b2 должно быть (a3 -> b3) и c2 должно быть a3 -> c3. Таким образом,

((.) (.)) (.) :: (b3 -> c3) -> (a2 -> (a3 -> b3)) -> a2 -> a3 -> c3 

, который так же, как

((.) (.)) (.) :: (b3 -> c3) -> (a2 -> a3 -> b3) -> (a2 -> a3 -> c3) 

Это то же самое, что у вас есть в вашем вопросе, если вы делаете некоторые переименования.

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