Как называется этот монадоподобный шаблон функционального программирования? - PullRequest
20 голосов
/ 21 августа 2011

Я иногда сталкивался с паттерном в коде, который напоминает монаду, но не сохраняет согласованный тип для >>=.

Вот самый простой пример, который я могу придумать:

(Сначала некоторые логические значения уровня типа:

data TyT = TyT
data TyF = TyF

class TyOr a b c | a b -> c

instance TyOr TyF TyF TyF
-- rest similarly

)

Теперь вот наш конструктор типа "монада":

data Marked p a = Marked a
    deriving (Show)

Для данного p, Marked p - это * -> *, который действует очень похоже на m в монада, но другая, как это происходит далее, когда мы определяем «связать»:

(>>%) :: (TyOr p q r) => Marked p a -> (a -> Marked q b) -> Marked r b
(Marked x) >>% f = Marked y where Marked y = f x

Что здесь отличается тем, что результат >>% имеет другой тип конструктор, чем аргументы. Кроме этого это в основном монада.

Мы могли бы использовать это так:

a :: Marked TyF Int
a = Marked 5

f :: Int -> Marked TyT Int
f x = Marked (x + 1)

ghci> a >>% f
Marked 6

ghci> :t a >>% f
a >>% f :: Marked TyT Int

(Это было вдохновлено наблюдением outis о том, что Python "с" не может быть монада, потому что она меняет тип , но я видел это другими (более простыми) способами тоже).

1 Ответ

10 голосов
/ 21 августа 2011

Ну, в некотором смысле это тесно связано с монадами, просто несовместимо с классом типа Monad.В частности, мы можем отметить следующие параллели:

  • Моноиды имеют ассоциативную операцию с тождеством, определенным для значений согласованного типа: mappend :: a -> a -> a и mempty :: a.

  • Монады имеют ассоциативную операцию с тождеством, определенным для конструкторов типа , например: join :: m (m a) -> m a и return :: a -> m a.

  • Функции--действительно, стрелки в категории - имеют ассоциативную операцию и идентичность, но ассоциативная операция индексируется объектами категории , что здесь означает «типы»: (.) :: arr b c -> arr a b -> arr a c и id :: arr a a.

... так какой была бы монада, чьи join проиндексированы типами?Хм.

Несколько ссылок, которые вы можете найти интересными, исследуя связанные понятия:


post scriptum -Вы сказали это в комментарии к вопросу:

Вы правы.Я действительно хочу исправить это, чтобы быть более похожим на монаду, хотя я на самом деле не "использую" монады.Я отредактирую это.Хотя у меня был бы более или менее тот же вопрос о Аппликативах.

На самом деле, ограничение вещей до Applicative существенно меняет дело!Разница между a -> Marked p b и Marked p (a -> b) заключается в том, что в первом случае свойства структуры Marked p могут зависеть от параметра a;тогда как в последнем случае маркировка не зависит от аргументов функции.Независимость означает, что оба могут рассматриваться отдельно, что значительно упрощает дела;отмечая, что любое значение типа a изоморфно функции типа () -> a, вы, вероятно, можете напрямую превратить его в своего рода двухуровневую версию Arrow.

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

...