Skip to content

Instantly share code, notes, and snippets.

@aaronlevin
Created April 3, 2017 20:20
Show Gist options
  • Save aaronlevin/740982d02121990e2450dc1c8f17753d to your computer and use it in GitHub Desktop.
Save aaronlevin/740982d02121990e2450dc1c8f17753d to your computer and use it in GitHub Desktop.
When trying to compile this with Scala 2.12.1 I got a NullPointerException
☭ scala foo.scala
cat: /release: No such file or directory
java.lang.NullPointerException
at Main$Monad.<init>(foo.scala:29)
at Main$$anon$1.<init>(foo.scala:58)
at Main$.<init>(foo.scala:58)
at Main$.<clinit>(foo.scala)
at Main.main(foo.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at scala.reflect.internal.util.ScalaClassLoader.$anonfun$run$2(ScalaClassLoader.scala:98)
at scala.reflect.internal.util.ScalaClassLoader.asContext(ScalaClassLoader.scala:32)
at scala.reflect.internal.util.ScalaClassLoader.asContext$(ScalaClassLoader.scala:30)
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:129)
at scala.reflect.internal.util.ScalaClassLoader.run(ScalaClassLoader.scala:98)
at scala.reflect.internal.util.ScalaClassLoader.run$(ScalaClassLoader.scala:90)
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:129)
at scala.tools.nsc.CommonRunner.run(ObjectRunner.scala:22)
at scala.tools.nsc.CommonRunner.run$(ObjectRunner.scala:21)
at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:39)
at scala.tools.nsc.CommonRunner.runAndCatch(ObjectRunner.scala:29)
at scala.tools.nsc.CommonRunner.runAndCatch$(ObjectRunner.scala:28)
at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:39)
at scala.tools.nsc.ScriptRunner.runCompiled(ScriptRunner.scala:170)
at scala.tools.nsc.ScriptRunner.$anonfun$runScript$1(ScriptRunner.scala:187)
at scala.tools.nsc.ScriptRunner.$anonfun$runScript$1$adapted(ScriptRunner.scala:187)
at scala.tools.nsc.ScriptRunner.$anonfun$withCompiledScript$2(ScriptRunner.scala:156)
at scala.tools.nsc.ScriptRunner.runScript(ScriptRunner.scala:124)
at scala.tools.nsc.ScriptRunner.runScriptAndCatch(ScriptRunner.scala:200)
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:63)
at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:88)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:99)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:104)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
import scala.language.higherKinds
object jazz {
trait Functor[F[_]] {
def map[A,B](value: F[A])(func: A => B): F[B]
}
abstract class Applicative[F[_]](implicit val functor: Functor[F]) extends Functor[F] {
def pure[A](a: A): F[A]
def ap[A,B](value: F[A])(func: F[A => B]): F[B]
def map[A,B](value: F[A])(func: A => B): F[B] = functor.map[A,B](value)(func)
}
abstract class Monad[F[_]](implicit val applicative: Applicative[F]) extends Applicative[F]()(applicative.functor) {
def flatMap[A,B](value: F[A])(func: A => F[B]): F[B]
def pure[A](a: A): F[A] = applicative.pure[A](a)
def ap[A,B](value: F[A])(func: F[A => B]): F[B] = applicative.ap[A,B](value)(func)
}
implicit val optionFunctor: Functor[Option] = new Functor[Option] {
def map[A,B](value: Option[A])(func: A => B): Option[B] = {
value match {
case None => None
case Some(a) => Some(func(a))
}
}
}
implicit val optionApplicative: Applicative[Option] = new Applicative[Option] {
def pure[A](a: A): Option[A] = Some(a)
def ap[A,B](value: Option[A])(func: Option[A => B]): Option[B] = {
func match {
case None => None
case Some(f) => functor.map(value)(f)
}
}
}
/**
* This will compile fine if instead we use:
* implicit val optionMonad: Monad[Option] = new Monad[Option]()(optionApplicative) {
*/
implicit val optionMonad: Monad[Option] = new Monad[Option] {
def flatMap[A,B](value: Option[A])(func: A => Option[B]): Option[B] = {
value match {
case None => None
case Some(a) => func(a)
}
}
}
def main(args: Array[String]): Unit = {
println("hello, friend")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment