Skip to content

Instantly share code, notes, and snippets.

@icsaba
Last active April 14, 2019 09:56
Show Gist options
  • Save icsaba/ca7865d9582f4470cf2a3db8e626537f to your computer and use it in GitHub Desktop.
Save icsaba/ca7865d9582f4470cf2a3db8e626537f to your computer and use it in GitHub Desktop.
Examples for functional programming in Scala to demonstrate haskell codes that's been learnt on the Unversity.
object SealedExample extends App {
sealed trait Expression
final case class Atom(v: Int) extends Expression
final case class Mul(l: Expression, r: Expression) extends Expression
final case class Add(l: Expression, r: Expression) extends Expression
val el = Add(Atom(10), Atom(12))
def evalExpression(e: Expression): Int = e match {
case Atom(value) => value
case Add(l, r) => evalExpression(l) + evalExpression(r)
case Mul(l, r) => evalExpression(l) - evalExpression(r)
}
println(el)
println(evalExpression(el))
}
import scalaz.Functor
object FunctorExample extends App{
implicit val optionFunctor: Functor[Option] = new Functor[Option] {
override def map[A, B](fa: Option[A])(f: A => B): Option[B] = fa match {
case None => None
case _ => Some(f (fa.get))
}
}
val len: String => Int = _.length
val resultOfSome = Functor[Option].map(Some("adsf"))(len)
val resultOfNone = Functor[Option].map(None)(len)
println(s"resultOfSome = $resultOfSome")
println(s"resultOfNone = $resultOfNone")
}
object MonoidExample extends App{
trait Monoid[A] {
def mappend(a1: A, a2: A): A
def mempty: A
}
object Monoid {
implicit val IntMonoid: Monoid[Int] = new Monoid[Int] {
def mappend(a: Int, b: Int): Int = a + b
def mempty: Int = 0
}
implicit val StringMonoid: Monoid[String] = new Monoid[String] {
def mappend(a: String, b: String): String = a + b
def mempty: String = ""
}
}
def sum[A: Monoid](xs: List[A]): A = {
val m = implicitly[Monoid[A]]
xs.foldLeft(m.mempty)(m.mappend)
}
println(sum(List("a", "b", "c")))
}
import scalaz.Monoid
object MonoidExample extends App{
implicit object WordsMonoid extends Monoid[Words] {
def zero: Words = Words("")
def append(v1: Words, v2: => Words): Words = Words(v1.letters + v2.letters)
}
case class Words(letters: String)
def sum[A: Monoid](xs: List[A]): A = {
val m = implicitly[Monoid[A]]
xs.foldLeft(m.zero)( (a,b) => m.append(a,b))
}
print(sum(List(Words("Hello"), Words(" World"))))
}
import Main.{addNat, one, two}
abstract class Nat {
def isZero: Boolean
def predecessor: Nat
def successor = new Succ(this)
def + (that: Nat): Nat
def - (that: Nat): Nat
}
object Zero extends Nat {
def isZero = true
def predecessor: Nat = throw new Exception("no predecessor")
def + (that: Nat): Nat = that
def - (that: Nat): Nat =
if (that == Zero) this
else throw new Exception("zero minus is not possible")
override def toString = "0"
}
class Succ(n: Nat) extends Nat{
def isZero = false
def predecessor: Nat = n
def - (that:Nat): Nat =
if (that == Zero) this
else this.predecessor - that.predecessor
def + (that:Nat): Nat =
if (that == Zero) this
else this.successor + that.predecessor
override def toString: String = "1+" ++ this.predecessor.toString
}
object ExampleForPatternMatching extends App{
val one: Nat = new Succ(Zero)
val two: Nat = new Succ(new Succ(Zero))
val two_2 : Nat = new Succ(one)
val four : Nat = two + two
println("Examples: ")
println(one)
println(two)
println(two_2)
println("+ operator")
println(four)
println()
// in haskell:
// addNat :: Nat -> Nat -> Nat
// addNat Zero n = n
// addNat n Zero = n
// addNat (Suc n) m = Suc (n `addNat` m)
def addNat( p: (Nat, Nat)) : Nat = p match {
case (Zero, b: Nat) => b
case (a: Nat, Zero) => a
case (a: Nat, b: Nat) => a.successor + b.predecessor
}
def subNat( p: (Nat, Nat)) : Nat = p match {
case (Zero, b: Nat) => throw new Exception("Ajjaj")
case (a: Nat, Zero) => a
case (a: Nat, b: Nat) => a.predecessor - b.predecessor
}
def subNatOption( p: (Nat, Nat)) : Option[Nat] = p match {
case (Zero, b: Nat) => None
case (a: Nat, Zero) => Some(a)
case (a: Nat, b: Nat) => Some(a.predecessor - b.predecessor)
}
println("+ operator with pattern matching")
println(addNat(one, two))
println("+ operator with pattern matching")
println(addNat(Zero, two))
println("- operator with pattern matching")
println(subNat(two, two))
println(" 0 - 2?")
println(subNatOption(Zero, two))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment