user2726995
user2726995

Reputation: 2062

Apply list of functions to value using Scala Cats

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

Answers (1)

Travis Brown
Travis Brown

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

Related Questions