将A => M 变成M

对于单子M ,是否可以将A => M[B]变成M[A => B]

我已经尝试过这种types无济于事了,这让我觉得这是不可能的,但我想我会问。 而且,在Hooglesearcha -> mb -> m (a -> b)没有返回任何东西,所以我不会很幸运。

在实践中

不,这是不可能的,至less不是有意义的。

考虑这个Haskell代码

 action :: Int -> IO String action n = print n >> getLine 

这首先需要打印它(这里执行的IO),然后从用户读取一行。

假设我们有一个假想的transform :: (a -> IO b) -> IO (a -> b) 。 那么作为一个心理实验,考虑一下:

 action' :: IO (Int -> String) action' = transform action 

以上就必须事先做好所有IO,然后才能知道n ,然后返回一个纯函数。 这不能等同于上面的代码。

要强调一点,请考虑下面这个无意义的代码:

 test :: IO () test = do f <- action' putStr "enter n" n <- readLn putStrLn (fn) 

神奇的是, action'应该提前知道用户打算下一步! 会话看起来像

 42 (printed by action') hello (typed by the user when getLine runs) enter n 42 (typed by the user when readLn runs) hello (printed by test) 

这需要一个时间机器,所以它不能完成。

理论上

不,不能做。 这个论点与我给类似问题的论点类似 。

假设通过矛盾transform :: forall ma b. Monad m => (a -> mb) -> m (a -> b) transform :: forall ma b. Monad m => (a -> mb) -> m (a -> b) 。 专注于继续monad ((_ -> r) -> r) (我省略了newtype包装器)。

 transform :: forall ab r. (a -> (b -> r) -> r) -> ((a -> b) -> r) -> r 

专精r=a

 transform :: forall a b. (a -> (b -> a) -> a) -> ((a -> b) -> a) -> a 

应用:

 transform const :: forall a b. ((a -> b) -> a) -> a 

通过咖喱霍华德同构,以下是一个直觉重言式

 ((A -> B) -> A) -> A 

但是这是Peirce定律,在直觉逻辑中是不可certificate的。 矛盾。

其他答复很好地说明了对于任何monad m来说,通常不可能实现从a -> mbm (a -> b)的函数。 但是,有一些特定的monad可以实现这个function。 一个例子是读者monad:

 data Reader ra = R { unR :: r -> a } commute :: (a -> Reader rb) -> Reader r (a -> b) commute f = R $ \ra -> unR (fa) r 

没有。

例如, Option是monad,但函数(A => Option[B]) => Option[A => B]没有任何有意义的实现:

 def transform[A, B](a: A => Option[B]): Option[A => B] = ??? 

你把什么,而不是???SomeSome什么呢? 还是None