Я иногда сталкивался с паттерном в коде, который напоминает монаду, но
не сохраняет согласованный тип для >>=
.
Вот самый простой пример, который я могу придумать:
(Сначала некоторые логические значения уровня типа:
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 "с" не может быть
монада, потому что она меняет тип , но я видел это другими (более простыми) способами
тоже).