是否有可能构建一个函数来映射任意arity的monad元组?
如,
f :: (m a -> m [a]) -> (m x, m y) -> (m [x], m [y])
(但是对于任意的arity)。 This similar question,提出了许多有希望的建议;例如,镜头' each
或over both
,但每个似乎都需要一个同质类型的元组:我想使用具有不同内部类型的同质monad元组。
答案 0 :(得分:4)
你说的方式是不可能的。
在您的类型签名中,初始函数只能使用m a
,但您希望将m x
和m 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,这在我们想要操作它们时更有意义。