Last active
August 29, 2015 14:09
-
-
Save erikkaplun/38aa55484d6712e47190 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import scala.annotation.implicitNotFound | |
object DemoWithNaiveSupertype extends App { | |
trait Addable { | |
def +(other: Addable): Addable | |
} | |
case class Foo(x: Int) extends Addable { | |
def +(other: Addable) = Foo(x + other.asInstanceOf[Foo].x) | |
} | |
case class Bar(x: Int) extends Addable { | |
def +(other: Addable) = Bar(x + other.asInstanceOf[Bar].x) | |
} | |
def doAdd(a: Addable, b: Addable) = println(a + b) | |
doAdd(Foo(1), Foo(2)) | |
doAdd(Bar(1), Bar(2)) | |
doAdd(Bar(1), Foo(2)) // runtime error | |
} | |
object DemoWithParametrizedSupertype extends App { | |
trait Addable[T] { self: T => | |
def +(other: T): T | |
} | |
// ei kompileeruks `self: T =>` nõude tõttu: | |
// class B | |
// class A extends Addable[B] | |
case class Foo(x: Int) extends Addable[Foo] { | |
def +(other: Foo) = Foo(x + other.x) | |
} | |
case class Bar(x: Int) extends Addable[Bar] { | |
def +(other: Bar) = Bar(x + other.x) | |
} | |
def doAdd[T <: Addable[T]](a: T, b: T) = | |
println(a + b) | |
doAdd(Foo(1), Foo(2)) | |
doAdd(Bar(1), Bar(2)) | |
// doAdd(Bar(1), Foo(2)) | |
} | |
object DemoWithTypeClass extends App { | |
case class Foo(x: Int) | |
case class Bar(x: Int) | |
case class Baz(x: String) | |
@implicitNotFound("Don't know how to add values of type ${T}") | |
trait HowToAdd[T] { def plus(a: T, b: T): T } | |
implicit val howToAddFoo = new HowToAdd[Foo] { | |
def plus(a: Foo, b: Foo) = Foo(a.x + b.x) | |
} | |
implicit val howToAddBar = new HowToAdd[Bar] { | |
def plus(a: Bar, b: Bar) = Bar(a.x + b.x) | |
} | |
// implicit val howToAddBaz = new HowToAdd[Baz] { | |
// def plus(a: Baz, b: Baz) = Baz(a.x + " " + b.x) | |
// } | |
def doAdd[T](a: T, b: T)(implicit num: HowToAdd[T]): T = | |
num.plus(a, b) | |
val a = doAdd(Foo(1), Foo(2)) | |
val b = doAdd(Bar(1), Bar(2)) | |
// doAdd(Baz("Hello"), Baz("World!")) | |
/****************************/ | |
// implicit class NumericOps[T](x: T)(implicit num: Addable[T]) { | |
// def +(other: T) = num.plus(x, other) | |
// } | |
// Baz("Hello") + Baz("World!") | |
} | |
object TypedValidationDemo extends App { | |
sealed trait AgeCategory | |
case object Infant extends AgeCategory | |
case object Toddler extends AgeCategory | |
case object Teen extends AgeCategory | |
case object Adult extends AgeCategory | |
// constructor on private -- väljastpoolt luua ei saa; ainult juurdekäivast companion object'ist | |
case class Age private(n: Int) | |
object Age { | |
def validAge(n: Int) = 0 <= n && n <= 100 | |
def wrap(n: Int): Option[Age] = if (validAge(n)) Some(Age(n)) else None | |
def unwrap(age: Age) = age.n | |
} | |
def ageGroup(age: Age) = { | |
Age.unwrap(age) match { | |
case n if 0 <= n && n <= 2 => Infant | |
case n if n <= 5 => Toddler | |
case n if n <= 18 => Teen | |
case n if n >= 18 && n <= 100 => Adult | |
} | |
} | |
val inputAge: Int = 101 // user input | |
val age = Age.wrap(inputAge) | |
val category = age.map(ageGroup) | |
println(category) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import print_function | |
# vt. http://en.wikipedia.org/wiki/Algebraic_data_type | |
def Option(x): | |
"""Helper x/None väärtuste konvertimiseks Some(x)/Null'iks""" | |
return Null if x is None else Some(x) | |
class Some(object): | |
def __init__(self, x): | |
self.x = x | |
def __iter__(self): | |
return iter([self.x]) | |
# def map(self, fn): | |
# return Some(fn(self.x)) | |
def __str__(self): return "Some(%s)" % self.x | |
class Null(object): | |
def __iter__(self): | |
return iter([]) | |
# def map(self, fn): | |
# return Null | |
def __str__(self): | |
return "Null" | |
Null = Null() | |
def main(): | |
print(map(lambda x: x * 2, Some(4))) # => list | |
# print(Some(4).map(lambda x: x * 2)) # => Option | |
# sitt validator | |
# def vali_age(n): | |
# return n if 0 <= n <= 100 else None | |
# hea validator | |
def vali_age(n): | |
return Some(n) if 0 <= n <= 100 else Null | |
def calc_age_group(n): | |
return 'adult' | |
input_age = 123 # int(raw_input()) | |
age = vali_age(input_age) | |
age_group = map(calc_age_group, age) # => list | |
# age_group = age.map(calc_age_group) # => Option | |
print(age_group) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import print_function | |
HOW_TO_ADD = {} | |
class Foo(object): | |
def __init__(self, x): | |
self.x = x | |
def __str__(self): | |
return "Foo(%s)" % self.x | |
class Bar(object): | |
def __init__(self, x): | |
self.x = x | |
def __str__(self): | |
return "Bar(%s)" % self.x | |
class Baz(object): | |
def __init__(self, x): | |
self.x = x | |
def __str__(self): | |
return "Baz(%s)" % self.x | |
def do_add(a, b): | |
assert type(a) == type(b) | |
try: | |
adder = HOW_TO_ADD[type(a)] | |
except KeyError: | |
raise Exception("don't know how to add values of type %s" % type(a).__name__) | |
return adder(a, b) | |
HOW_TO_ADD[Foo] = lambda a, b: Foo(a.x + b.x) | |
HOW_TO_ADD[Bar] = lambda a, b: Bar(a.x + b.x) | |
HOW_TO_ADD[Baz] = lambda a, b: Baz(a.x + b.x) | |
print(do_add(Foo(1), Foo(2))) | |
print(do_add(Bar(1), Bar(2))) | |
print(do_add(Baz(1), Bar(2))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment