Haskell中高阶函数的提升

Haskell中高阶函数的提升,haskell,higher-order-functions,lifting,Haskell,Higher Order Functions,Lifting,我试图构造一个类型为的函数: liftsumting::((a->mb)->mb)->(a->tmb)->tmb 其中t是一个单声道变压器。具体而言,我有兴趣这样做: liftSumthingIO :: MonadIO m => ((a -> IO b) -> IO b) -> (a -> m b) -> m b 我摆弄了一些哈斯凯尔魔法图书馆,但没用。我怎么得到它 是的,或者可能有一个我没有找到的现成解决方案?这不能在所有MonadIO实例上通用,因为I

我试图构造一个类型为的函数:

liftsumting::((a->mb)->mb)->(a->tmb)->tmb
其中
t
是一个单声道变压器。具体而言,我有兴趣这样做:

liftSumthingIO :: MonadIO m => ((a -> IO b) -> IO b) -> (a -> m b) -> m b
我摆弄了一些哈斯凯尔魔法图书馆,但没用。我怎么得到它
是的,或者可能有一个我没有找到的现成解决方案?

这不能在所有
MonadIO
实例上通用,因为
IO
类型处于否定位置。有一些关于hackage的库针对特定实例(,)执行此操作,但关于它们是否在语义上合理,特别是关于它们如何处理异常和类似奇怪的
IO
y事情,存在一些争论

编辑:有些人似乎对积极/消极立场的区别感兴趣。事实上,没什么好说的(你可能已经听过了,但名字不同)。这个术语来自于子类型的世界


子类型背后的直觉是“
a
b
的一个子类型(我将写
a Gah!为什么哈斯克尔的问题都这么难?这里没有简单的要点:-(@drozzy:事实上,这个标签可能并不总是那么容易,但人们的努力确实会得到回报。”由于
IO
类型处于否定位置"-你能详细解释一下这意味着什么以及为什么它如此重要吗?@DanBurton我已经写了一些关于它的文章。这当然是有帮助的。我认为monad控件可能允许我做足够的修补。我不认为上下文从
MA
TMA
的变化会破坏任何东西。因为没有其他答案我将此设置为已接受。快速问题:为什么
liftSumthing f=(>>=).liftIO.f$return
无效?毕竟
Monad m=>(a->mb)->mb
Monad m=>ma
使用双射
(>=)::Monad m=>ma->(对于所有b.(a->mb)->mb
\f->f return::Monad m=>(对于所有b.(a->MB)->MB)->MA
。我猜这与
对于所有的
都有关系。@m.Aroosi确实,你对你的孔不小心。对于所有a b.((a->IO b)->IO b)->((a->m b)->m b)
对于所有a。(对于所有b.(a->IO b)->IO b)->(对于所有b.(a->MB)->MB)
。特别是:在前者(我们试图编写的那一个)中,调用方可以选择
b
,并且可以选择它与
a
不同,在这种情况下
return
不是
(a->IO b)->IO b
函数的正确参数。
f1 :: ((a1 -> b1) -> c1) -> (d1 -> e1)
f2 :: ((a2 -> b2) -> c2) -> (d2 -> e2)
class Monad m => MonadIO m where
    liftIO :: IO a -> m a