0

I wrote this code

import cats.Cartesian
import cats.instances.option._
val x = Some(1)
val y = Some(2)
Cartesian[Option].product(x, y)

This gave me Some((1, 2)). Good!

So I tried again

import cats.Cartesian
import cats.instances.either._
val x : Either[String, Int] = Right(1)
val y : Either[String, Int] = Right(2)
Cartesian[Either].product(x, y)

Now I get an error

cmd11.sc:1: Either takes two type parameters, expected: one
val res11 = Cartesian[Either].product(x, y) 

Why didn't I get Right((1, 2))

Knows Not Much
  • 30,395
  • 60
  • 197
  • 373

3 Answers3

3

Either is not Cartesian. Either[A, ?] (with one type arg given) is. The simple answer is as you stated already:

type MyEither[A] = Either[String, A]
val x: MyEither[Int] = Right(10)
val y: MyEither[Int] = Right(20)
Cartesian[MyEither].product(x, y)
res0: MyEither[(Int, Int)] = Right((10, 20))

You can also use a type lambda

// A type-lambda. Scala doesn't have a nice syntax for this but it's
// analogous to a function { a => { b => either(a,b) } }.
// Variance optional
type CurriedEither[+A] = { type l[+B] = Either[A, B] }
Cartesian[CurriedEither[String]#l].product(x, y)
// Can also inline
// This is a standard approach for one-off situations
Cartesian[{type l[B] = Either[String, B]}#l].product(x, y)

If you have the kind-projector plugin you can write

Cartesian[Either[String, ?]].product(x, y)

Basically, it gives a nice syntax for lambdas.

HTNW
  • 27,182
  • 1
  • 32
  • 60
2

I found the answer

type MyEither[A] = Either[String, A]
val x : MyEither[Int] = Right(10)
val y : MyEither[Int] = Right(20)
Cartesian[MyEither].product(x, y)
res19: MyEither[(Int, Int)] = Right((10, 20))
Knows Not Much
  • 30,395
  • 60
  • 197
  • 373
1

Bit of a hack, but you can also use a structural type to accomplish this in a slightly shorter way:

Cartesian[({type L[A] = Either[String, A]})#L].product(x, y)

Edit: in the future, looks like Dotty will eventually bring partial type application so you could just do Cartesian[Either[String, _]]: http://dotty.epfl.ch/docs/internals/higher-kinded-v2.html

Joe K
  • 18,204
  • 2
  • 36
  • 58