-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathMonads.scala
55 lines (39 loc) · 1.21 KB
/
Monads.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// resource fot this video: https://www.youtube.com/watch?v=I2iaaKU1mDg
type RegularFunction[A, B ] = A => B
def ac[A, B, C](
ab: A => B,
bc: B => C): A => C = a =>
val b = ab(a)
val c = bc(b)
c
type SpecialFunction[A, B, D[_]] = A => D[B]
trait Monad[D[_]]:
def flatMap[B, C](db: D[B])(bdc: B => D[C]): D[C]
def adc[A, B, C, D[_]](
adb: A => D[B],
bdc: B => D[C])(using monad: Monad[D]): A => D[C] = a =>
val db = adb(a)
val dc = monad.flatMap(db)(bdc)
dc
type A = String
type B = Int
type C = Adult
type D[+E] = Option[E]
def parseString(a: A): D[B] =
a.toIntOption
case class Adult(age: B)
def keepAdults(b: B): D[C] =
if b >= 18 then Some(Adult(b)) else None
given Monad[D] with
def flatMap[B, C](db: D[B])(bdc: B => D[C]): D[C] =
db match
case Some(b) => bdc(b)
case None => None
val parseStringAndThenKeepAdults: A => D[C] =
adc(parseString, keepAdults) // (using summon[Monad[D]])
object Monads extends App:
println("─" * 50)
println(parseStringAndThenKeepAdults("18")) // Some(Adult(18))
println(parseStringAndThenKeepAdults("17")) // None
println(parseStringAndThenKeepAdults("not Int"))// None
println("─" * 50)