Haskell (a -> m a) -> m (a -> a) -> m (a -> a)

Haskell (a -> m a) -> m (a -> a) -> m (a -> a)

过去几个月我一直在研究 Haskell,我 运行 遇到了一种我不太确定如何处理的 monad 情况。

我有一个 a -> m a 类型的值和第二个 m (a -> a) 类型的值,我需要组合它们,使第一个的结果最终作为第二个和如果可能,生成 m (a -> a)。在过去的一天里,我一直坚持这一点,我并没有全神贯注。我想我正在寻找像 (a -> m a) -> m (a -> a) -> m (a -> a) 这样的函数。如果更有意义的话,我可以提供一个更具体的例子。

一般情况下,您不能这样做。问题是您的结果类型:m (a -> a)。这是一个 single monadic action,它产生一个函数;但是您的第一个输入具有 a -> m a 的形式,它(可能)为每个参数产生一个 different monadic 动作。因此,例如,对于 [] monad [a -> a] 是具有固定长度的函数列表,而 a -> [a] 可以为每个参数具有不同的长度。所以一般来说没有办法把函数类型 'push' 变回 m ;有关相关的 SO 问题,请参阅 What is the general case of QuickCheck's promote function?

如果 a -> m a 可以满足您的需要,那么您可以使用

m (a -> a) 参数转换为 a -> m a
\ x -> fmap ($ x) af

并使用>=>(或<=<,从您的类型中不清楚)将函数组合在一起。