Pregunta

He estado jugando con Scalaz para tener un poco de la sensación de Haskell en Scala. Para comprender cómo funcionan las cosas en Scala, comencé a implementar varias estructuras algebraicas yo mismo y encontré un comportamiento que ha mencionado la gente de Scalaz.

Aquí está mi código de ejemplo que implementa un functor:

trait Functor[M[_]] {
  def fmap[A, B](a: M[A], b: A => B): M[B]
}

sealed abstract class Foo[+A]
case class Bar[A]() extends Foo[A]
case class Baz[A]() extends Foo[A]

object Functor {

  implicit val optionFunctor: Functor[Option] = new Functor[Option]{
    def fmap[A, B](a: Option[A], b: A => B): Option[B] = a match {
      case Some(x) => Some(b(x))
      case None => None
    }   
  }

  implicit val fooFunctor: Functor[Foo] = new Functor[Foo] {
    def fmap[A, B](a: Foo[A], b: A => B): Foo[B] = a match {
      case Bar() => Bar()
      case Baz() => Baz()
    }   
  }
}

object Main {
  import Functor._

  def some[A](a: A): Option[A] = Some(a)
  def none[A]: Option[A] = None

    def fmap[M[_], A, B](a: M[A])(b: A => B)(implicit f: Functor[M]): M[B] =
      f.fmap(a, b)

  def main(args: Array[String]): Unit = { 
    println(fmap (some(1))(_ + 1)) 
    println(fmap (none)((_: Int) + 1)) 
    println(fmap (Bar(): Foo[Int])((_: Int) + 1))                                                    
  }
}

Escribí una instancia de functores para la opción y un falso Sumtype Foo. El problema es que Scala no puede inferir el parámetro implícito sin una anotación de tipo explícito o un método de envoltura

def some[A](a: A): Option[A] = Some(a)

println(fmap (Bar(): Foo[Int])((_: Int) + 1))

Scala infiere tipos como functor [bar] y functor [algunos] sin esas soluciones.

¿Porqué es eso? ¿Alguien podría señalarme la sección en la especificación del idioma que define este comportamiento?

Saludos, Raichoo

No hay solución correcta

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top