Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
可以在Haskell实例声明中组合类型吗?_Haskell_Typeclass - Fatal编程技术网

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

可以在Haskell实例声明中组合类型吗?,haskell,typeclass,Haskell,Typeclass,我已经编写了一个Haskell typeclass,使用(a->m_)形式的类型来声明它的实例会很方便,其中m是一种(*->*),比如monad,而是一个不饱和的插槽。我知道如何编写newtypexamb=X(a->mb),并为xam声明一个实例。但我想要的是,如果可能的话,使用裸的、未包装的->类型 如果要声明表单(a->)类型的实例,则可以编写: instance Foo a ((->) a) where ... 但我不知道如何/是否可以使用表单类型(a->m)。我想我想在实例声明中

我已经编写了一个Haskell typeclass,使用
(a->m_)
形式的类型来声明它的实例会很方便,其中
m
是一种
(*->*)
,比如monad,而
是一个不饱和的插槽。我知道如何编写
newtypexamb=X(a->mb)
,并为
xam
声明一个实例。但我想要的是,如果可能的话,使用裸的、未包装的
->
类型

如果要声明表单
(a->
)类型的实例,则可以编写:

instance Foo a ((->) a) where ...
但我不知道如何/是否可以使用表单类型
(a->m)
。我想我想在实例声明中编写类型构造函数
(>)a
和类型构造函数
m

我想这样写:

instance Foo a ((->) a (m :: *->*)) where ...
{-# 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
  }
或:

但这些当然不起作用。有可能这样做吗

具体来说,这就是我想要实现的目标。我为他写了一个打字班 嵌入(一级)其他单体恐惧者中的单体恐惧者, 像这样:

instance Foo a ((->) a (m :: *->*)) where ...
{-# 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::*->*)

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

类monawarder w m=>deepmonawarder w r m | m->r其中

w
从未出现在任何成员签名中这一事实表明存在问题

。。。我为Monawarder编写了一个typeclass,它嵌入到其他Monawarder的内部(一个级别)

我会采取相反的观点。谈论单子堆栈是一种转换的方法是有道理的 另一个monad堆栈的版本。例如:

StateT s (WriterT w IO)   "contains"     IO
WriterT w (Maybe a)       "contains"     Maybe a
一个monad堆栈m1包含另一个monadm2意味着什么? 这只是意味着有一种方法可以将m2中的计算转换为m1中的计算:

convert ::  m2 a -> m1 a
当然,当使用monad变压器时,这只是提升

为了表达您在另一个monad中嵌入monad阅读器的概念,我将使用 类型类别:

class HasReader m m' r where ...
  deepAsk :: m r
  deepLocal :: (r -> r) -> m' a -> m a
这里的想法是,一个实例HasReader m'r表达了以下事实: monadm“包含”一个monadm',它本身就是一个具有 环境r

deepAsk返回m'的环境,但作为m中的计算

deepLocal使用环境修改功能在m'中运行计算 但将其作为计算返回到m。请注意此类型签名与您的不同之处: 我的deepLocal使用不同的单子,m'm,而你的单子是从mm

下一步是决定要编写哪些三元组(m,m',r) of拥有阅读器。很明显,你脑海中似乎有这样的例子:

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

谢谢。您提出了几个建议:(1)将实例的类型更改为(->)w,或者将类的第一个参数从外部读取器环境的类型更改为外部读取器monad的类型。(2) 我改变了当地人的生活方式。(3) 我可能想为monad堆栈提供类的实例,这些堆栈只有一层读卡器;在许多这样的情况下,这个课程并没有那么有用或必要。回答(1):这是值得探索的,谢谢。Re(2):我需要一个与我描述的类型相同的deepLocal;虽然它可能有一些优势,但我还没有看到你所提议的深度。我会考虑一下。Re(3):事实上,对于您的第二组案例,我们不需要HasReader类,我们也不需要自己执行
lift
ing,因为它已经写入到您的
m
monad的monader实例中。我的
deepmonawarder
类用于堆栈中的外部monawarder“妨碍”更深入嵌入的monawarder的情况,使后者的
ask
local
方法更难访问。当然,人们仍然可以通过使用
lift
mapReader
等正确组合来获取它们;但是这些组合并不总是显而易见的…Re(3)-为什么不给出一个具体的例子,说明您想使用DeepReader类,我们将看到选项是什么。继续讨论。。。