Control.Monad
| Авторские права | (c) Университет Глазго 2001 |
|---|---|
| Лицензия | BSD-стиль (см. файл libraries/base/LICENSE) |
| Поддерживающий | libraries@haskell.org |
| Стабильность | предварительная |
| Переносимость | переносимая |
| Безопасный Haskell | Безопасный |
| Язык | Haskell2010 |
Классы Functor и monad
class Functor (f :: Type -> Type) where Источник
Тип f является Functor, если он предоставляет функцию fmap, которая, учитывая любые типы a и b, позволяет вам применять любую функцию из (a -> b) для преобразования f a в f b, сохраняя структуру f. Кроме того, f должен соответствовать следующим правилам:
Обратите внимание, что второе правило вытекает из свободной теоремы типа fmap и первого правила, поэтому вам нужно только проверить, что выполняется первое условие. См. статьи School of Haskell или Дэвида Лупошайинского для объяснения.
Минимальное полное определение
Методы
fmap :: (a -> b) -> f a -> f b Источник
fmap используется для применения функции типа (a -> b) к значению типа f a, где f — функтор, для получения значения типа f b. Обратите внимание, что для любого конструктора типа с более чем одним параметром (например, Either) только последний параметр типа может быть изменён с помощью fmap (например, b в `Either a b`).
Некоторые конструкторы типов с двумя и более параметрами имеют экземпляр Bifunctor, который позволяет отображать как последний, так и предпоследний параметры.
Примеры
Преобразование из Maybe Int в Maybe String с помощью show:
>>> fmap show Nothing Nothing >>> fmap show (Just 3) Just "3"
Преобразование из Either Int Int в Either Int String с помощью show:
>>> fmap show (Left 17) Left 17 >>> fmap show (Right 17) Right "17"
Удвоение каждого элемента списка:
>>> fmap (*2) [1,2,3] [2,4,6]
Применение even ко второму элементу пары:
>>> fmap even (2,2) (2,True)
Возможно, удивительно, что функция применяется только к последнему элементу кортежа по сравнению с примером со списком, где она применяется ко всем элементам списка. Чтобы понять это, вспомните, что кортежи — это конструкторы типов с несколькими параметрами типа: кортеж из 3 элементов (a,b,c) также может быть записан как (,,) a b c, и его экземпляр Functor определён для Functor ((,,) a b) (т.е. только третий параметр можно отображать с помощью fmap).
Это объясняет, почему fmap можно использовать с кортежами, содержащими значения разных типов, как в следующем примере:
>>> fmap even ("hello", 1.0, 4)
("hello",1.0,True)
(<$) :: a -> f b -> f a infixl 4 Источник
Замена всех позиций ввода одним и тем же значением. По умолчанию это fmap . const, но это может быть переопределено более эффективной версией.
Примеры
Экземпляры
| Functor Complex Source | Since: base-4.9.0.0 |
| Functor First Source | Since: base-4.9.0.0 |
| Functor Last Source | Since: base-4.9.0.0 |
| Functor Max Source | Since: base-4.9.0.0 |
| Functor Min Source | Since: base-4.9.0.0 |
| Functor ArgDescr Source | Since: base-4.7.0.0 |
| Functor ArgOrder Source | Since: base-4.7.0.0 |
| Functor OptDescr Source | Since: base-4.7.0.0 |
| Functor NonEmpty Source | Since: base-4.9.0.0 |
| Functor P Source | Since: base-4.8.0.0 |
Defined in GHC.Internal.Text.ParserCombinators.ReadP | |
| Functor ReadP Source | Since: base-2.1 |
| Functor ReadPrec Source | Since: base-2.1 |
| Functor IO Source | Since: base-2.1 |
| Functor Maybe Source | Since: base-2.1 |
| Functor Solo Source | Since: base-4.15 |
| Functor [] Source | Since: base-2.1 |
Defined in GHC.Internal.Base | |
| Monad m => Functor (WrappedMonad m) Source | Since: base-2.1 |
Defined in Control.Applicative Methodsfmap :: (a -> b) -> WrappedMonad m a -> WrappedMonad m b Source (<$) :: a -> WrappedMonad m b -> WrappedMonad m a Source | |
| Functor (Arg a) Source | Since: base-4.9.0.0 |
| Functor (Array i) Source | Since: base-2.1 |
| Functor (ArrowMonad a) Source | Since: base-4.6.0.0 |
Определено в GHC.Internal.Control.Arrow Методыfmap :: (a0 -> b) -> ArrowMonad a a0 -> ArrowMonad a b Source (<$) :: a0 -> ArrowMonad a b -> ArrowMonad a a0 Source | |
| Functor (ST s) Source | Since: base-2.1 |
| Functor (Either a) Source | Since: base-3.0 |
| Functor (StateL s) Source | Since: base-4.0 |
| Functor (StateR s) Source | Since: base-4.0 |
| Functor (Proxy :: Type -> Type) Источник | С версии: base-4.7.0.0 |
| Functor (U1 :: Type -> Type) Источник | С версии: base-4.9.0.0 |
| Functor (V1 :: Type -> Type) Источник | С версии: base-4.9.0.0 |
| Functor (ST s) Источник | С версии: base-2.1 |
| Functor ((,) a) Источник | С версии: base-2.1 |
Определено в GHC.Internal.Base | |
| Arrow a => Functor (WrappedArrow a b) Источник | С версии: base-2.1 |
Определено в Control.Applicative Краткое описание методовfmap :: (a0 -> b0) -> WrappedArrow a b a0 -> WrappedArrow a b b0 Источник (<$) :: a0 -> WrappedArrow a b b0 -> WrappedArrow a b a0 Источник | |
| Functor m => Functor (Kleisli m a) Источник | С версии: base-4.14.0.0 |
| Functor (URec (Ptr ()) :: Type -> Type) Source | Since: base-4.9.0.0 |
| Functor (URec Char :: Type -> Type) Source | Since: base-4.9.0.0 |
| Functor (URec Double :: Type -> Type) Source | Since: base-4.9.0.0 |
| Functor (URec Float :: Type -> Type) Source | Since: base-4.9.0.0 |
| Functor (URec Int :: Type -> Type) Source | Since: base-4.9.0.0 |
| Functor (URec Word :: Type -> Type) Source | Since: base-4.9.0.0 |
| Functor ((,,) a b) Source | Since: base-4.14.0.0 |
Определено в GHC.Internal.Base Методыfmap :: (a0 -> b0) -> (a, b, a0) -> (a, b, b0) Исходный код (<$) :: a0 -> (a, b, b0) -> (a, b, a0) Исходный код | |
| (Functor f, Functor g) => Functor (Product f g) Исходный код | С версии: base-4.9.0.0 |
Определено в Data.Functor.Product Методыfmap :: (a -> b) -> Product f g a -> Product f g b Исходный код (<$) :: a -> Product f g b -> Product f g a Исходный код | |
| (Functor f, Functor g) => Functor (Sum f g) Исходный код | С версии: base-4.9.0.0 |
Определено в Data.Functor.Sum Методыfmap :: (a -> b) -> Sum f g a -> Sum f g b Исходный код (<$) :: a -> Sum f g b -> Sum f g a Исходный код | |
| (Functor f, Functor g) => Functor (f :*: g) Исходный код | С версии: base-4.9.0.0 |
Определено в GHC.Internal.Generics Методыfmap :: (a -> b) -> (f :*: g) a -> (f :*: g) b Исходный код (<$) :: a -> (f :*: g) b -> (f :*: g) a Исходный код | |
| (Functor f, Functor g) => Functor (f :+: g) Исходный код | С версии: base-4.9.0.0 |
Определено в GHC.Internal.Generics Методыfmap :: (a -> b) -> (f :+: g) a -> (f :+: g) b Исходный код (<$) :: a -> (f :+: g) b -> (f :+: g) a Исходный код | |
| Functor (K1 i c :: Type -> Type) Исходный код | С версии: base-4.9.0.0 |
Определено в GHC.Internal.Generics Методыfmap :: (a -> b) -> K1 i c a -> K1 i c b Исходный код (<$) :: a -> K1 i c b -> K1 i c a Исходный код | |
| Functor ((,,,) a b c) Исходный код | С версии: base-4.14.0.0 |
Определено в GHC.Internal.Base Методыfmap :: (a0 -> b0) -> (a, b, c, a0) -> (a, b, c, b0) Исходный код (<$) :: a0 -> (a, b, c, b0) -> (a, b, c, a0) Исходный код | |
| Functor ((->) r) Исходный код | С версии: base-2.1 |
Определено в GHC.Internal.Base Методыfmap :: (a -> b) -> (r -> a) -> r -> b Исходный код (<$) :: a -> (r -> b) -> r -> a Исходный код | |
| (Functor f, Functor g) => Functor (Compose f g) Source | Since: base-4.9.0.0 |
| (Functor f, Functor g) => Functor (f :.: g) Source | Since: base-4.9.0.0 |
| Functor f => Functor (M1 i c f) Source | Since: base-4.9.0.0 |
| Functor ((,,,,) a b c d) Source | Since: base-4.18.0.0 |
Defined in GHC.Internal.Base | |
| Functor ((,,,,,) a b c d e) Source | Since: base-4.18.0.0 |
Defined in GHC.Internal.Base | |
| Functor ((,,,,,,) a b c d e f) Source | Since: base-4.18.0.0 |
Defined in GHC.Internal.Base | |
class Applicative m => Monad (m :: Type -> Type) where Source
Класс Monad определяет основные операции над монадой, концепцией из раздела математики, известного как теория категорий. Однако с точки зрения программиста Haskell, лучше всего рассматривать монаду как абстрактный тип данных действий. Выражения do в Haskell обеспечивают удобный синтаксис для записи монадических выражений.
Экземпляры Monad должны удовлетворять следующим условиям:
- Левый тождество
return a >>= k = k a- Правый тождество
m >>= return = m- Ассоциативность
m >>= (\x -> k x >>= h) = (m >>= k) >>= h
Кроме того, операции Monad и Applicative должны быть связаны следующим образом:
Вышеприведенные законы подразумевают:
и что pure и (<*>) удовлетворяют законам аппликативного функтора.
Экземпляры Monad для List, Maybe и IO, определенные в Prelude, удовлетворяют этим законам.
Минимальное полное определение
Методы
(>>=) :: m a -> (a -> m b) -> m b infixl 1 Source
Последовательно выполняет два действия, передавая любое значение, произведённое первым, в качестве аргумента второму.
'as >>= bs' можно понять как выражение do.
do a <- as bs a
Альтернативное название этой функции — 'bind', но некоторые могут называть её 'flatMap', так как она эквивалентна
\x f -> join (fmap f x) :: Monad m => m a -> (a -> m b) -> m b
что можно рассматривать как отображение значения с помощью Monad m => m a -> m (m b) и последующим «сглаживанием» m (m b) в m b с помощью join.
(>>) :: m a -> m b -> m b infixl 1 Source
Последовательно выполняет два действия, игнорируя любое значение, произведённое первым, как операторы последовательности (такие как точка с запятой) в императивных языках.
'as >> bs' можно понять как выражение do.
do as bs
или в терминах (>>=) как
as >>= const bs
Вводит значение в монадический тип. Эта функция не должна отличаться от её реализации по умолчанию, как pure. Оправдание существования этой функции чисто историческое.
Экземпляры
| Monad Complex Источник | С версии: base-4.9.0.0 |
| Monad First Источник | С версии: base-4.9.0.0 |
| Monad Last Источник | С версии: base-4.9.0.0 |
| Monad Max Источник | С версии: base-4.9.0.0 |
| Monad Min Источник | С версии: base-4.9.0.0 |
| Monad NonEmpty Источник | С версии: base-4.9.0.0 |
| Monad STM Источник | С версии: base-4.3.0.0 |
| Монад (ST s) Источник | С момента: base-2.1 |
| Моноид a => Монад ((,) a) Источник | С момента: base-4.9.0.0 |
| Монад m => Монад (Kleisli m a) Источник | С момента: base-4.14.0.0 |
| Монад m => Монад (StateT s m) Источник | С момента: base-4.18.0.0 |
| Монад f => Монад (Ap f) Источник | С момента: base-4.12.0.0 |
| Монад f => Монад (Alt f) Источник | С момента: base-4.8.0.0 |
Определено в GHC.Internal.Data.Semigroup.Internal Методы(>>=) :: Alt f a -> (a -> Alt f b) -> Alt f b Исходный код (>>) :: Alt f a -> Alt f b -> Alt f b Исходный код return :: a -> Alt f a Исходный код | |
| Monad f => Monad (Rec1 f) Исходный код | С версии: base-4.9.0.0 |
Определено в GHC.Internal.Generics Методы(>>=) :: Rec1 f a -> (a -> Rec1 f b) -> Rec1 f b Исходный код (>>) :: Rec1 f a -> Rec1 f b -> Rec1 f b Исходный код return :: a -> Rec1 f a Исходный код | |
| (Monoid a, Monoid b) => Monad ((,,) a b) Исходный код | С версии: base-4.14.0.0 |
Определено в GHC.Internal.Base Методы(>>=) :: (a, b, a0) -> (a0 -> (a, b, b0)) -> (a, b, b0) Исходный код (>>) :: (a, b, a0) -> (a, b, b0) -> (a, b, b0) Исходный код return :: a0 -> (a, b, a0) Исходный код | |
| (Monad f, Monad g) => Monad (Product f g) Исходный код | С версии: base-4.9.0.0 |
Определено в Data.Functor.Product Методы(>>=) :: Product f g a -> (a -> Product f g b) -> Product f g b Исходный код (>>) :: Product f g a -> Product f g b -> Product f g b Исходный код return :: a -> Product f g a Исходный код | |
| (Monad f, Monad g) => Monad (f :*: g) Исходный код | С версии: base-4.9.0.0 |
Определено в GHC.Internal.Generics Методы(>>=) :: (f :*: g) a -> (a -> (f :*: g) b) -> (f :*: g) b Исходный код (>>) :: (f :*: g) a -> (f :*: g) b -> (f :*: g) b Исходный код return :: a -> (f :*: g) a Исходный код | |
| (Monoid a, Monoid b, Monoid c) => Monad ((,,,) a b c) Исходный код | С версии: base-4.14.0.0 |
Определено в GHC.Internal.Base Методы(>>=) :: (a, b, c, a0) -> (a0 -> (a, b, c, b0)) -> (a, b, c, b0) Исходный код (>>) :: (a, b, c, a0) -> (a, b, c, b0) -> (a, b, c, b0) Исходный код return :: a0 -> (a, b, c, a0) Исходный код | |
| Monad ((->) r) Исходный код | С версии: base-2.1 |
Определено в GHC.Internal.Base Методы(>>=) :: (r -> a) -> (a -> r -> b) -> r -> b Исходный код (>>) :: (r -> a) -> (r -> b) -> r -> b Исходный код return :: a -> r -> a Исходный код | |
| Monad f => Monad (M1 i c f) Исходный код | С момента: base-4.9.0.0 |
Определено в GHC.Internal.Generics Методы(>>=) :: M1 i c f a -> (a -> M1 i c f b) -> M1 i c f b Исходный код (>>) :: M1 i c f a -> M1 i c f b -> M1 i c f b Исходный код return :: a -> M1 i c f a Исходный код | |
class Monad m => MonadFail (m :: Type -> Type) where Исходный код
Когда значение связывается в do-нотации, шаблон слева от <- может не совпадать. В этом случае этот класс предоставляет функцию восстановления.
Monad без экземпляра MonadFail может использоваться только совместно с шаблоном, который всегда совпадает, например, с newtype, кортежами, типами данных с одним конструктором данных и неуничтожимыми шаблонами (~pat).
Экземпляры MonadFail должны удовлетворять следующему закону: fail s должно быть левым нулем для >>=,
fail s >>= f = fail s
Если ваш Monad также является MonadPlus, популярное определение —
fail _ = mzero
fail s должно быть действием, выполняющимся в самом монаде, а не исключением (за исключением экземпляров MonadIO). В частности, fail не должно реализовываться с помощью error.
С момента: base-4.9.0.0
Методы
fail :: String -> m a Исходный код
Экземпляры
| MonadFail Q Источник | |
Определено в GHC.Internal.TH.Syntax | |
| MonadFail P Источник | С версии: base-4.9.0.0 |
Определено в GHC.Internal.Text.ParserCombinators.ReadP | |
| MonadFail ReadP Источник | С версии: base-4.9.0.0 |
Определено в GHC.Internal.Text.ParserCombinators.ReadP | |
| MonadFail ReadPrec Источник | С версии: base-4.9.0.0 |
Определено в GHC.Internal.Text.ParserCombinators.ReadPrec | |
| MonadFail IO Источник | С версии: base-4.9.0.0 |
Определено в GHC.Internal.Control.Monad.Fail | |
| MonadFail Maybe Источник | С версии: base-4.9.0.0 |
Определено в GHC.Internal.Control.Monad.Fail | |
| MonadFail [] Источник | С версии: base-4.9.0.0 |
Определено в GHC.Internal.Control.Monad.Fail | |
| MonadFail f => MonadFail (Ap f) Источник | С версии: base-4.12.0.0 |
Определено в GHC.Internal.Data.Monoid | |
class (Alternative m, Monad m) => MonadPlus (m :: Type -> Type) where Source
Моноиды, которые также поддерживают выбор и неудачу.
Минимальное полное определение
Nothing
Экземпляры
| MonadPlus STM Источник |
Берёт первое не- С версии: base-4.3.0.0 |
| MonadPlus P Источник | С версии: base-2.1 |
Определено в GHC.Internal.Text.ParserCombinators.ReadP | |
| MonadPlus ReadP Источник | С версии: base-2.1 |
| MonadPlus ReadPrec Источник | С версии: base-2.1 |
| MonadPlus IO Источник |
Берёт результат первого не-выбрасывающего С версии: base-4.9.0.0 |
| MonadPlus Maybe Источник |
Выбирает самое левое С версии: base-2.1 |
| MonadPlus [] Источник |
Объединяет списки конкатенацией, начиная с пустого списка. С версии: base-2.1 |
Определено в GHC.Internal.Base | |
| (ArrowApply a, ArrowPlus a) => MonadPlus (ArrowMonad a) Источник | С версии: base-4.6.0.0 |
Определено в GHC.Internal.Control.Arrow Методыmzero :: ArrowMonad a a0 Source mplus :: ArrowMonad a a0 -> ArrowMonad a a0 -> ArrowMonad a a0 Source | |
| MonadPlus (Proxy :: Type -> Type) Source | Since: base-4.9.0.0 |
| MonadPlus (U1 :: Type -> Type) Source | Since: base-4.9.0.0 |
| MonadPlus m => MonadPlus (Kleisli m a) Source | Since: base-4.14.0.0 |
| MonadPlus f => MonadPlus (Ap f) Source | Since: base-4.12.0.0 |
| MonadPlus f => MonadPlus (Alt f) Source | Since: base-4.8.0.0 |
| MonadPlus f => MonadPlus (Rec1 f) Source | Since: base-4.9.0.0 |
| (MonadPlus f, MonadPlus g) => MonadPlus (Product f g) Source | Since: base-4.9.0.0 |
Функции
Правила именования
Функции в этом модуле используют следующие правила именования:
- Суффикс '
M' всегда обозначает функцию в категории Kleisli: конструктор типа монадыmдобавляется к результатам функции (с учётом каррирования) и нигде больше.
filter :: (a -> Bool) -> [a] -> [a] filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
- Суффикс '
_' изменяет тип результата с(m a)на(m ()). Таким образом, например:
sequence :: Monad m => [m a] -> m [a] sequence_ :: Monad m => [m a] -> m ()
- Префикс '
m' обобщает существующую функцию до монадической формы. Например:
filter :: (a -> Bool) -> [a] -> [a] mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a
mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b) Источник
Применяет монадическое действие к каждому элементу структуры, вычисляет эти действия слева направо и собирает результаты. Для версии, которая игнорирует результаты, см. mapM_.
Примеры
mapM — это буквально traverse с типом, ограниченным Monad. Его реализация может быть более эффективной благодаря дополнительным возможностям Monad.
mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m () Источник
Применяет монадическое действие к каждому элементу структуры, вычисляет их слева направо и игнорирует результаты. Для версии, которая не игнорирует результаты, см. mapM.
mapM_ — это то же самое, что и traverse_, но специализировано для монадических действий.
forM :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b) Источник
forM — это mapM с переставленными аргументами. Для версии, которая игнорирует результаты, см. forM_.
forM_ :: (Foldable t, Monad m) => t a -> (a -> m b) -> m () Источник
forM_ — это mapM_ с переставленными аргументами. Для версии, которая не игнорирует результаты, см. forM.
forM_ — это то же самое, что и for_, но специализировано для монадических действий.
sequence :: (Traversable t, Monad m) => t (m a) -> m (t a) Источник
Вычисляет каждое монадическое действие в структуре слева направо и собирает результаты. Для версии, которая игнорирует результаты, см. sequence_.
Примеры
Основное использование:
Два первых примера — это случаи, когда входные и выходные данные sequence изоморфны.
>>> sequence $ Right [1,2,3,4] [Right 1,Right 2,Right 3,Right 4]
>>> sequence $ [Right 1,Right 2,Right 3,Right 4] Right [1,2,3,4]
Следующие примеры демонстрируют поведение короткого замыкания для sequence.
>>> sequence $ Left [1,2,3,4] Left [1,2,3,4]
>>> sequence $ [Left 0, Right 1,Right 2,Right 3,Right 4] Left 0
sequence_ :: (Foldable t, Monad m) => t (m a) -> m () Источник
Вычисляет каждое монадическое действие в структуре слева направо и игнорирует результаты. Для версии, которая не игнорирует результаты, см. sequence.
sequence_ — это то же самое, что и sequenceA_, но специализировано для монадических действий.
(=<<) :: Monad m => (a -> m b) -> m a -> m b infixr 1 Источник
То же самое, что и >>=, но с переставленными аргументами.
as >>= f == f =<< as
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c infixr 1 Источник
Слева-направо композиция стрелок Kleisli.
'(bs >=> cs) a' можно понять как выражение do
do b <- bs a cs b
или в терминах (>>=) как
bs a >>= cs
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c infixr 1 Источник
Справа-налево композиция стрелок Kleisli. (>=>), с переставленными аргументами.
Обратите внимание, как этот оператор напоминает композицию функций (.):
(.) :: (b -> c) -> (a -> b) -> a -> c (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
forever :: Applicative f => f a -> f b Source
Повторять действие бесконечно.
Примеры
Распространённое применение forever — обработка входных данных из сетевых сокетов, Handle и каналов (например, MVar и Chan).
Например, вот как мы можем реализовать эхо-сервер, используя forever для прослушивания клиентских подключений по сетевому сокету и для эха клиентского ввода по дескрипторам подключений клиентов:
echoServer :: Socket -> IO () echoServer socket = forever $ do client <- accept socket forkFinally (echo client) (\_ -> hClose client) where echo :: Handle -> IO () echo client = forever $ hGetLine client >>= hPutStrLn client
Обратите внимание, что «forever» не обязательно приводит к нетерминируемому выполнению. Если действие находится в MonadPlus и прерывается после некоторого числа итераций, тогда forever фактически возвращает mzero, эффективно прерывая вызов своего родителя.
void :: Functor f => f a -> f () Source
void value игнорирует результат вычисления, например, возвращаемое значение действия IO.
Примеры
Заменить содержимое Maybe Int на unit:
>>> void Nothing Nothing
>>> void (Just 3) Just ()
Заменить содержимое Either Int Int на unit, получив в результате Either Int ():
>>> void (Left 8675309) Left 8675309
>>> void (Right 8675309) Right ()
Заменить каждый элемент списка на unit:
>>> void [1,2,3] [(),(),()]
Заменить второй элемент пары на unit:
>>> void (1,2) (1,())
Игнорировать результат действия IO:
>>> mapM print [1,2] 1 2 [(),()]
>>> void $ mapM print [1,2] 1 2
Обобщения функций над списками
join :: Monad m => m (m a) -> m a Source
Функция join — стандартный оператор объединения монады. Она используется для удаления одного уровня монадической структуры, проектируя её связанный аргумент на внешний уровень.
'join bss' может быть понято как выражение do
do bs <- bss bs
Примеры
>>> join [[1, 2, 3], [4, 5, 6], [7, 8, 9]] [1,2,3,4,5,6,7,8,9]
>>> join (Just (Just 3)) Just 3
Распространённое применение join — запуск вычисления IO, возвращённого транзакцией STM , так как транзакции STM не могут выполнять IO напрямую. Вспомним, что
atomically :: STM a -> IO a
используется для выполнения транзакций STM атомарно. Таким образом, специализируя типы atomically и join до
atomically :: STM (IO b) -> IO (IO b) join :: IO (IO b) -> IO b
мы можем их комбинировать как
join . atomically :: STM (IO b) -> IO b
для запуска транзакции STM и действия IO , которое она возвращает.
msum :: (Foldable t, MonadPlus m) => t (m a) -> m a Source
Сумма коллекции действий, использующая (<|>), обобщающая concat.
msum аналогично asum, но специализирована на MonadPlus.
Примеры
Базовое использование, используя экземпляр MonadPlus для Maybe:
>>> msum [Just "Hello", Nothing, Just "World"] Just "Hello"
mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a Source
Прямой аналог MonadPlus для filter.
Примеры
Функция filter — это просто mfilter , специализированная для монады списков:
filter = ( mfilter :: (a -> Bool) -> [a] -> [a] )
Пример использования mfilter с монадой Maybe:
>>> mfilter odd (Just 1) Just 1 >>> mfilter odd (Just 2) Nothing
filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a] Source
Это обобщает функцию filter для списков.
runIdentity (filterM (Identity . p) xs) == filter p xs
Примеры
>>> filterM (\x -> do
putStrLn ("Keep: " ++ show x ++ "?")
answer <- getLine
pure (answer == "y"))
[1, 2, 3]
Keep: 1?
y
Keep: 2?
n
Keep: 3?
y
[1,3]
>>> filterM (\x -> do
putStr (show x)
x' <- readLn
pure (x == x'))
[1, 2, 3]
12
22
33
[2,3]
mapAndUnzipM :: Applicative m => (a -> m (b, c)) -> [a] -> m ([b], [c]) Source
Функция mapAndUnzipM применяет свой первый аргумент к списку, возвращая результат как пару списков. Эта функция в основном используется с сложными структурами данных или монадой состояния.
zipWithM :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m [c] Source
Функция zipWithM обобщает zipWith на произвольные аппликативные функторы.
zipWithM_ :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m () Source
zipWithM_ — это расширение zipWithM , которое игнорирует окончательный результат.
foldM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b Source
Функция foldM аналогична foldl, за исключением того, что её результат заключён в монаду. Обратите внимание, что foldM работает слева направо по списку аргументов. Это может быть проблемой, если (>>) и «функция складывания» не коммутативны.
foldM f a1 [x1, x2, ..., xm] == do a2 <- f a1 x1 a3 <- f a2 x2 ... f am xm
Если требуется вычисление справа налево, входной список нужно перевернуть.
Примечание: foldM равно foldlM
foldM_ :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m () Source
Подобно foldM, но результат игнорируется.
replicateM :: Applicative m => Int -> m a -> m [a] Source
replicateM n act выполняет действие act n раз, а затем возвращает список результатов.
replicateM n (pure x) == replicate n x
Примеры
>>> replicateM 3 getLine hi heya hiya ["hi","heya","hiya"]
>>> import Control.Monad.State >>> runState (replicateM 3 $ state $ \s -> (s, s + 1)) 1 ([1,2,3],4)
replicateM_ :: Applicative m => Int -> m a -> m () Source
Подобно replicateM, но результат игнорируется.
Примеры
>>> replicateM_ 3 (putStr "a") aaa
Условное выполнение монадических выражений
guard :: Alternative f => Bool -> f () Source
Условное прерывание вычислений Alternative. Определяется как
guard True = pure () guard False = empty
Примеры
Общее использование guard включает условное сигнализирование об ошибке в монаде ошибок и условный отказ от текущего выбора в парсере, основанном на Alternative.
В качестве примера сигнализации об ошибке в монаде ошибок Maybe, рассмотрим функцию безопасного деления safeDiv x y, которая возвращает Nothing, когда знаменатель y равен нулю, и Just (x `div`
y) в противном случае. Например:
>>> safeDiv 4 0 Nothing
>>> safeDiv 4 2 Just 2
Определение safeDiv с использованием охранных условий, но без guard.
safeDiv :: Int -> Int -> Maybe Int
safeDiv x y | y /= 0 = Just (x `div` y)
| otherwise = Nothing
Определение safeDiv с использованием guard и Monad do-нотации:
safeDiv :: Int -> Int -> Maybe Int safeDiv x y = do guard (y /= 0) return (x `div` y)
when :: Applicative f => Bool -> f () -> f () Исходный код
Условное выполнение Applicative выражений. Например,
Примеры
when debug (putStrLn "Debugging")
выведет строку Debugging, если булево значение debug равно True, и в противном случае ничего не сделает.
>>> putStr "pi:" >> when False (print 3.14159) pi:
unless :: Applicative f => Bool -> f () -> f () Исходный код
Обратное when.
Примеры
>>> do x <- getLine
unless (x == "hi") (putStrLn "hi!")
comingupwithexamplesisdifficult
hi!
>>> unless (pi > exp 1) Nothing Just ()
Операторы монодического подъёма
liftM :: Monad m => (a1 -> r) -> m a1 -> m r Исходный код
Поднятие функции в монаду. Это эквивалентно fmap, но специализировано для монад.
liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r Исходный код
Поднять функцию в монаду, сканируя монодические аргументы слева направо.
Примеры
>>> liftM2 (+) [0,1] [0,2] [0,2,1,3]
>>> liftM2 (+) (Just 1) Nothing Nothing
>>> liftM2 (+) (+ 3) (* 2) 5 18
liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r Исходный код
Поднятие функции в монаду, сканируя монодические аргументы слева направо (см. liftM2).
liftM4 :: Monad m => (a1 -> a2 -> a3 -> a4 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m r Исходный код
Поднять функцию в монаду, сканируя монодические аргументы слева направо (см. liftM2).
liftM5 :: Monad m => (a1 -> a2 -> a3 -> a4 -> a5 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r Исходный код
Поднять функцию в монаду, сканируя монодические аргументы слева направо (см. liftM2).
ap :: Monad m => m (a -> b) -> m a -> m b Исходный код
Во многих случаях операции liftM могут быть заменены использованием ap, что способствует применению функций.
return f `ap` x1 `ap` ... `ap` xn
эквивалентно
liftM<n> f x1 x2 ... xn
Примеры
>>> pure (\x y z -> x + y * z) `ap` Just 1 `ap` Just 5 `ap` Just 10 Just 51
Строгие монодические функции
(<$!>) :: Monad m => (a -> b) -> m a -> m b infixl 4 Исходный код
Строгая версия <$>.
С момента: base-4.8.0.0
© The University of Glasgow and others
Licensed under a BSD-style license (see top of the page).
https://downloads.haskell.org/~ghc/9.12.1/docs/libraries/base-4.21.0.0-8e62/Control-Monad.html