Skip to content

Instantly share code, notes, and snippets.

@pshirshov
Last active October 13, 2017 00:11
Show Gist options
  • Save pshirshov/8cff9adf05d6879888c4889dd33d07d0 to your computer and use it in GitHub Desktop.
Save pshirshov/8cff9adf05d6879888c4889dd33d07d0 to your computer and use it in GitHub Desktop.
import com.typesafe.config.{Config, ConfigFactory}
import scala.language.{existentials, higherKinds, implicitConversions}
trait Monoid[T] {
def mapply(a: T, b: T): T
def mzero: T
}
trait Foldable[F[_]] {
protected type T
def ffold(f: F[T], initial: T, m: (T, T) => T): T
}
object FoldableOps {
private sealed trait Contracts[M] {
type IsTr_of_M[F[_]] = F[M] <:< Traversable[M]
type Fldb_of_M[F[_]] = Foldable[F] {type T = M}
}
implicit def FoldableTraversable[M, F[_] : Contracts[M]#IsTr_of_M]: Contracts[M]#Fldb_of_M[F] = new Foldable[F] {
override protected type T = M
override def ffold(f: F[T], initial: T, m: (T, T) => T) = {
implicitly[Contracts[T]#IsTr_of_M[F]].apply(f).fold[T](initial)(m)
}
}
implicit class FoldableOfMonoidsExt[M: Monoid, F[_] : Contracts[M]#Fldb_of_M](l: F[M]) {
private val m = implicitly[Monoid[M]]
def msum: M = {
implicitly[Contracts[M]#Fldb_of_M[F]].ffold(l, m.mzero, m.mapply)
}
}
}
object ConfigOps {
implicit object Monoid extends Monoid[Config] {
override def mapply(a: Config, b: Config): Config = a.withFallback(b)
override def mzero: Config = ConfigFactory.empty()
}
}
import ConfigOps._
import FoldableOps._
Seq(ConfigFactory.empty()).msum
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment