Scala Cats是否提供与Haskell mapM等价的函数?
Scala Cats中的Haskell mapM等价功能
嘿,答案是肯定的!Scala Cats里完全有和Haskell mapM等价的功能,只不过它的标准命名不是mapM,而是traverse——这是函数式编程库里更通用的命名惯例。
你自己写的实现逻辑完全正确:mapM本质就是「先对集合元素映射产生效应值,再将效应和集合的结构翻转」,而Cats的Traverse类型类正好把这个逻辑封装成了traverse方法。
直接使用Cats的traverse
Cats已经通过扩展方法,把traverse加到了所有实现Traverse的集合类型(比如List、Vector、Option等)上,你可以直接调用,甚至不需要自己封装:
import cats.Applicative import cats.Traverse import cats.implicits._ // 这就是你想要的等价实现,和你写的逻辑完全一致 def mapM[A, B, F[_]: Applicative, Col[_]: Traverse](col: Col[A])(f: A => F[B]): F[Col[B]] = col.traverse(f)
实际使用示例
比如用IO作为效应类型的场景:
import cats.effect.IO val numbers = List(1, 2, 3) // 等价于Haskell的mapM (\n -> return (n*2)) numbers val doubledIO: IO[List[Int]] = numbers.traverse(n => IO(n * 2))
为什么叫traverse而不是mapM?
Haskell的mapM是针对Monad的版本,但Cats的traverse放宽了约束到Applicative(和你定义的一样),这是更通用的设计——毕竟很多效应类型只需要Applicative就能完成这个操作,不需要全量的Monad能力。不过如果你需要严格对应Monad约束的版本,Cats也提供了traverseM方法,日常用traverse就足够覆盖绝大多数场景了。
内容的提问来源于stack exchange,提问作者Vitalii Honta
相关产品推荐
相关产品推荐

