haskell - ограничения ранга n? (или преобразователи монад и Data.Suitable)

Я пытаюсь написать что-то, что похоже на "типы ранга 2", но вместо ограничений. (Или, может быть, неверно полагать, что изменение -> в определении "типов ранга 2" на => имеет смысл; пожалуйста, отредактируйте вопрос, если считаете, что лучше терминологии).

setup

Во-первых, Подходящий класс типов (из Data.Suitable , основа rmonad) может использоваться для обозначения типов значений, которые могут В этом вопросе я буду использовать

Suitable m a

, чтобы обозначить, что значение a может использоваться как значение для некоторых функций монады m (в частности, если m - это DSL, тогда его значения обычно a , которые подходят), например

class PrintSuitable m where
    printSuitable :: Suitable m a => a -> m ()

См. Верхний комментарий для RMonad [ ссылка ] и его источник для примера того, как использовать "Подходит". Например, один может определить Подходящий m (Карта a b) и распечатать количество элементов на карте.

вопрос

цель : Теперь у меня есть преобразователь монад MyMonadT , и я хочу сделать MyMonadT m экземпляром PrintSuitable всякий раз, когда m - это экземпляр PrintSuitable .

Мотивация ограничений ранга 2 : Проблема в том, что тип a вводится в отношении функции printSuitable , т.е. не появляется в классе подпись. Поскольку можно добавить ограничения только к сигнатуре класса (дополнительные ограничения для реализации функции экземпляра недопустимы), имеет смысл сказать кое-что обо всех a в подпись класса (строка 2 ниже).

Ниже показан предполагаемый код.

instance (PrintSuitable m, MonadTrans t,
        (forall a. Suitable (t m) a => Suitable m a), -- rank 2 constraint
        ) => PrintSuitable (t m) where

    printSuitable = lift ...

-- MyMonadT doesn't change what values are Suitable, hence the rank 2 expression,
-- (forall a. Suitable (t m) a => Suitable m a) should hold true
data instance Constraints (MyMonadT m) a =
    Suitable m a => MyMonadT_Constraints
instance Suitable m a => Suitable (MyMonadT m) a where -- the important line
    constraints = MyMonadT_Constraints

instance MonadTrans MyMonadT where ...
-- now, MyMonadT m is a PrintSuitable whenever m is a PrintSuitable

-- the manual solution, without using MonadTrans, looks roughly like this
instance PrintSuitable m => PrintSuitable (t m) where
    printSuitable a = withResConstraints $ \MyMonadT_Constraints -> ...

указанное ограничение говорит, что все, что подходит в (t m) , подходит в m . Но, конечно, это неверный Haskell; как можно кодировать функциональный эквивалент?

Заранее спасибо !!!

7
задан gatoatigrado 10 November 2011 в 09:01
поделиться