0
import cats.{Functor, Monoid}

trait Fold[I, O] {
  type M

  def m: Monoid[M]

  def tally: I => M

  def summarize: M => O
}

object Fold {
  def apply[I, O, _M](_m: Monoid[_M])(_tally: I => _M, _summarize: _M => O): Fold[I, O] = new Fold[I, O] {
    override type M = _M

    override def m = _m

    override def tally = _tally

    override def summarize = _summarize
  }
}

object BeautifulFold  extends App {
  def fold[I, O](input: Seq[I])(f: Fold[I, O]): O =
    f.summarize(input.foldLeft(f.m.empty)((x, y) => f.m.combine(x, f.tally(y))))

  def sum[M](implicit ev: Monoid[M]): Fold[M, M] = Fold.apply(ev)(identity, identity)

  implicit def foldFunctor[I] = new Functor[({type F[X] = Fold[I, X]})#F] {
    override def map[A, B](fa: Fold[I, A])(f: A => B): Fold[I, B] =
      Fold(fa.m)(fa.tally, fa.summarize.andThen(f))
  }

  import cats.implicits._

  fold(List(1,2,3))(sum)

  fold(List(1,2,3))((sum[Int]:Fold[Int,Int]).map(s => s"Sum is $s"))
}

works perfectly in REPL :paste mode but it throws an error,

[error] value map is not a member of Fold[Int,Int]
[error]   fold(List(1,2,3))((sum[Int]:Fold[Int,Int]).map(s => s"Sum is $s"))

during sbt compile. SBT version is 1.1.0

The partial settings for build.sbt are,

scalaVersion := "2.12.4"
val catsVer = "1.1.0"

scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature", "-Xlog-implicits", "-Ypartial-unification")

libraryDependencies in ThisBuild ++= Seq(
  "org.typelevel" %% "cats-core" % catsVer,
  "org.typelevel" %% "cats-macros" % catsVer,
  "org.typelevel" %% "cats-kernel" % catsVer,
  "org.typelevel" %% "cats-free" % catsVer,
  ...

What is wrong with my compilation setting? Thanks.

Update 1

There is nothing wrong with this code snippet. What I did wrong was I didn't include -Ypartial-unification to scalacOptions in my actual project like I did here. And there is also another thing, please refer to the answer.

Community
  • 1
  • 1
thlim
  • 2,908
  • 3
  • 34
  • 57

1 Answers1

1

It is important to include -Ypartial-unification option to scalacOptions, as mentioned in Cats README file. It is also important how it is done if you have a multi modules project. The option should be added to modules that require this option. If it is preferable to be a global option, please put it in the common settings list, as in,

lazy val commonSettings = Seq(
  organization := "org.teckhooi",
  version := "1.0-SNAPSHOT",
  publishArtifact in (Compile, packageDoc) := false,
  publishArtifact in packageDoc := false,
  sources in(Compile, doc) := Seq.empty,
  logLevel := util.Level.Info,
  scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature", "-Xlog-implicits", "-Ypartial-unification")
)

lazy val root = project aggregate(foo, bar)

lazy val foo = project.settings(commonSettings)

lazy val bar = project.settings(commonSettings)

)

thlim
  • 2,908
  • 3
  • 34
  • 57