Подтвердить что ты не робот

Как функторы в Haskell и OCaml похожи?

Я играл в Haskell в течение прошлого года или около того, и я действительно начинаю его "добираться" до Monads, Lenses, Type Families,... много.

Я собираюсь немного покинуть эту зону комфорта, и я перехожу к проекту OCaml в качестве дневной работы. Просматривая синтаксис, я искал аналогичные концепции более высокого уровня, например, например, функтор.

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

Может кто-нибудь объяснить мне, схожи ли эти две концепции, и если да, то чего я не вижу или не вижу? Я немного искал язык, и, похоже, нет четкого ответа.

Kasper

4b9b3361

Ответ 1

С практической точки зрения вы можете думать о "функторах" в OCaml и Haskell как о несвязанных. Как вы сказали, в Haskell функтор - это любой тип, который позволяет вам отображать функцию над ним. В OCaml функтор является модулем, параметризованным другим модулем.

В функциональном программировании, что является функтором? имеет хорошее описание того, какие функторы на двух языках и как они отличаются.

Однако, как следует из названия, на самом деле существует связь между двумя, казалось бы, разрозненными концепциями! Оба языковых функтора - это просто реализация понятия из теории категорий.

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

Наиболее очевидным примером категории является категория множеств и функций: множества - это объекты и функции между множествами морфизмов. Ясно, что каждое множество имеет тождественную функцию и функции могут быть составлены. Очень похожую категорию можно сформировать, посмотрев на язык функционального программирования, такой как Haskell или OCaml: конкретные типы (например, типы с видом *) - это объекты, а функции Haskell/OCaml - это морфизмы между ними.

В теории категорий функтор является преобразованием между категориями. Это похоже на функцию между категориями. Когда мы смотрим на категорию типов Haskell, функтор, по сути, является функцией уровня типа: он сопоставляет типы с чем-то другим. Особый тип функтора мы заботимся о типах карт для других типов. Прекрасным примером этого является Maybe: Maybe отображает Int в Maybe Int, String в Maybe String и так далее. Он обеспечивает отображение для каждого возможного типа Haskell.

У функторов есть еще одно требование - они должны отображать морфизмы категорий, а также объекты. В частности, если мы имеем морфизм A → B, а наш функтор отображает A в A' и B в B', он должен отобразить морфизм A → B на некоторый морфизм A' → B'. В качестве конкретного примера предположим, что мы имеем типы Int и String. Существует целая группа функций Haskell Int → String. Для того чтобы Maybe был собственным функтором, для каждой из них должна быть функция Maybe Int → Maybe String.

К счастью, это именно то, что делает функция fmap - она ​​отображает функции. Для Maybe он имеет тип (a → b) → Maybe a → Maybe b; мы можем добавить некоторые круглые скобки, чтобы получить: (a → b) → (Maybe a → Maybe b). То, что говорит эта сигнатура типа, состоит в том, что для любой нормальной функции мы имеем также соответствующую функцию над Maybe s.

Таким образом, функтор является отображением между типами, которое также сохраняет функции между ними. Функция fmap по существу является лишь доказательством этого второго ограничения на функторы. Это позволяет легко понять, как класс Haskell Functor является только определенной версией математического понятия.

А как насчет OCaml? В OCaml функтор не является типом, а модулем. В частности, это параметризованный модуль: модуль, который принимает в качестве аргумента другой модуль. Уже мы можем видеть некоторые параллели: в Haskell a Functor похож на функцию уровня уровня; в OCaml функтор подобен функции уровня модуля. Так что, это та же математическая идея; однако вместо использования в типах, подобных Haskell, используется для модулей.

Более подробно о функциях OCaml, связанных с функционалами теории категорий на сайте CS: Какова связь между функторами в SML и теорией категорий?. Вопрос касается SML, а не OCaml как таковой, но я понимаю, что модульная система OCaml очень тесно связана с системой SML.

В заключение: функторы в Haskell и OCaml представляют собой две принципиально разные структуры, которые оба являются подтверждением одной и той же очень абстрактной математической идеи. Я думаю, это довольно аккуратно:).