Reputation: 2062
in haskell I could do the following to a string
let f = sequence [id, reverse]
f "test"
I am at a bit of a loss how to approach this in a better method using Cats. I currently have something like
val f = List(fun1,fun2)
val data = "test"
f map {fun => fun(data)}
Is there an implementations of Sequence or SequenceU that can accomplish this using Cats?
Upvotes: 4
Views: 313
Reputation: 139058
It's more or less exactly the same, except that the syntax is a little different, you need some extra imports, and the generic version isn't as convenient since Scala's String
isn't just an alias for a list of characters:
import cats.instances.function._, cats.instances.list._, cats.syntax.traverse._
val funcs: List[String => String] = List(identity, _.reverse)
val f = funcs.sequenceU
In Haskell sequence
requires a Traversable
instance for the outer type constructor of its argument, and a Monad
instance for the inner type constructor. Cats's sequence
is almost the same—Traversable
is called Traverse
(because the name Traversable
is already taken by the standard library), and it requires an Applicative
instance instead of Monad
(which is a more accurate constraint—Haskell's sequence
only requires a monad instance for historical reasons).
If you wanted you could just import cats.implicits._
, but that brings in a lot of other stuff. The imports above provide the minimal type class instances and syntactic extensions you need.
You can use f
, which is a String => List[String]
, like this:
scala> f("test")
res0: List[String] = List(test, tset)
Note that if you're on 2.12.1 and have the -Ypartial-unification
compiler flag enabled, you can just write .sequence
, not .sequenceU
. Why you need the U
on earlier Scala versions is a long story—see my blog post here for an explanation.
Upvotes: 5