Функция run
для большинства монад на самом деле является просто артефактом того, как монада представлена внутри;Например, монада Reader
теоретически может быть представлена как просто
type Reader r a = r -> a
State
как
type State s a = s -> (s, a)
и так далее.Однако, если бы мы сделали это, мы не смогли бы предоставить различные реализации классов типов (включая Monad
) для Reader
и State
, поскольку они оба были бы просто представлены (->)
.
-то есть, если бы мы написали
instance Functor (Reader r)
-- ....
и
instance Functor (State s)
-- ...
, наш компилятор пожаловался бы, что мы пытаемся дать две разные Functor
реализации для (->) a
.
Таким образом, вместо type
мы просто более или менее пишем одно и то же с помощью newtype
, например,
newtype Reader r a = Reader { runReader :: r -> a }
или
newtype State s a = State { runState :: s -> (s, a)}
Как видите, run
функции на самом деле не делают ничего здесь, они просто "разворачивают" новый тип, чтобы мы могли получить базовое значение.
(фактические реализации могут включать в себя монадные преобразователи и поэтому выглядят немного болеесложно, но по сути они все еще делают то же самое).