dcastro
dcastro

Reputation: 68640

Using functions as applicative functors/cartesians

I'm using the cats lib for this.

It's easy enough to combine two lists using their applicative functor instance (or Cartesian, to be precise):

import cats._
import cats.implicits._

(List(23, 4), List(55, 56)).mapN(_ + _)
>> List(78, 79, 59, 60)

However, I can't seem to be able to do the same with two functions:

val strLength: String => Int = _.length

(strLength, strLength).mapN(_ + _)
>> value mapN is not a member of (String => Int, String => Int)

It does work if I do some of the implicit conversions explicitly, and if I create a type alias to give the compiler a hand:

type F[A] = Function1[String, A]
val doubleStrLength = catsSyntaxTuple2Cartesian[F, Int, Int]((strLength, strLength)).mapN(_ + _)

doubleStrLength("hello")
>> 10

Is there an easier way to do this? Seems excessively verbose

Edit: I create a worksheet here if you wanna play with it: https://scastie.scala-lang.org/dcastro/QhnD8gwEQEyfnr14g34d9g/2

Upvotes: 8

Views: 164

Answers (1)

Luka Jacobowitz
Luka Jacobowitz

Reputation: 23502

This only works if you have partial-unification enabled. The easiest way to do so, is to add the sbt-partial-unification plugin.

If you're on Scala 2.11.9 or newer, you can also simply add the compiler flag:

scalacOptions += "-Ypartial-unification"

Upvotes: 6

Related Questions