将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 -> mb
到m (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] = ???
你把什么,而不是???
? Some
? Some
什么呢? 还是None
?