Skip to content

Instantly share code, notes, and snippets.

@vabka
Last active June 10, 2021 22:16
Show Gist options
  • Save vabka/dca8006f234756638ce77f566054b5a2 to your computer and use it in GitHub Desktop.
Save vabka/dca8006f234756638ce77f566054b5a2 to your computer and use it in GitHub Desktop.
module ExhangeRatesAPI.Service
open ExhangeRatesAPI.Types
open ExhangeRatesAPI.Common
type Rate =
{ Left: Symbol
Right: Symbol
Value: decimal }
module Rate =
let right rate = rate.Right
let left rate = rate.Left
let flipRate rate =
{ Left = rate.Right
Right = rate.Left
Value = 1m / rate.Value }
let calculateRates (src: Symbol) (dst: Symbol list) (rates: Rate list) : Rate list =
let all =
rates |> List.append (rates |> List.map flipRate)
let getLeft src =
all |> List.filter (fun x -> x.Left = src)
let getRight dst =
all |> List.filter (fun x -> x.Right = dst)
let tryGetDirect dst =
all
|> List.tryFind (fun x -> x.Left = src && x.Right = dst)
let tryGetWithJoin dst =
optional {
// nested loops method
let left = getLeft src
let right = getRight dst
let innerJoin left =
right
|> Seq.filter (fun right -> left.Right = right.Left)
|> Seq.map (fun right -> left, right)
let! result =
left
|> Seq.map innerJoin
|> Seq.concat
|> Seq.tryHead
let left = fst result
let right = snd result
return
{ Left = left.Left
Right = right.Right
Value = left.Value * right.Value }
}
let getRate dst =
tryGetDirect dst
|> Option.orElseWith (fun _ -> tryGetWithJoin dst)
dst
|> Seq.map getRate
|> Seq.map Option.get
|> Seq.toList
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment