可以在Haskell实例声明中组合类型吗?

我写了一个Haskell类型类,并且使用form (a -> m _)类型来声明它的实例是很方便的,其中m是类型的(* -> *) ,比如monad,而_是一个插槽将保持不饱和状态。 我知道如何编写newtype X amb = X (a -> mb) ,并为X am声明一个实例。 但是我正在寻找的是使用裸露的,未包装的->类型,如果可能的话。

如果想要为表单类型(a -> _)声明实例,那么你可以写:

instance Foo a ((->) a) where ...

但我不知道如何/是否可以使用表单类型(a -> m _)来完成它。 我想我想在我的实例声明中编写类型构造函数(->) a _和类型构造函数m _

我想写这样的东西:

instance Foo a ((->) a (m :: *->*)) where ...

要么:

instance Foo a ((->) a (m *)) where ...

但当然这些都不起作用。 是否有可能做到这一点?

具体而言,这是我想要实现的。 我为其他MonadReaders内部(一级)嵌入的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
  }

我认为你走错了路,让事情比他们需要的复杂得多。

一些观察:

...(( - >)w(m :: * - > *))...

让我们来探讨一下你的意思。 您正在将它用于DeepMonadReader类中的类型参数m ,因此它需要是monad。 你能举出一个具有这种类型的monad的具体例子吗? 为什么不使用((->) w)

class MonadReader wm => DeepMonadReader wrm | m - > r其中...

w从来不会在任何成员签名中出现这一事实,这表明有什么不对劲。

...我为其他MonadReader内部(一层)内嵌的MonadReaders写了一个类型类型...

我会采取相反的观点。 讨论monad堆栈是有意义的,monad堆栈是另一个monad堆栈的转换版本。 例如:

StateT s (WriterT w IO)   "contains"     IO
WriterT w (Maybe a)       "contains"     Maybe a

monad堆栈m1 “包含”另一个monad m2意味着什么? 这只是意味着有一种方法可以将m2中的计算转换为m1中的计算:

convert ::  m2 a -> m1 a

当然,这只是在使用monad变压器时lift

为了表达嵌入另一个monad中的monad reader的概念,我将使用这个类型的类:

class HasReader m m' r where ...
  deepAsk :: m r
  deepLocal :: (r -> r) -> m' a -> m a

这里的想法是,一个HasReader的实例表达了这样一个事实,即monad m “包含”monad m“ ,它本身就是一个具有环境r的读者。

deepAsk返回M”,但在计算环境。

deepLo​​cal使用环境修改函数以m'运行计算,但将其作为以m计算。 请注意这种类型签名与您的不同:我的deepLo​​cal使用不同的monads, m'm,而您的只是从mm

下一步是决定我们要编写哪些三元组(m,m',r)HasReader实例。 很明显,你似乎有这样的例子:

m                                    m'                           r
---------------------                -----------                  --
ReaderT s (ReaderT r m)              ReaderT r m                  r
ReaderT t (ReaderT s (ReaderT r m)   ReaderT s (Reader T r m)     s
...

但想要拥有这些实例似乎也是合理的:

StateT s (ReaderT r m)               ReaderT r m                  r
WriterT w (ReaderT r m)              ReaderT r m                  r
MaybeT (ReaderT r m)                 ReaderT r m                  r
...

但事实证明,我们不需要HasReader类来处理这些情况。 我们可以只写表达,比如M计算”,lift它为m。

链接地址: http://www.djcxy.com/p/43523.html

上一篇: Can one compose types in a Haskell instance declaration?

下一篇: Illegal instance declaraion when using tuples