Приведение в порядок монад - превращение монадного трансформатора в монаду нового типа
Я пытаюсь взять напримерExceptT a (StateT A M)
для какого-то конкретного типаA
и монадаM
и завернуть их в мои новые монады.
Сначала я определил, чтоStateT A M
часто появляется в других контекстах, и поэтому я решил, что было бы лучше обернуть это в монадеM1
а затем завернутьExceptT a M1
вM2
.
Желаемое свойство сделатьM1
а такжеM2
случаиMonadState
и классM
(допустим, это называетсяMyMonadClass
). ТакжеM2
должен быть примеромMonadError
.
Сначала я начал с синонимов простого типа:
type MyState = StateT A M
type MyBranch a = ExceptT a MyState
потом я подумал, что сначала набросаю объявления экземпляров (без реализации экземпляра) и вот где я впервые застрял.instance MonadState A (MyState)
казалось, не правильный синтаксис. Я думал, что мне придется создатьnewtype MyState' a = StateT a M
а потомtype MyState = MyState A
(Позволяет не использовать языковые расширения там, где это не нужно).
Однако, как только я начал преобразовывать синонимы вnewtype
декларации я начал терять связь сStateT A M
а такжеExceptT ...
типы.
newtype MyState' s a = MyState' { runMyState :: s -> (s, a) }
type MyState = MyState' A
newtype MyBranch e a = MyBranch { runMyBranch :: MyState (Either e a) }
Теперь уже реализованные преобразователи исчезли, и я думаю, что пытаюсь сделать что-то, что не имеет особого смысла. Итак, мой вопрос: как правильно обернуть этот тип поведения в новые составные монады, которые делают доступными нижележащие слои, чтобы избежать ненужного подъема и сохранить вещи ясными и хорошо организованными.