Last active
November 28, 2019 12:32
-
-
Save kryptt/608225304ac575c09288433170622f60 to your computer and use it in GitHub Desktop.
no ifs profit
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
/* | |
* This file has the setup and boilerplate. | |
* how to calculate the pay for a teacher, and the fee for a student. | |
* how to find the student or teacher just from a name string, and a | |
* `List` of names. | |
*/ | |
type Fee = Double | |
type Pay = Double | |
type Balance = Double | |
sealed trait Person | |
case class Student(name: String, teacher: Teacher) extends Person | |
case class Teacher(name: String, students: List[Person]) extends Person | |
def feeCalc: Student => Fee = _ match { | |
case Student(_, t) => 1.10 * payCalc(t) / t.students.length | |
} | |
def payCalc: Teacher => Pay = _.students.foldLeft(0.0){ | |
case (pay, t:Teacher) => pay + 0.1 * payCalc(t) | |
case (pay, s:Student) => pay + 2.5 | |
} | |
def feeBalance: Fee => Balance = identity | |
def payBalance: Pay => Balance = - _ | |
//Not worrying about the data itself | |
val names: List[String] = List.empty | |
def findPerson(name: String): Option[Either[Student, Teacher]] = None |
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
/* | |
* Lets write down some intermediate helpper functions; | |
* the information from the signatures (types) of these intermediate functions helps | |
* document the expected flow | |
*/ | |
def calc: Either[Student, Teacher] => Either[Fee, Pay] = | |
feeCalc.choose(payCalc) | |
def balance: Either[Fee, Pay] => Balance = | |
feeBalance.choice(payBalance) | |
def calcBalance: Either[Student, Teacher] => Balance = | |
calc.andThen(balance) | |
def nameBalance: String => Option[Balance] = | |
findPerson(_).map(calcBalance) | |
// ------------- // | |
names.foldMap(nameBalance(_).orEmpty) | |
// res: Balance = 0.0 | |
// ------------- // | |
/* this is how it would look like if we avoided the helpers */ | |
names.foldMap( | |
findPerson(_).map( | |
feeCalc.choose(payCalc).andThen(feeBalance.choice(payBalance)) | |
).orEmpty | |
) | |
// res: Balance = 0.0 | |
// ------------- // |
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
/* | |
* Lets write down some intermediate helpper functions; | |
* the information from the signatures (types) of these intermediate functions helps | |
* document the expected flow | |
*/ | |
def calc: Either[Student, Teacher] => Either[Fee, Pay] = | |
feeCalc choose payCalc | |
def balance: Either[Fee, Pay] => Balance = | |
feeBalance choice payBalance | |
// ------------- // | |
names | |
.flatMap(findPerson) | |
.map(calc) | |
.foldMap(balance) | |
// res: Balance = 0.0 | |
// ------------- // | |
/* this is how it would look like if we avoided the helpers */ | |
names | |
.flatMap(findPerson) | |
.map(feeCalc.choose(payCalc)) | |
.foldMap(feeBalance.choice(payBalance)) | |
// res: Balance = 0.0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A nice little note is that the merged functions iterates through the array only once, and releases the garbage it generates quicker...