我有那种
ActionT TL.Text (ReaderT T.Text IO)我正试图为此创建一个MonadReader实例,这样我就不必提要求了,但是总是
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use -XFlexibleInstances if you want to disable this)我试过一些实例类型,下面几个,但是他们总是得到上面的错误
instance MonadReader T.Text (ActionT TL.Text (ReaderT T.Text IO))
instance MonadReader r (ActionT TL.Text (ReaderT r IO))
instance (ScottyError e, MonadReader r m) => MonadReader r (ActionT e (ReaderT r m))我觉得我错过了一些基本的例子。我想我理解FlexibleInstances,但我看不出这在这里是如何适用的。
对于实例类型的任何帮助都将不胜感激,我希望自己实现ask和local,因为主要目标是学习。
谢谢。
更新
我让它和FlexibleInstances, MultiParamTypeClasses, UndecidableInstances一起工作
instance (ScottyError e, Monad m, MonadReader r m) => MonadReader r (ActionT e m) where
ask = lift ask仍在努力在当地实施。我也认为UndecidableInstances是坏的?
更新2
我想我真正需要的是。
instance (ScottyError e, Monad m, MonadReader r m) => MonadReader r (ActionT e (ReaderT r m)) where但我还是找不出local
发布于 2014-04-19 05:54:27
实例将是
instance (ScottyError e, Monad m, MonadReader r m) => MonadReader r (ActionT e (ReaderT r m)) where然而,Scotty没有公开实现本地功能所需的函数。
我正在尝试编写一个mapActionT,以便实现local,如果我想出了这样做的类型,我将更新这个答案:)
编辑:
我想我有mapActionT,但我不确定。
mapActionT :: (Monad m, Functor n, ScottyError e) => (forall a . m a -> n a) -> ActionT e m b -> ActionT e n b
mapActionT nat m = ActionT $ flip mapErrorT (runAM m) $ \rt ->
flip mapReaderT rt $ \st ->
StateT $ \s -> fmap (\a -> (a,s)) (nat (evalStateT st s))最后,我从葫芦复制类型签名,以便为fmap引入函子n。
欢迎对执行情况提出任何意见。
发布于 2014-04-18 15:06:22
正如您自己回答的那样,您需要UndecidableInstances来实现完全通用的MonadReader实例。这是一个必要的缺点,您可以在实现这类泛型monad类型类实例的所有库中看到它。
我担心实现local将是一个问题。如果您查看标准实例,它们都使用某种特定于特定monad的映射函数。而且,由于ActiveT似乎都没有导出这样的方法或它的内部,所以看起来不可行。
https://stackoverflow.com/questions/23147892
复制相似问题