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

Как насчет стрел?

Просматривая различные обучающие материалы о различных классах тематических классов Haskell, мы находим такие вещи, как Monoid, Functor, Monad и т.д. - все из которых имеют десятки экземпляров. Но по какой-то причине, когда мы достигаем Arrow, есть только два экземпляра: функции и монады. В обоих случаях использование экземпляра Arrow менее сильное и сложнее, чем просто непосредственное использование основной вещи.

Есть ли у кого-нибудь интересные примеры стрелок? Я уверен, что должно быть что-то, но я никогда не сталкивался с ними ни о чем писать...

4b9b3361

Ответ 1

HXT, библиотека, которая используется для синтаксического анализа XML, является очень хорошим примером использования стрелок (посмотрите, как часто слово Arrow происходит в именах модулей этого пакета!). Вы должны посмотреть на большой учебник: http://adit.io/posts/2012-04-14-working_with_HTML_in_haskell.html

Но также хорошо иметь концепцию стрелки для функций. Например, следующий код

((+1) &&& (*2)) 3 -- result is (4,6)

просто работает, потому что (->) является экземпляром класса стрелок (оператор &&& определяется в Control.Arrow).

Благодаря синтаксису arrow у вас также есть отличный инструмент для написания сложных вычислений в Haskell (он также работает для функций, монад и фильтров XML в HXT).

Ответ 2

Мне нравится думать о Arrow как оправляемых ациклических графах. Например, стрелка типа:

SomeArrow (a, b, c) (d, e, f)

... вы можете представить в виде графика, который имеет три входящих края типа a, b и c и три исходящих ребра типа d, e и f.

Используя эту интерпретацию, операции композиции категории для Arrow похожи на горизонтальную конкатенацию для графов, соединяющих их ребра вместе:

(.) :: SomeArrow b c -> SomeArrow a b -> Some Arrow a c

... где a, b и c могут быть самими кортежами. Аналогично, id - это только тождественный граф, который пересылает все входящие ребра к исходящим ребрам:

id :: SomeArrow a a

Другая операция ключа - (***), которая похожа на вертикальную конкатенацию графиков:

(***) :: Arrow a b -> Arrow c d -> Arrow (a, c) (b, d)

Вы можете думать об этом как о поведении двух графиков бок о бок, объединяя их входные ребра и выходные ребра.

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