Что означает именно "функция внутри функтора"

В теории категорий функтор является гомоморфизмом между двумя категориями. В Haskell сказано, что аппликативный функтор позволяет нам применять функции "внутри функтора". Можно ли перевести эти слова "функционировать внутри функтора" обратно в математику или дать другое понимание? (Я знаю, что функтор может быть Maybe, [] и т.д., но все еще изо всех сил, чтобы понять это понятие.)

2 ответа

Решение

Моя теория категорий совсем не сильна (я начал с программирования на Haskell и недавно пытался изучить некоторые из основ теории категорий некоторых ее концепций). Но вот что у меня есть:

В Haskell функтор - это конструктор типов, то есть он отображает общие типы в "типы в функторе".

В теории категорий функтор отображает объекты одной категории на объекты другой категории.

Применяя теорию категорий к Haskell, мы представляем, что работаем с категорией Hask, категорией типов Haskell.

Так что функторы Хаскелла не являются функторами общей теории категорий; все они отображаются из Hask в подкатегорию Hask (потому что тип f a для какого-то функтора f и произвольный тип a все еще тип Хаскеля). Например, Maybe функтор отображает объекты (типы) в Hask на категорию типов формы Maybe a,

Функции являются первоклассными в Haskell, поэтому типы функций являются совершенно обычными типами (и являются объектами Hask), поэтому функторы также отображают типы функций на "типы функций в функторе". Таким образом, фраза "функция внутри функтора" является сокращением для значения в типе, которое является результатом применения функтора к типу функции. например Just (+1) одно конкретное значение в типе Maybe (Int -> Int), который является объектом (типом), к которому относится Maybe функтор отображает объект Int -> Int,

Таким образом, "аппликативный функтор" - это функтор, у которого есть некоторые дополнительные правила, которых достаточно, чтобы принимать значения, являющиеся функциями типов, которые являются объектами категории "назначение" функтора, и применять эти значения к другим значениям в типах в категории назначения.,

С помощью Maybe снова в качестве примера, если бы мы только знали, что это был функтор, который дает нам соответствие между объектами Int -> Char а также Maybe (Int -> Char)и между объектами Int а также Maybe Intи между объектами Char а также Maybe Char, Но пока у нас есть возможность принять значение в Int -> Char и значение в Int и произвести значение в Char, Maybe будучи функтором, мы не гарантируем, что у нас есть какая-либо возможность выполнить соответствующую операцию со значением в Maybe (Int -> Char) и значение в Maybe Int,

Когда мы также знаем, что это аппликативный функтор, тогда у нас есть возможность принять значение в Maybe (Int -> Char) и значение в Maybe Int и произвести значение в Maybe Charи это удовлетворяет определенным свойствам при применении Int -> Char значения для Int ценности.

Насколько я знаю, аппликативные функторы не очень интересны с точки зрения теории категорий. Возможно, это связано с тем, что теория категорий связана с отношениями между объектами, которые соответствуют типам в Haskell, но с точки зрения программирования аппликативные функторы мотивируются отношениями между значениями в этих типах? (мы хотим, чтобы значения в "типах функций", полученные с помощью функтора, все еще могли быть применены к вычислениям).

Перевод Вернуться к математике

В замкнутой моноидальной категории существует понятие "показатель степени", которое "усваивает" соотношение морфизма. Затем вы можете оценить эти показатели. То есть у вас есть способ сказать (извините за мое мнение, в Stackru отсутствует mathjax)

eval : (a ~> b,a) -> b

а также мета-операции для каррирования и неостановки.
"Аппликативный функтор" отображает показатели "применимым" образом, F (a ~> b) может сочетаться с F a чтобы получить F b, Это связано с тем, что аппликативные функторы являются моноидальными функторами, поэтому у них есть операция (в целевой категории)

f a -> f b -> f (a,b)

который, когда вы также Fmap Eval дает вам ap из Хаскелла.

Я сомневаюсь, что это было полезно,

Хаскелл

Лучший способ понять аппликативный функтор - это посмотреть на тип

class Functor f => Applicative f where
  pure :: a -> f a
  <*>  :: f (a -> b) -> f a -> f b

тривиальный пример

newtype Id a = Id a
instance Applicative Id where
  pure a = Id a
  Id f <*> Id a = Id (f $ a)

Id также Monad, На самом деле все Monadс Applicative,

pure = return
mf <*> mx = do f <- mf
               x <- mx
               return (f x)

более интересный пример, хотя это бесконечные последовательности

data Seq a = Seq a (Seq a)
instance Applicative Seq where
  pure a = Seq a (pure a)
  (Seq f fs) <*> (Seq x xs) = Seq (f x) (fs <$> xs)

Вы можете думать об этом как эквивалент zipWith $ в списках. Все Monadс Applicative, но я думаю, что бесконечная последовательность забавна, потому что соответствующий экземпляр монады... неочевиден (и довольно медленен). Это будет оставлено читателю в качестве упражнения (кстати, я привожу этот пример / упражнение из того, что я помню, прочитав, что, как мне кажется, свинарник написал на этом сайте).

Другие вопросы по тегам