~ubuntu-branches/debian/sid/nunit/sid

« back to all changes in this revision

Viewing changes to samples/fsharp/money/Money.fs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2014-09-16 13:43:36 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20140916134336-kjxz48tty6lx2ja5
Tags: 2.6.3+dfsg-1
* [c7bd1b5] Imported Upstream version 2.6.3+dfsg
* [bcb4bf8] Move nunit-console-runner to GAC-installed libnunit2.6, 
  don't treat it as a private lib. This lib is signed, and treated 
  as a GAC lib by consumers such as MonoDevelop.
* [7f08e99] Bump version to 2.6.3 as required
* [84535eb] Refreshed patches
* [8479f61] Split package up into per-assembly packages. This makes 
  ABI tracking easier in the future, as we can meaningfully have GAC 
  policy for cases where ABI isn't truly bumped, and no policy for 
  cases where it is. For example, if nunit.framework bumps ABI but 
  nunit.core does not, previously we would need to rebuild everything 
  using NUnit, but under the new split packaging, that rebuild would 
  not be needed for apps only using nunit.core.
* [17a7dc7] Add missing nunit.mocks.dll to nunit.pc

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
module NUnit.Samples.Money
 
2
 
 
3
open System
 
4
open System.Collections.Generic
 
5
 
 
6
type IMoney =
 
7
    abstract IsZero : bool
 
8
    abstract Add : IMoney -> IMoney
 
9
    abstract AddMoney : Money -> IMoney
 
10
    abstract Multiply : int -> IMoney
 
11
    abstract Negate : unit -> IMoney
 
12
    abstract Subtract : IMoney -> IMoney
 
13
 
 
14
and Money(amount: int, currency: string) as this =
 
15
 
 
16
    member internal this.currency
 
17
        with get() = currency
 
18
    member internal this.amount
 
19
        with get() = amount
 
20
 
 
21
    override self.Equals(anObject) =
 
22
        match anObject with
 
23
            | :? Money as money -> this.IsZero && money.IsZero || currency = money.currency && amount = money.amount
 
24
            | _ -> false
 
25
    override this.GetHashCode() = currency.GetHashCode() + amount 
 
26
    override this.ToString() = System.String.Format("[{0} {1}]", amount, currency)
 
27
 
 
28
    interface IMoney with
 
29
        member this.IsZero = amount = 0
 
30
        member this.Add(m: IMoney) = m.AddMoney(this)
 
31
        member this.AddMoney(m: Money) = this.AddMoney(m)
 
32
        member this.Multiply(factor) = this.Multiply(factor) :> IMoney
 
33
        member this.Negate() = this.Negate() :> IMoney
 
34
        member this.Subtract(m: IMoney) = this.Subtract(m) : IMoney
 
35
 
 
36
    member this.IsZero = (this :> IMoney).IsZero
 
37
    member this.Add(m: IMoney) = m.AddMoney(this)
 
38
    member this.AddMoney(m: Money) =
 
39
        if m.currency = this.currency then new Money(m.amount + this.amount, this.currency) :> IMoney
 
40
        else new MoneyBag( [this; m] ) :> IMoney
 
41
    member this.Multiply(factor) = new Money( this.amount * factor, this.currency )
 
42
    member this.Negate() = new Money( -this.amount, this.currency)
 
43
    member this.Subtract(m: IMoney) = m.Negate().Add(this);
 
44
 
 
45
    // Operator overrides
 
46
    static member (+) (m1: Money, m2: Money) = m1.AddMoney(m2)
 
47
    static member (*) (m1: Money, factor) = m1.Multiply(factor)
 
48
    static member (*) (factor, m1: Money) = m1.Multiply(factor)
 
49
    static member (~-) (m: Money) = m.Negate()
 
50
    static member (-) (m1: Money, m2: Money) = m1.Subtract(m2)
 
51
 
 
52
and MoneyBag(contents0: Money list) =
 
