-
Notifications
You must be signed in to change notification settings - Fork 18
/
QuadraticRootsExample.scala
113 lines (100 loc) · 3.08 KB
/
QuadraticRootsExample.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import cats.implicits._
import treelog.LogTreeSyntaxWithoutAnnotations._
object QuadraticRootsExample extends App {
case class Parameters(a: Double, b: Double, c: Double)
// Roots are real
println("Success case:")
println(root(Parameters(2, 5, 3)).value.written.show)
/*
Extracting root
Calculating Numerator
Calculating Determinant
Calculating b^2
Got b: 5.0
Got b^2: 25.0
Calculating 4ac
Got a: 2.0
Got c: 3.0
Got 4ac: 24.0
Got b^2 - 4ac: 1.0
Calculating sqrt(determinant)
Determinant (1.0) is >= 0
Got sqrt(determinant): 1.0
Got b: 5.0
Got -b: -5.0
Got -b + sqrt(determinant): -4.0
Calculating Denominator
Got a: 2.0
Got 2a: 4.0
Got root = numerator / denominator: -1.0
*/
// Roots are complex
println("Failure case:")
println(root(Parameters(2, 5, 10)).value.written.show)
/*
Extracting root: Failed
Calculating Numerator: Failed
Calculating Determinant
Calculating b^2
Got b: 5.0
Got b^2: 25.0
Calculating 4ac
Got a: 2.0
Got c: 10.0
Got 4ac: 80.0
Got b^2 - 4ac: -55.0
Calculating sqrt(determinant): Failed
Determinant (-55.0) is < 0: Failed
*/
private def root(parameters: Parameters) =
"Extracting root" ~< {
for {
num <- numerator(parameters) ~> "Calculating Numerator"
den <- denominator(parameters) ~> "Calculating Denominator"
root <- (num / den) ~> ("Got root = numerator / denominator: " + _)
} yield root
}
private def numerator(parameters: Parameters) =
for {
det <- determinant(parameters)
sqrtDet <- sqrtDeterminant(det)
b <- parameters.b ~> ("Got b: " + _)
minusB <- -b ~> ("Got -b: " + _)
sum <- (minusB + sqrtDet) ~> ("Got -b + sqrt(determinant): " + _)
} yield sum
private def sqrtDeterminant(det: Double) =
"Calculating sqrt(determinant)" ~< {
for {
_ <- if (det >= 0) det ~> (d => s"Determinant ($d) is >= 0") else det ~>! (d => s"Determinant ($d) is < 0")
sqrtDet <- Math.sqrt(det) ~> ("Got sqrt(determinant): " + _)
} yield sqrtDet
}
private def denominator(parameters: Parameters) =
for {
a <- parameters.a ~> ("Got a: " + _)
twoA <- (2 * a) ~> ("Got 2a: " + _)
} yield twoA
private def determinant(parameters: Parameters) =
"Calculating Determinant" ~< {
for {
bSquared <- bSquared(parameters)
fourac <- fourac(parameters)
determinant <- (bSquared - fourac) ~> ("Got b^2 - 4ac: " + _)
} yield determinant
}
private def bSquared(parameters: Parameters) =
"Calculating b^2" ~< {
for {
b <- parameters.b ~> ("Got b: " + _)
bSquared <- (b * b) ~> ("Got b^2: " + _)
} yield bSquared
}
private def fourac(parameters: Parameters) =
"Calculating 4ac" ~< {
for {
a <- parameters.a ~> ("Got a: " + _)
c <- parameters.c ~> ("Got c: " + _)
fourac <- (4 * a * c) ~> ("Got 4ac: " + _)
} yield fourac
}
}