eirirlar
eirirlar

Reputation: 812

Cats instances for Some and None et al

In Scala 2.13 and Cats, the following works fine:

import cats.implicits._
Traverse[Option]

However the following fails:

import cats.implicits._
Traverse[Some]

I would like for the latter to work, not only for Traverse of Option subclasses, but for any type that has a parent that there exists a given typeclass for.

I have tried creating a method with implicit proof <:< but can't quite get it to work.

Upvotes: 0

Views: 368

Answers (1)

Dmytro Mitin
Dmytro Mitin

Reputation: 51723

If you really understand what you do you can define necessary instance manually (when it exists).

Some is isomorphic to Id.

implicit val someTraverse: Traverse[Some] = new Traverse[Some] {
  override def traverse[G[_]: Applicative, A, B](fa: Some[A])(f: A => G[B]): G[Some[B]] = f(fa.value).map(Some(_))
  override def foldLeft[A, B](fa: Some[A], b: B)(f: (B, A) => B): B = f(b, fa.value)
  override def foldRight[A, B](fa: Some[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = f(fa.value, lb)
}

Generally this is not possible. If F is a functor and G[T] <: F[T] for all T then G is not necessarily a functor.

Calling generic function with Functor using subclass (cats/scalaz)

Also sometimes you can derive type classes using kittens.

Why can find `Functor` instance for Tree but not for Branch or Leaf?

Upvotes: 2

Related Questions