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_Io_Monad Transformers - Fatal编程技术网

Haskell 为什么任何单子堆栈都能派生出单子呢?

Haskell 为什么任何单子堆栈都能派生出单子呢?,haskell,io,monad-transformers,Haskell,Io,Monad Transformers,我很困惑编译器没有抱怨下面的代码(代码编译): 如果我必须在某个地方添加MonadIO m作为约束,例如 deriving instance MonadIO m => MonadIO (Foo e m a) 事实上,如果我尝试 deriving instance MonadIO (Foo e m a), 编译器抱怨 我还注意到,当我在那里添加约束MonadIO m时,我只能使用liftIO,而不管我是否使用了独立派生和约束的方法2,这也是有意义的。MonadIO实例处于MonadIO

我很困惑编译器没有抱怨下面的代码(代码编译):

如果我必须在某个地方添加
MonadIO m
作为约束,例如

deriving instance MonadIO m => MonadIO (Foo e m a)
事实上,如果我尝试

deriving instance MonadIO (Foo e m a),
编译器抱怨

我还注意到,当我在那里添加约束
MonadIO m
时,我只能使用
liftIO
,而不管我是否使用了独立派生和约束的方法2,这也是有意义的。
MonadIO
实例处于
MonadIO m
的条件下

是只有我一个人,还是违反直觉


这与不推荐使用的-XDatatypeContexts扩展有关吗?

对于
GeneralizedNewtypeDeriving
,所有实例都有相同的约束条件-newtype的基类型必须是同一类的实例:

实例所做的只是应用和删除newtype构造函数

的派生实例,即
Monad
具有已存在的约束
Monad(em除外)
。但是,
MonadIO(m除外)
没有实例,因此它必须是对生成的
MonadIO
声明的约束

如果我尝试使用
MonadIO(Foo e m)
,将生成一个错误:

something :: Foo e m ()
something = liftIO $ print "5"
以下是错误:

    • No instance for (MonadIO m) arising from a use of ‘liftIO’
      Possible fix:
        add (MonadIO m) to the context of
          the type signature for:
            something :: Foo e m ()
    • In the expression: liftIO $ print "5"
      In an equation for ‘something’: something = liftIO $ print "5"

我知道这一点。但为什么这样做会如此尴尬?例如,当我派生
MonadError E
时,我以后不必添加任何约束。
MonadError E
不需要对
m
进行任何约束,因为使用了
ExceptT
的实现,这适用于所有
m
MonadIO
在没有
m
约束的情况下无法实现,因为它必须使用
m
中的实现,从而确保存在这样的实现。这并不令人尴尬,或者至少它正是它所需要的尴尬。添加了一个链接到文档,希望有更好的解释。
    • No instance for (MonadIO m) arising from a use of ‘liftIO’
      Possible fix:
        add (MonadIO m) to the context of
          the type signature for:
            something :: Foo e m ()
    • In the expression: liftIO $ print "5"
      In an equation for ‘something’: something = liftIO $ print "5"