2012-01-24 3 views
3

У меня есть стек монада трансформатор формы:Создание пользовательских Экземпляры PersistBackend

newtype T m a = T { unT :: StateT State (SqlPersist m) a } 
    deriving (Monad, MonadState State) 

И хотите использовать постоянные insert и lookup звонки, так что мне нужно сделать PersistBackend экземпляр для T. Тем не менее, фантомный тип кодирует конкретный бэкэнд в возвращаемом типе Key - это вызывает некоторые дополнительные головные боли. Для того, чтобы решить вопрос типа фантом, мой экземпляр имеет вид:

instance (Monad m, MonadIO m, MonadBaseControl IO m) => PersistBackend T m where 
    insert = T . lift . liftM (Key . unKey) . insert 
    ... and about a dozen such methods ... 

Am I вслепую с видом простой способ? Способ кроме вызова функции вручную подъема: insertT = T . lift . insert

ответ

1

У меня есть две различные рекомендации:

  1. Флип вещи вокруг, и положить SqlPersist вокруг вашего StateT вместо наоборот.
  2. Создайте модуль с поднятыми версиями функций, аналогичный тому, что делает MonadState.

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

+0

Прямо сейчас я делаю решение Yesod для функции 'runDB', но в будущем я мог бы построить TH' $ (derivePersist' {'Unique',' Store', 'Query'}') ' функция - это было бы приятным дополнением к постоянному шаблону (если это выполнимо)? –

+0

В теории, да, я так думаю, но это похоже на довольно большое начинание. Если вы планируете приблизиться к этому, я бы рекомендовал сначала отправить по электронной почте список Yesod для обсуждения. –

Смежные вопросы