【发布时间】:2016-06-19 22:17:36
【问题描述】:
我编写了一个 Haskell 类型类,使用 (a -> m _) 形式的类型声明它的实例会很方便,其中 m 是一种 (* -> *),例如 monad,_ 是一个不饱和的槽。我知道如何编写newtype X a m b = X (a -> m b),并为X a m 声明一个实例。但如果可能的话,我正在寻找的是使用裸露的、未包装的 -> 类型。
如果想为(a -> _) 形式的类型声明实例,那么你可以写:
instance Foo a ((->) a) where ...
但我不知道如何/是否可以使用(a -> m _) 形式的类型来做到这一点。我想我希望在我的实例声明中组合类型构造函数 (->) a _ 和类型构造函数 m _。
我想写这样的东西:
instance Foo a ((->) a (m :: *->*)) where ...
或:
instance Foo a ((->) a (m *)) where ...
但是这些当然是行不通的。可以这样做吗?
具体来说,这就是我想要实现的目标。我为 嵌入在(一层)其他 MonadReader 中的 MonadReaders, 像这样:
{-# LANGUAGE FunctionalDependencies FlexibleInstances
UndecidableInstances #-}
class MonadReader w m => DeepMonadReader w r m | m -> r where
{ deepask :: m r
; deepask = deepreader id
; deeplocal :: (r -> r) -> m a -> m a
; deepreader :: (r -> a) -> m a
; deepreader f = do { r <- deepask; return (f r) }
}
instance MonadReader r m => DeepMonadReader w r (ReaderT w m) where
{ deepask = lift ask
; deeplocal = mapReaderT . local
; deepreader = lift . reader
}
最好也提供一个类似这样的实例:
instance MonadReader r m => DeepMonadReader w r ((->) w (m :: * ->
*)) where
{ deepask = \w -> ask
; deeplocal f xx = \w -> local f (xx w)
; deepreader xx = \w -> reader xx
}
【问题讨论】: