29
3/12/2009 1 What is F#? Microsoft Multi-paradigm Language CLR All the .NET platform benefits First class language in to Visual Studio 2010 What about F# makes it functional or concurrent? Immutable Constructs Higher Order Functions Partial Application Ability to do lazy evaluation Asynchronous Workflows

Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

1

What is F#?

Microsoft Multi-paradigm Language

CLR – All the .NET platform benefits

First class language in to Visual Studio 2010

What about F# makes it functional or concurrent?

Immutable Constructs

Higher Order Functions

Partial Application

Ability to do lazy evaluation

Asynchronous Workflows

Page 2: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

2

Real World Application!

Auto Insurance Rating Engine

Page 3: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

3

Page 4: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

4

List of Policies

Policy

Calculation

Policy

Calculation

Driver Factor

Coverage Coverage Coverage

Vehicle

Driver Driver

Vehicle

Driver Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Calculation

Why can’t it be faster?

Page 5: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

5

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let rec Rate (policies: System.Collections.Generic.List<Policy>) =

let policies = List.of_seq policies

let rec exec = function

|[] -> ()

|p::tail -> async{

calcCoverages(p, GetCurrentRates(p), GetCoverages(p))

} |> Async.Spawn

exec tail

exec policies

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 6: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

6

let Rate (policies: System.Collections.Generic.List<Policy>) =

let policies = List.of_seq policies

let rec exec = function

|[] -> ()

|p::tail -> async{

calcCoverages(p, GetCurrentRates(p), GetCoverages(p))

} |> Async.Spawn

exec tail

exec policies

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let rec Rate (policies: System.Collections.Generic.List<Policy>) =

let policies = List.of_seq policies

let rec exec = function

|[] -> ()

|p::tail -> async{

calcCoverages(p, GetCurrentRates(p), GetCoverages(p))

} |> Async.Spawn

exec tail

exec policies

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 7: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

7

let rec Rate (policies: System.Collections.Generic.List<Policy>) =

let policies = List.of_seq policies

let rec exec = function

|[] -> ()

|p::tail -> async{

calcCoverages(p, GetCurrentRates(p), GetCoverages(p))

} |> Async.Spawn

exec tail

exec policies

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let rec Rate (policies: System.Collections.Generic.List<Policy>) =

let policies = List.of_seq policies

let rec exec = function

|[] -> ()

|p::tail -> async{

calcCoverages(p, GetCurrentRates(p), GetCoverages(p))

} |> Async.Spawn

exec tail

exec policies

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 8: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

8

let rec calcCoverages (policy:Policy) rates coverages = function

| [] -> ()

| c::tail -> updatePolicy(policy (Async.Run(GetRates policy rates c)))

calcCoverages policy rates tail

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let rec calcCoverages (policy:Policy) rates coverages = function

| [] -> ()

| c::tail -> updatePolicy(policy (Async.Run(GetRates policy rates c)))

calcCoverages policy rates tail

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 9: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

9

let GetRates (policy:Policy) rates coverage =

async{

let! results = Async.Parallel[

for v in Policy.vehicles ->

async{return (Result policy v coverage rates).Force()}

]

return (coverage, Seq.reduce(+) results)}

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let GetRates (policy:Policy) rates coverage =

async{

let! results = Async.Parallel[

for v in Policy.vehicles ->

async{return (Result policy v coverage rates).Force()}

]

return (coverage, Seq.reduce(+) results)}

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 10: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

10

let GetRates (policy:Policy) rates coverage =

async{

let! results = Async.Parallel[

for v in Policy.vehicles ->

async{return (Result policy v coverage rates).Force()}

]

return (coverage, Seq.reduce(+) results)}

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let GetRates (policy:Policy) rates coverage =

async{

let! results = Async.Parallel[

for v in Policy.vehicles ->

async{return (Result policy v coverage rates).Force()}

]

return (coverage, Seq.reduce(+) results)}

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 11: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

11

let GetRates (policy:Policy) rates coverage =

async{

let! results = Async.Parallel[

for v in Policy.vehicles ->

async{return (Result policy v coverage rates).Force()}

]

return (coverage, Seq.reduce(+) results)}

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let GetRates (policy:Policy) rates coverage =

async{

let! results = Async.Parallel[

for v in Policy.vehicles ->

async{return (Result policy v coverage rates).Force()}

]

return (coverage, Seq.reduce(+) results)}

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 12: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

12

let Result (p:Policy)(v:Vehicle)(c:AutoCoverage)(r:CurrentRates) =

lazy(

let QueryRate(rq:RateQuery) =

rq.Coverage <- c.ToInt()

r.GetRate(rq) ...

BasicPolicyFactor()

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let Result (p:Policy)(v:Vehicle)(c:AutoCoverage)(r:CurrentRates) =

lazy(

let QueryRate(rq:RateQuery) =

rq.Coverage <- c.ToInt()

r.GetRate(rq) ...

BasicPolicyFactor()

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 13: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

13

let Result (p:Policy)(v:Vehicle)(c:AutoCoverage)(r:CurrentRates) =

lazy(

let QueryRate(rq:RateQuery) =

rq.Coverage <- c.ToInt()

r.GetRate(rq) ...

BasicPolicyFactor()

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let Result (p:Policy)(v:Vehicle)(c:AutoCoverage)(r:CurrentRates) =

lazy(

let QueryRate(rq:RateQuery) =

rq.Coverage <- c.ToInt()

r.GetRate(rq) ...

BasicPolicyFactor()

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 14: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

14

let Result (p:Policy)(v:Vehicle)(c:AutoCoverage)(r:CurrentRates) =

lazy(

let QueryRate(rq:RateQuery) =

rq.Coverage <- c.ToInt()

r.GetRate(rq) ...

BasicPolicyFactor()

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let Result (p:Policy)(v:Vehicle)(c:AutoCoverage)(r:CurrentRates) =

lazy(

let QueryRate(rq:RateQuery) =

rq.Coverage <- c.ToInt()

r.GetRate(rq) ...

BasicPolicyFactor()

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 15: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

15

let BasicPolicyFactor() =

lazy(

Seq.map force [AverageDriverFactor();

MultiPolicyCombinationDiscount();

CompanyCarDiscount();]

|> Seq.reduce (*)

)

(Lazy<decimal>)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let BasicPolicyFactor() =

lazy(

Seq.map force [AverageDriverFactor();

MultiPolicyCombinationDiscount();

CompanyCarDiscount();]

|> Seq.reduce (*)

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 16: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

16

let BasicPolicyFactor() =

lazy(

Seq.map force [AverageDriverFactor();

MultiPolicyCombinationDiscount();

CompanyCarDiscount();]

|> Seq.reduce (*)

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let AverageDriverFactor() =

lazy(

let mutable accum = (decimal)0

for d in p.Drivers do

accum <- accum + (DriverFactor d).Force()

accum / (decimal)p.Drivers.Count)

(unit -> Lazy<decimal>)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 17: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

17

let AverageDriverFactor() =

lazy(

let mutable accum = (decimal)0

for d in p.Drivers do

accum <- accum + (DriverFactor d).Force()

accum / (decimal)p.Drivers.Count)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let AverageDriverFactor() =

lazy(

let mutable accum = (decimal)0

for d in p.Drivers do

accum <- accum + (DriverFactor d).Force()

accum / (decimal)p.Drivers.Count)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 18: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

18

let DriverFactor d =

lazy(

[BaseRate d;

DriverClassFactor d;

InsuranceScoreFactor d;

GoodStudentFactor d;

GrangeLifeFactor d;

AwayAtSchoolFactor d]

|> Seq.map force

|> Seq.reduce (*)

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let DriverFactor d =

lazy(

[BaseRate d;

DriverClassFactor d;

InsuranceScoreFactor d;

GoodStudentFactor d;

GrangeLifeFactor d;

AwayAtSchoolFactor d]

|> Seq.map force

|> Seq.reduce (*)

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 19: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

19

let DriverFactor d =

lazy(

[BaseRate d;

DriverClassFactor d;

InsuranceScoreFactor d;

GoodStudentFactor d;

GrangeLifeFactor d;

AwayAtSchoolFactor d]

|> Seq.map force

|> Seq.reduce (*)

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let InsuranceScoreFactor (d:Driver) =

let rq = new RateQuery(RateTableType.CreditScoreFactor)

rq.Age <- Common.CalculateDriverAge(d.BirthDate, p)

let rec scoreCalc() =

match d.InsuranceScoreAttribute.ToString() with

| "CBRN" when score < 2 -> -2

| "CBRS" when score < 2 -> -3

| "CBRW" when score < 2 -> -4

| "CBRV" when score < 2 -> -5

| "CBRX" when score < 2 -> -6

| _ -> d.InsuranceScore

rq.CreditScore <- scoreCalc()

QueryRate rq

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 20: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

20

let InsuranceScoreFactor (d:Driver) =

let rq = new RateQuery(RateTableType.CreditScoreFactor)

rq.Age <- Common.CalculateDriverAge(d.BirthDate, p)

let rec scoreCalc() =

match d.InsuranceScoreAttribute.ToString() with

| "CBRN" when score < 2 -> -2

| "CBRS" when score < 2 -> -3

| "CBRW" when score < 2 -> -4

| "CBRV" when score < 2 -> -5

| "CBRX" when score < 2 -> -6

| _ -> d.InsuranceScore

rq.CreditScore <- scoreCalc()

QueryRate rq

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let InsuranceScoreFactor (d:Driver) =

let rq = new RateQuery(RateTableType.CreditScoreFactor)

rq.Age <- Common.CalculateDriverAge(d.BirthDate, p)

let rec scoreCalc() =

match d.InsuranceScoreAttribute.ToString() with

| "CBRN" when score < 2 -> -2

| "CBRS" when score < 2 -> -3

| "CBRW" when score < 2 -> -4

| "CBRV" when score < 2 -> -5

| "CBRX" when score < 2 -> -6

| _ -> d.InsuranceScore

rq.CreditScore <- scoreCalc()

QueryRate rq

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 21: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

21

let InsuranceScoreFactor (d:Driver) =

let rq = new RateQuery(RateTableType.CreditScoreFactor)

rq.Age <- Common.CalculateDriverAge(d.BirthDate, p)

let rec scoreCalc() =

match d.InsuranceScoreAttribute.ToString() with

| "CBRN" when score < 2 -> -2

| "CBRS" when score < 2 -> -3

| "CBRW" when score < 2 -> -4

| "CBRV" when score < 2 -> -5

| "CBRX" when score < 2 -> -6

| _ -> d.InsuranceScore

rq.CreditScore <- scoreCalc()

QueryRate rq

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let InsuranceScoreFactor (d:Driver) =

let rq = new RateQuery(RateTableType.CreditScoreFactor)

rq.Age <- Common.CalculateDriverAge(d.BirthDate, p)

let rec scoreCalc() =

match d.InsuranceScoreAttribute.ToString() with

| "CBRN" when score < 2 -> -2

| "CBRS" when score < 2 -> -3

| "CBRW" when score < 2 -> -4

| "CBRV" when score < 2 -> -5

| "CBRX" when score < 2 -> -6

| _ -> d.InsuranceScore

rq.CreditScore <- scoreCalc()

QueryRate rq

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 22: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

22

let DriverFactor d =

lazy(

[BaseRate d;

DriverClassFactor d;

InsuranceScoreFactor d;

GoodStudentFactor d;

GrangeLifeFactor d;

AwayAtSchoolFactor d]

|> Seq.map force

|> Seq.reduce (*)

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let DriverFactor d =

lazy(

[BaseRate d;

DriverClassFactor d;

InsuranceScoreFactor d;

GoodStudentFactor d;

GrangeLifeFactor d;

AwayAtSchoolFactor d]

|> Seq.map force

|> Seq.reduce (*)

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 23: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

23

let DriverFactor d =

lazy(

[BaseRate d;

DriverClassFactor d;

InsuranceScoreFactor d;

GoodStudentFactor d;

GrangeLifeFactor d;

AwayAtSchoolFactor d]

|> Seq.map force

|> Seq.reduce (*)

)

let force (x:Lazy<x>) = x.Force()

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let DriverFactor d =

lazy(

[BaseRate d;

DriverClassFactor d;

InsuranceScoreFactor d;

GoodStudentFactor d;

GrangeLifeFactor d;

AwayAtSchoolFactor d]

|> Seq.map force

|> Seq.reduce (*)

)

decimal list

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 24: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

24

let DriverFactor d =

lazy(

[BaseRate d;

DriverClassFactor d;

InsuranceScoreFactor d;

GoodStudentFactor d;

GrangeLifeFactor d;

AwayAtSchoolFactor d]

|> Seq.map force

|> Seq.reduce (*)

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let DriverFactor d =

lazy(

[BaseRate d;

DriverClassFactor d;

InsuranceScoreFactor d;

GoodStudentFactor d;

GrangeLifeFactor d;

AwayAtSchoolFactor d]

|> Seq.map force

|> Seq.reduce (*)

)

decimal

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 25: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

25

let AverageDriverFactor() =

lazy(

let mutable accum = (decimal)0

for d in p.Drivers do

accum <- accum + (DriverFactor d).Force()

accum / (decimal)p.Drivers.Count

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let AverageDriverFactor() =

lazy(

let mutable accum = (decimal)0

for d in p.Drivers do

accum <- accum + (DriverFactor d).Force()

accum / (decimal)p.Drivers.Count

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 26: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

26

let BasicPolicyFactor() =

lazy(

Seq.map force [AverageDriverFactor();

MultiPolicyCombinationDiscount();

CompanyCarDiscount();]

|> Seq.reduce (*)

)

(unit -> Lazy<decimal>)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let Result (p:Policy)(v:Vehicle)(c:AutoCoverage)(r:CurrentRates) =

lazy(

let QueryRate(rq:RateQuery) =

rq.Coverage <- c.ToInt()

r.GetRate(rq) ...

BasicPolicyFactor()

)

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 27: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

27

let GetRates (policy:Policy) rates coverage =

async{

let! results = Async.Parallel[

for v in Policy.vehicles ->

async{return (Result policy v coverage rates).Force()}

]

return (coverage, Seq.reduce(+) results)}

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

let CalcCoverages (policy:Policy) rates coverages = function

| [] -> ()

| c::tail -> updatePolicy(policy, (Async.Run(GetRates policy rates c)))

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 28: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

28

let rec Rate (policies: System.Collections.Generic.List<Policy>) =

let policies = List.of_seq policies

let rec exec = function

|[] -> ()

|p::tail -> async{

calcCoverages(p, GetCurrentRates(p), GetCoverages(p))

} |> Async.Spawn

exec tail

exec policies

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

(d1 + d2) / 2

Parallel

Parallel

Spawned Thread

Process List of Policies

Policy Policy

Coverage Coverage Coverage

Vehicle Vehicle

Basic Policy Factor

Avg Driver Factor

Driver

Driver Factor

Driver Factor

Driver

Company Car Factor

Multi-policy Factor

ZipcodeFactor

Policy

Coverage Coverage

Page 29: Real World F# · async{let! results = Async.Parallel[for v in Policy.vehicles -> async{return(Result policy v coverage rates).Force()}] return (coverage, Seq.reduce(+) results)} (d1

3/12/2009

29

1 5 10 20 40 50

C# 3 10 15 38 78 95

F# 1 4 7 15 20 35

#light

let RealWorld F# = Concurrent applications

Amanda Laucher

[email protected]

pandamonial.com

Twitter: pandamonial