Haskell:如何在monad的任意元组上映射函数

时间:2015-04-12 10:32:00

标签: haskell tuples monads functor lens

是否有可能构建一个函数来映射任意arity的monad元组?

如,

f :: (m a -> m [a]) -> (m x, m y) -> (m [x], m [y])

(但是对于任意的arity)。 This similar question,提出了许多有希望的建议;例如,镜头' eachover both,但每个似乎都需要一个同质类型的元组:我想使用具有不同内部类型的同质monad元组。

1 个答案:

答案 0 :(得分:4)

你说的方式是不可能的。

在您的类型签名中,初始函数只能使用m a,但您希望将m xm y传递给它,因此类型不匹配。< / p>

使用rankNTypes启用它当然是可能的:

{-# LANGUAGE rankNTypes #-}
f :: Monad m => (forall a. m a -> m [a]) -> (m x, m y) -> (m [x], m [y])
f fun (x, y) = (fun x, fun y)

这是因为括号内的forall a.强制它是多态的,而不仅仅是类型a


你可能想要的是这样的:

f :: Monad m => (a -> m b) -> (m a, m a) -> (m b, m b)

甚至

f :: Monad m => (a -> m c) -> (b -> m d) -> (m a, m b) -> (m c, m d)

请注意,我将函数类型从m a -> m b更改为a -> m b因为这允许我们对monadic操作进行排序,而不是转换monad,这在我们想要操作它们时更有意义。