Интуиция для «запуска» функции монад - PullRequest
0 голосов
/ 05 февраля 2019

Я изучаю монады в Haskell, я понял, почему они полезны, я в целом понял, что связывают, объединяют, возвращают и делают.

Я также рассмотрел основные примеры использования для основного читателя / писателя./ state / list / возможно монады.

Тем не менее, будучи новичком, я все еще не чувствую, что у меня есть представление о том, что означает функция «run» (например, runState, runReader, runWriter) в целом.Кажется, у него нет общей сигнатуры, как у вышеприведенных функций, и я не понимаю ее, если она определима / имеет смысл для всех монад.

1 Ответ

0 голосов
/ 05 февраля 2019

Функция 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 функции на самом деле не делают ничего здесь, они просто "разворачивают" новый тип, чтобы мы могли получить базовое значение.

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

...