53
    // Although mutable, this should only be changed in the constructor
 
54
    let mutable contents = []
 
55
    do
 
56
        let mutable map = Map.empty
 
57
        for m in contents0 do
 
58
            if m.IsZero <> true then
 
59
                match map.TryFind(m.currency) with
 
60
                    | None -> map <- map.Add(m.currency, m.amount)
 
61
                    | Some(_) as old ->
 
62
                        map <- map.Add(m.currency, m.amount + old.Value)
 
63
        for pair in map do
 
64
            contents <- new Money(pair.Value, pair.Key)::contents
 
65
 
 
66
    member this.Contents
 
67
        with get() = contents
 
68
 
 
69
    override this.Equals(anObject) =
 
70
        match anObject with
 
71
            | :? MoneyBag as bag when this.IsZero -> bag.IsZero
 
72
            | :? MoneyBag as bag -> bag.contentsEqual(contents)
 
73
            | _ ->false
 
74
    override this.GetHashCode() =
 
75
        contents.GetHashCode()
 
76
    override this.ToString() =
 
77
        contents.ToString()
 
78
 
 
79
    interface IMoney with
 
80
        member this.IsZero = contents.IsEmpty
 
81
        member this.Multiply(factor) = this.Multiply(factor) :> IMoney
 
82
        member this.Negate() = this.Negate() :> IMoney
 
83
        member this.Subtract(m: IMoney) = this.Subtract(m)
 
84
        member this.Add(m: IMoney) : IMoney = this.Add(m)
 
85
        member this.AddMoney(m: Money) = this.AddMoney(m) :> IMoney
 
86
 
 
87
    member this.IsZero = contents.IsEmpty
 
88
    member this.Multiply(factor) =
 
89
        if factor = 0 then new MoneyBag( [] )
 
90
        else new MoneyBag( [ for m in contents -> m * factor ] )
 
91
    member this.Negate() = new MoneyBag( [ for m in contents -> -m ] )
 
92
    member this.Add(m: IMoney): IMoney =
 
93
        match m with
 
94
            | :? Money as money -> this.AddMoney(money).simplify()
 
95
            | :? MoneyBag as bag -> this.AddMoneyBag(bag).simplify()
 
96
            | _ -> failwith "Unexpected Type for IMoney"
 
97
    member this.AddMoney(money: Money): MoneyBag =
 
98
        new MoneyBag( [ for m in contents -> if m.currency = money.currency then new Money(m.amount + money.amount, m.currency) else m ] )
 
99
    member this.AddMoneyBag(bag: MoneyBag): MoneyBag =
 
100
        let mutable result = bag
 
101
        for m in contents do
 
102
            result <- result.AddMoney m
 
103
        result
 
104
    member this.Subtract(money: IMoney): IMoney = this.Add( money.Negate() )
 
105
 
 
106
    member private self.contains(aMoney: Money) =
 
107
        List.tryFind (fun m -> m = aMoney) contents <> None            
 
108
    member private self.contentsEqual(c: Money list) =
 
109
        if c.Length <> contents.Length then false
 
110
        else List.forall (fun m -> self.contains m) c
 
111
    member private self.simplify() =
 
112
        match contents.Length with
 
113
            | 1 -> contents.Head :> IMoney
 
114
            | _ -> self :> IMoney
 
115
 
 
116
    static member (*) (bag: MoneyBag, factor) = bag.Multiply(factor)
 
117
    static member (*) (factor, bag: MoneyBag) = bag.Multiply(factor)
 
118
    static member (~-) (bag: MoneyBag) = bag.Negate()
 
119
    static member (+) (bag: MoneyBag, m: IMoney) = bag.Add(m)
 
120
    static member (+) (m: Money, bag: MoneyBag) = bag.AddMoney(m)
 
121
    static member (-) (bag: MoneyBag, m: IMoney) = bag.Subtract(m)
 
122
    static member (-) (m: Money, bag: MoneyBag) = m.Subtract(bag)