Операционная монада с интерпретатором в произвольной монаде

Я использую операционную монаду Генриха Апфельмуса. Я хотел бы параметризовать интерпретатор монадой для типа результата. Компилируется следующая версия моего кода:

{-# LANGUAGE GADTs #-}

import Control.Monad.Operational

data EloI a where
    Display :: Int -> EloI ()

type Elo a = Program EloI a

interpret :: Monad m => (Int -> m ())
                     -> Elo a
                     -> Int
                     -> m a
interpret display = interp
  where
    interp :: Monad m => Elo a -> Int -> m a
    interp = eval . view
    eval :: Monad m => ProgramView EloI a -> Int -> m a
    eval (Display i :>>= is) s = interp (is ()) s

Теперь я изменяю последнюю строку на

eval (Display i :>>= is) s = display i >> interp (is ()) s

, и вывод типа больше не выполняется, я получаю вывод

Не удалось вывести (m ~ m1) из контекста (Monad м)
связаны сигнатурой типа для интерпретации :: Monad m => (Int -> m ()) -> Elo a -> Int -> m a (...)

Когда я удаляю подпись типа для interp, я получаю дополнительную ошибку (не удалось вывести (a1 ~ a)).
Когда я меняю все m на IO (как в примере с крестиками-ноликами для операционной монады), он снова компилируется.
Я пытаюсь сделать что-то, что не имеет смысла, или я могу подсказать GHC? Признаюсь, я не уверен, что мне нужна такая гибкость.

5
задан Duschvorhang 3 December 2011 в 23:58
поделиться