Skip to content

Instantly share code, notes, and snippets.

@terjokhin
Created July 26, 2017 07:46
Show Gist options
  • Save terjokhin/3747ff9a6f7a5883446012af24bb7a02 to your computer and use it in GitHub Desktop.
Save terjokhin/3747ff9a6f7a5883446012af24bb7a02 to your computer and use it in GitHub Desktop.
Generalizing over forEach operation. Smells bad. Works hard.
object ForEachExperiment extends App {
trait ForEach[M[_]] {
def foreach[V](m: M[V])(f: V => Unit ): Unit
}
object ForEachInstances {
implicit val optionForEach: ForEach[Option] = new ForEach[Option] {
override def foreach[V](m: Option[V])(f: (V) => Unit): Unit = m.foreach(f)
}
implicit val optionForList: ForEach[List] = new ForEach[List] {
override def foreach[V](m: List[V])(f: (V) => Unit): Unit = m.foreach(f)
}
}
object ForEach {
def foreach[V, M[V]](container: M[V], f: V => Unit )(implicit impl: ForEach[M]): Unit = impl.foreach(container)(f)
}
object ForEachSyntax {
implicit class ForEachOps[V, M[V]](opt: M[V]) {
def generalForeach(f: V => Unit)(implicit impl: ForEach[M]): Unit = ForEach.foreach(opt, f)
}
}
import ForEachInstances._
import ForEachSyntax._
val opt1: Option[Int] = Some(123)
val opt2: Option[Int] = None
val list1: List[Int] = Nil
val list2: List[Int] = 1 :: 2 :: Nil
opt1.generalForeach(v => println(s"opt1 is : $v"))
opt2.generalForeach(v => println(s"opt2 is : $v"))
list1.generalForeach(v => println(s"list1 is : $v"))
list2.generalForeach(v => println(s"list2 is : $v"))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment