Functor Instance for Type Constructor with Two Parameters in Scala

前端 未结 2 1954
悲哀的现实
悲哀的现实 2021-01-03 00:48

I have a class Foo with two parameters, and I am trying to write a Functor instance for Foo with the first parameter fixed, as follows:

object S         


        
2条回答
  •  心在旅途
    2021-01-03 01:09

    but inspection of their source code reveals an odd ?, which doesn't compile for me

    ? comes from the kind-projector project, which is a Scala compiler plugin you need to add to your build.sbt:

    resolvers += Resolver.sonatypeRepo("releases")
    
    addCompilerPlugin("org.spire-math" %% "kind-projector" % "0.9.4")
    

    Which prettifies the creation of type lambdas for you:

    implicit def fooInstances[X]: Functor[Foo[X, ?]] =
      new Functor[Foo[X, ?]] {
        def fmap[A, B](f: A => B): Foo[X, A] => Foo[X, B] =
          foo => Foo[X, B](f(foo.value))
    }
    

    Remember that we can also use partial type application with type aliases:

    implicit def fooInstances[X] = {
      type PartiallyAppliedFoo[A] = Foo[X, A]
      new Functor[PartiallyAppliedFoo] {
        override def fmap[A, B](f: (A) => B): (PartiallyAppliedFoo[A]) => PartiallyAppliedFoo[B] = foo => Foo[X, B](f(foo.value))
      }
    }
    

    Edit (05/04/2020)

    Note the syntax for kind project has changed from ? to * for partially applied types, thus the above example should be:

    sbt:

    resolvers += Resolver.sonatypeRepo("releases")
    
    addCompilerPlugin("org.spire-math" %% "kind-projector" % "0.11.0")
    

    Code:

    implicit def fooInstances[X]: Functor[Foo[X, *]] =
      new Functor[Foo[X, *]] {
        def fmap[A, B](f: A => B): Foo[X, A] => Foo[X, B] =
          foo => Foo[X, B](f(foo.value))
    }
    

提交回复
热议问题