-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathlecture9.fs
More file actions
176 lines (137 loc) · 5.46 KB
/
Copy pathlecture9.fs
File metadata and controls
176 lines (137 loc) · 5.46 KB
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
(*
Lecture Nov 4, 2015: Combining behaviour with data.
Unit testing with FsUnit and NUnit.
Based on chapter 9 of RWFP.
The unit testing part is in chapter 11, but the code
here has been updated to support FsUnit and NUnit.
If tests fail to run in Visual studio/Windows (FsUnit dll related error messages) then check that
your Help -> About Visual Studio shows that you have installed update 4 to VS2013 and appropriate
.Net framework updates. It is encouraged to test it in VS2015.
In MonoDevelop it is possible to get FsUnit 1.4.0.0 with NUnit to work
by changing the target .Net framework to version 4.5, otherwise installing FsUnit from NuGet will
fail with incompatible framework error.
*)
module lecture9
//namespace Lecture9
type Rect =
{ Left : float32
Top : float32
Width : float32
Height : float32
}
member this.Deflate (vspace, hspace) =
{Left = this.Left + vspace
Top = this.Top + hspace
Width = this.Width - (2.0f * vspace)
Height = this.Height - (2.0f * hspace) }
member this.Area() =
this.Width * this.Height
let r = {Left=0.0f; Top=0.0f; Width=100.0f; Height=200.0f}
r.Area ()
// from lecture 8
type Client =
{ Name : string; Income : int ; YearsInJob : int
UsesCreditCard : bool; CriminalRecord : bool }
type QueryInfo =
{ Title : string
Check : Client -> bool
Positive : Decision
Negative : Decision }
and Decision =
| Result of string
| Query of QueryInfo
let rec tree =
Query {Title = "More than €40k"
Check = (fun cl -> cl.Income > 40000)
Positive = moreThan40
Negative = lessThan40}
and moreThan40 =
Query {Title = "Has criminal record"
Check = (fun cl -> cl.CriminalRecord)
Positive = Result "NO"
Negative = Result "YES"}
and lessThan40 =
Query {Title = "Years in job"
Check = (fun cl -> cl.YearsInJob > 1)
Positive = Result "YES"
Negative = usesCreditCard}
and usesCreditCard =
Query {Title = "Uses credit card"
Check = (fun cl -> cl.UsesCreditCard)
Positive = Result "YES"
Negative = Result "NO"}
let rec testClientTree client tree =
match tree with
| Result msg -> printfn " OFFER A LOAN: %s" msg
| Query qinfo -> let result, case =
if qinfo.Check(client) then
"yes", qinfo.Positive
else
"no", qinfo.Negative
printfn " - %s ? %s" qinfo.Title result
testClientTree client case
let john = {Name = "John Doe"; Income = 40000 ; YearsInJob = 1 ;
UsesCreditCard = true ; CriminalRecord = false }
testClientTree john tree
type Decision with
member x.decide(client) = testClientTree client x
static member foo () = "static member"
tree.decide(john)
type IClientCredit =
abstract Check : Client -> bool
abstract Report : Client -> unit
let testCriminal =
{new IClientCredit with
member this.Check(cl) = cl.CriminalRecord
member this.Report(cl) = printfn "%s' has a criminal record" cl.Name
}
type Client2 =
{ Name : string; Income : int ; YearsInJob : int
UsesCreditCard : bool; CriminalRecord : bool }
member x.Foo () = 1
member x.Bar () = "bar"
interface IClientCredit with
member this.Check(cl) = cl.CriminalRecord
member this.Report(cl) = printfn "%s' has a criminal record" cl.Name
type Client with
member x.Gender = "M"
type ClientInfo(name, income, years) =
let loanCoefficient = income / 500 * years
do printfn "Creating client '%s'" name
member x.Name = name
member x.Income = income
member x.Years = years
member x.Report () =
printfn "Client: %s, loan coefficient: %d" name loanCoefficient
type Triangle (a:float, b:float, c:float) =
member this.A = a
member this.B = b
member this.C = c
member this.IsRightAngled =
a*a + b*b = c*c
member this.IsTriangle : bool =
a+b > c
#if INTERACTIVE
#r @"..\packages\NUnit.2.6.4\lib\nunit.framework.dll"
#r @"..\packages\FsUnit.1.4.0.0\lib\net45\FsUnit.NUnit.dll"
#endif
open NUnit.Framework
open FsUnit
[<TestFixture>]
type ``Given a rightangled triangle`` () =
let triangle = new Triangle (3.0, 4.0, 5.0)
[<Test>]
member this.
``Whether the right angled triangle is a triangle`` () =
triangle.IsTriangle |> should equal true
[<Test>]
member this.
``Whether the right angle check works`` () =
triangle.IsRightAngled |> should equal true
[<TestFixture>]
type ``Given some negative values`` () =
let triangle = new Triangle (3.0, 4.0, -5.0)
[<Test>]
member this.
``The triangle test should fail`` () =
triangle.IsTriangle |> should equal false