Два известных примера applicatives - монады и ziplists. Есть ли какие-либо другие примеры?
Из Время мух, таких как аппликативный функтор Conor Mcbride Conor McBride:
Структурные полицейские отметит, что
de
является еще одним примером заявительного функтора, который не является монадом, Принесите вещи из дальнего будущего в ближайшее время, и это лучше не было возможно. Однако, где заявительные функторы вообще только потянули проездные функторы (контейнеры с конечным элементами),DE
тянет через все контейнеры. Так что это немного особенное. Интересно, что это такое.
И
Функтор
de
представляет собой фиксированную задержку, а не произвольную. Я разделяю время на дискретные ломтики.de x
- это типx
, из-за следующего среза.de (de x)
, таким образом, типx
, в течение двух ломтиков, и вы не можете сделать его раньше!
Прочитайте весь пост. Чтобы ответить на непосредственный вопрос, вывод автора
не выглядит!
Хорошо, вот реализация. Это кон.
newtype de x = de x derviving show - ssh, не говори! экземпляр функтором де fmap f (de x) = de (f x) Экземпляр Applative de, где чистый = де De f <*> de s = de (f s) Fix :: (de x -> x) -> x исправить f = f (de (fix f))
Я считаю, что стрелки являются аппликативными функторами. Существует, безусловно, запечатлевый тип управления.
Недавно я определил прикладной экземпляр для нового типа поверх (,,,)
, "квадрат". (Стандартная библиотека определяет экземпляр для (,)
, но не для (,,,)
. Ничего страшного, так как стандартная реализация имеет иную семантику, чем то, что я искал.)
Фоном является то, что я разбираю некоторые старые данные, и формат даты в данных неоднозначен. Каждую дату в данных можно разобрать на четыре возможности, хранящиеся в квадранте. Затем я хочу проверить каждую дату в квадранте, чтобы исключить семантически недействительные даты. (Нет месяцев с 32 днями, нет месяца 34, нет 5-го квартала и т.д.) Наконец, я хочу взять каждую дату в наборе данных, и сократить весь набор до четырехугольника, представляя, какие форматы даты действительны для всего набора. Затем я выбираю лучший формат из этих вариантов, и предполагаю, что это и есть формат даты в наборе данных.
Эту операцию очень легко выразить в виде прикладных операций над четырехмерной структурой.
Вот основная форма кода:
Мой новый тип:
newtype DQ a = DQ (a, a, a, a) -- date quad
deriving ...
instance Functor DQ where
g `fmap` f = pure g <*> f
instance Applicative DQ where
pure x = DQ (x, x, x, x)
DQ (g, h, i, j) <*> DQ (a, b, c, d) = DQ (g a, h b, i c, j d)
Некоторые предварительные "чистые" функции:
parseDateInt :: Int -> DQ Date
validateDate :: Date -> Bool
extractBestDate :: DQ Date -> DQ Bool -> Date
Итак, как только мы получим квадрат разобранных дат (из parseDateInt
), нам нужно их валидировать:
validateDates :: DQ Date -> DQ Bool
validateDates = (validateDate <$>)
(Пока это всего лишь фанктор, но вы также можете написать
(чисто validateDate <*>)
.
Стоит также отметить симметрию между валидацией единичной
элемент, и подтверждая каждый элемент набора -- чтобы подтвердить один, вы можете написать
validateDate $ date
; чтобы подтвердить набор, пишите.
validateDate <$> date
. Поэтому fmap
записывается как <$>
, это функция, применяемая к functor.)
Шаг после этого состоит в том, чтобы взять набор действительных парсов и сложить его так, чтобы в конечный результат:
intuitDateType :: [DQ Bool] -> DQ Bool
intuitDateType dates = foldl1 (liftA2 (&&)) dates
Так что теперь можно перейти от [Int]
в файле данных к DQ Bool
.
представляющие собой возможно достоверные представления даты для набора данных.
(А оттуда ассоциировать каждую точку данных с объектом реальной даты,
вместо хлопьевидного Int, который был поставлен.)
Так или иначе, этот пост стал немного длинноватым, но идея в том, чтобы
Аппликативный пример позволил мне решить мою проблему примерно в 3 строчках
кода. Моя проблемная область заключалась в многократном применении функций к данным в
контейнер, что и делает аппликативный фанктор. На этих данных нет операции join
, поэтому экземпляр Monad не имеет особого смысла.
Conal Elliott пишет о коммуникационных процессорах и как они применяются . Те, кто похожи на Ziplist
в природе, где каждая соответствующая пара предметов в двух «контейнерах» объединяется.
Я много использовал эту концепцию в незаконченной, но милой игре, которую я сделал ( Cabal Install Defendtheking
, чтобы проверить это).
Фрагмент кода / примера использования в стиле применимого:
draw font
<$> lstP gABoard
<*> lstP gASelection
<*> mouseMotion
<*> lstP gASide
<*> lstP gAGameIteration