2
內由於我有以下的DSL(使用免費單子)及其解釋Memoising:哈斯克爾:使用MonadState一個FreeMonad解釋
data MyDslF next =
GetThingById Int (Thing -> next)
| Log Text next
type MyDslT = FT MyDslF
runMyDsl :: (MonadLogger m, MonadIO m, MonadCatch m) => MyDslT m a -> m a
runMyDsl = iterT run
where
run :: (MonadLogger m, MonadIO m, MonadCatch m) => MyDslF (m a) -> m a
run (Log message continue) = Logger.log message >> continue
run (GetThingById id' continue) = SomeApi.getThingById id' >>= continue
我希望可以先內部改變解釋使用MonadState因此,如果一個Thing
已經對給定Id
檢索,再有就是SomeApi
沒有第二個電話讓我們假設我已經知道如何使用get
和put
寫memoised版本,但我遇到的問題是運行MonadState
內runMyDsl
。 我在想該解決方案將類似於:
type ThingMap = Map Int Thing
runMyDsl :: (MonadLogger m, MonadIO m, MonadCatch m) => MyDslT m a -> m a
runMyDsl = flip evalStateT mempty . iterT run
where
run :: (MonadLogger m, MonadIO m, MonadCatch m, MonadState ThingMap m) => MyDslF (m a) -> m a
run ..
但類型不對齊,因爲run
回報(.. , MonadState ThingMap m) => m a
和evalStateT
預計StateT ThingMap m a
。