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
并使用>=>
(或<=<
,从您的类型中不清楚)将函数组合在一起。
过去几个月我一直在研究 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
并使用>=>
(或<=<
,从您的类型中不清楚)将函数组合在一起。