我刚刚编写了这个函数,它只接受第二个值在某个 monad 中的一对,然后“将 monad 拉出”以覆盖整个对。
unSndM :: Monad m => (a, m c) -> m (a, c)
unSndM (x, y) = do y' <- y
return (x, y')
是否有更好和/或更短或无点甚至标准的方式来表达这一点?
在 -XTupleSections 打开的情况下,我已经完成了以下工作......
unSndM' :: Monad m => (a, m c) -> m (a, c)
unSndM' (x, y) = y >>= return . (x,)
谢谢!
最佳答案
如果 Traversable
和 Foldable
(,) x)
的实例在图书馆里(我想我必须为他们的缺席承担一些责任)......
instance Traversable ((,) x) where
traverse f (x, y) = (,) x <$> f y
instance Foldable ((,) x) where
foldMap = foldMapDefault
...那么这(有时称为“强度”)将是
Data.Traversable.sequence
的特化.sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
所以
sequence :: (Monad m) => ((,) x) (m a) -> m (((,) x) a)
IE。
sequence :: (Monad m) => (x, m a) -> m (x, a)
事实上,序列并没有真正使用
Monad
的全部功能。 : Applicative
会做。此外,在这种情况下,pairing-with-x 是线性的,所以 traverse
只做 <$>
而不是 pure
的其他随机组合和 <*>
,并且(正如在其他地方指出的那样)您只需要 m
要有功能结构。
关于haskell - 这个简单的 Haskell 函数是否已经有了一个众所周知的名字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3998133/