// Again, no AST for python easily available class PythonLanguage extends LanguageAbstraction { type Term = String type Apply = String } // Still stringy, :fingerscrossed: implicit object pythonOptional extends MonadF[PythonLanguage, Option] { def map[First <: String, Func <: String, From, To](f: Phantom[Func, PythonLanguage, From => To])(fa: Phantom[First, PythonLanguage, Option[From]]) = Phantom[String, PythonLanguage, Option[To]](s"(lambda x: (${f.value})(x) if x is not None else x)(${fa.value})") def flatMap[First <: String, Func <: String, From, To](f: Phantom[Func, PythonLanguage, From => Option[To]])(fa: Phantom[First, PythonLanguage, Option[From]]) = Phantom[String, PythonLanguage, Option[To]](s"(lambda x: (${f.value})(x) if x is not None else x)(${fa.value})") } // Convenience method def liftPy[Z] = lift[PythonLanguage, Z] // Dataflow val fa = liftPy[Option[Int]]("5") val f = liftPy[Int => Option[Int]]("lambda a: a if a >= 0 else None") val f2 = liftPy[Int => Int]("lambda a: a + 1") println(fa.flatMap(f).map(f2).value) // Prints (lambda x: (lambda a: a + 1)(x) if x is not None else x)((lambda x: (lambda a: a if a >= 0 else None)(x) if x is not None else x)(5))