With this type:
let Empty =
{
Buy = new Dictionary<int64, int64 * float>()
Sell = new Dictionary<int64, int64 * float>()
}
if I assign it to several entities through the code:
let a = Empty
let b = Empty
they'll represent the same dictionaries.
How can I generate a new instance every time?
let makeEmpty () = {
Buy = new Dictionary<int64, int64 * float>()
Sell = new Dictionary<int64, int64 * float>()
}
Related
In Javascript it is possible to create a CustomEvent and include a second argument containing detail data to pass when the event is dispatched. For example:
let evt = new CustomEvent("hello", {
detail: { name: "John" }
});
elem.dispatchEvent(evt);
With Fable I can create a CustomEvent without the detail data as follows:
let evt = CustomEvent.Create "hello"
elem.dispatchEvent evt
The definition in Browser.Events is as follows:
type [<AllowNullLiteral>] CustomEventType =
[<Emit("new $0($1...)")>] abstract Create : typeArg: string * ?eventInitDict: CustomEventInit -> CustomEvent
[<Emit("new $0($1...)")>] abstract Create : typeArg: string * ?eventInitDict: CustomEventInit<'T> -> CustomEvent<'T>
But I can't work out how to create a CustomEventInit as I think this is an interface.
let details:CustomEventInit = { detail = {name = "John"}} //ERROR: This type is not a record type
let evt = CustomEvent.Create ("hello", details)
elem.dispatchEvent evt
Any help on how to achieve this would be greatly appreciated!
CustomEventInit is a class type, so you can instantiate it using an object expression:
let details =
let mutable bubbles = true
let mutable cancelable = true
let mutable composed = true
let mutable detail : obj = "John"
{
new CustomEventInit with
member _.bubbles
with set(value) = bubbles <- value
and get() = bubbles
member _.cancelable
with set(value) = cancelable <- value
and get() = cancelable
member _.composed
with set(value) = bubbles <- value
and get() = bubbles
member _.detail
with set(value) = detail <- value
and get() = detail
}
Or you could create a named subclass if you prefer.
Is there a succint way to express self-replicating types in F#? — That is, without repeating oneself.
// Manual self-replication
type Foo (par1 : Type1, par2 : Type2, par3 : Type3, par4 : Type4) =
let unique = new UniqueState() // unique for every instance of Foo
member this.SelfReplicate =
new Foo(par1, par2, par3, par4) // repeating myself
let a = new Foo(x, y, z, w)
let b = a.SelfReplicate
Attempt with manually injected self-replicator:
// Semi-automagic self-replication
type Foo' (par1 : Type1, par2 : Type2, par3 : Type3, par4 : Type4, replicate : unit -> Foo') =
let unique = new UniqueState() // unique for every instance of Foo'
member this.SelfReplicate = replicate() // not repeating myself
let rec foo' () = new Foo'(x, y, z, w, foo')
let a = foo'()
let b = a.SelfReplicate
I'm not sure how this can be any more succint without compiler magic. It just seems like there should be a way to capture the current arguments and type without repeating them syntactically.
You could define a type WithUnique<'T> which is a wrapper over a value of type 'T and adds a unique value to this. You may need to think about how you want the equality testing on those types to work - if you use record (as I do below), then two instances with different unique value will not be equal:
let rnd = System.Random()
let uniqueState() = rnd.Next()
type WithUnique<'T> =
{ Value : 'T; Unique : int }
static member Create(v) : WithUnique<'T> =
{ Value = v; Unique = uniqueState() }
member x.Replicate() =
{ Value = x.Value; Unique = uniqueState() }
The value of 'T is just one type, but this can be a tuple (or a record) if you need to wrap multiple things:
let wu1 = WithUnique.Create( (10, "hi") )
let wu2 = wu1.Replicate()
Given the above, wu1=wu2 will be false.
I'm looking to figure out a simple loop in order to calculate an amortization schedule in Swift.
So far, here is my setup on Playground:
let loanAmount: Double = 250000.00
let intRate: Double = 4.0
let years: Double = 30.0
var r: Double = intRate / 1200
var n: Double = years * 12
var rPower: Double = pow(1 + r, n)
var monthlyPayment: Double = loanAmount * r * rPower / (rPower - 1)
var annualPayment: Double = monthlyPayment * 12
For the actual loop, I'm unsure how to fix the code below.
for i in 0...360 {
var interestPayment: Double = loanAmount * r
var principalPayment: Double = monthlyPayment - interestPayment
var balance: Double; -= principalPayment
}
Looking to generate a monthly schedule. Thanks in advance for any tip.
I'm guessing you mean to declare the balance variable outside the loop, and to decrement it inside the loop:
// stylistically, in Swift it's usual to leave
// off the types like Double unless you have a
// reason to be explicit
let loanAmount = 250_000.00
let intRate = 4.0
let years = 30.0
// since these are one-off calculations, you
// should use let for them, too. let doesn't
// just have to be for constant numbers, it just
// means the number can't change once calculated.
let r = intRate / 1200
let n = years * 12
let rPower = pow(1 + r, n)
// like above, these aren't changing. always prefer let
// over var unless you really need to vary the value
let monthlyPayment = loanAmount * r * rPower / (rPower - 1)
let annualPayment = monthlyPayment * 12
// this is the only variable you intend to "vary"
// so does need to be a var
var balance = loanAmount
// start counting from 1 not 0 if you want to use an open
// (i.e. including 360) range, or you'll perform 361 calculations:
for i in 1...360 {
// you probably want to calculate interest
// from balance rather than initial principal
let interestPayment = balance * r
let principalPayment = monthlyPayment - interestPayment
balance -= principalPayment
println(balance)
}
This should print out the correct balances going down to zero for the final balance (well actually 9.73727765085641e-09 – but that's a whole other question).
If you wanted to create a monthly balance, say in an array, you could add an additional array variable to store that in:
var balance = loanAmount
//array of monthly balances, with the initial loan amount to start with:
var monthlyBalances = [balance]
for i in 1...360 {
let interestPayment = balance * r
let principalPayment = monthlyPayment - interestPayment
balance -= principalPayment
monthlyBalances.append(balance)
}
Advanced version for anyone who's interested
You might wonder if there's a way to declare monthlyBalances with let rather than var. And there is! You could use reduce:
let monthlyBalances = reduce(1...360, [loanAmount]) {
payments, _ in
let balance = payments.last!
let interestPayment = balance * r
let principalPayment = monthlyPayment - interestPayment
return payments + [balance - principalPayment]
}
However this is a bit nasty for a couple of reasons. It would much much nicer if the Swift standard library had a slightly different version of reduce called accumulate that generated an array out of a running total, like this:
let monthlyBalances = accumulate(1...360, loanAmount) {
balance, _ in
let interestPayment = balance * r
let principalPayment = monthlyPayment - interestPayment
return balance - principalPayment
}
And here's a definition of accumulate:
func accumulate<S: SequenceType, U>
(source: S, var initial: U, combine: (U, S.Generator.Element) -> U)
-> [U] {
var result: [U] = []
result.append(initial)
for x in source {
initial = combine(initial, x)
result.append(initial)
}
return result
}
I read on stackoverflow that easiest way to convert a DateTime variable back to Excel date was simply to do:
let exceldate = int(DateTime)
Admittedly this was in c# and not f#. This is supposed to work as the decimals represent time and int part represents date. I tried this and f# comes back with the error:
The type 'DateTime' does not support a conversion to the type 'int'
So how do I convert back to excel date?
More specificly, I m trying to create a vector of month 1st for a period between start date and end date. Both vector output and start date and end date are floats, i.e. excel dates. Here my clumsy first attempt:
let monthlies (std:float) (edd:float) =
let stddt = System.DateTime.FromOADate std
let edddt = System.DateTime.FromOADate edd
let vecstart = new DateTime(stddt.Year, stddt.Month, 1)
let vecend = new DateTime(edddt.Year, edddt.Month, 1)
let nrmonths = 12 * (edddt.Year-stddt.Year) + edddt.Month - stddt.Month + 1
let scaler = 1.0 - (float(stddt.Day) - 1.0) / float(DateTime.DaysInMonth(stddt.Year , stddt.Month))
let dtsvec:float[] = Array.zeroCreate nrmonths
dtsvec.[0] <- float(vecstart)
for i=1 to (nrmonths-1) do
let temp = System.DateTime.FromOADate dtsvec.[i-1]
let temp2 = temp.AddMonths 1
dtsvec.[i] = float temp2
dtsvec
This doesnt work because of the conversion issue and is rather complicated and imperative.
How do I do the conversion? How can I do this more functionally? Thanks
Once you have the DateTime object, just call ToOADate, like so:
let today = System.DateTime.Now
let excelDate = today.ToOADate()
So your example would end up like so:
let monthlies (std:float) (edd:float) =
let stddt = System.DateTime.FromOADate std
let edddt = System.DateTime.FromOADate edd
let vecstart = new System.DateTime(stddt.Year, stddt.Month, 1)
let vecend = new System.DateTime(edddt.Year, edddt.Month, 1)
let nrmonths = 12 * (edddt.Year-stddt.Year) + edddt.Month - stddt.Month + 1
let scaler = 1.0 - (float(stddt.Day) - 1.0) / float(System.DateTime.DaysInMonth(stddt.Year , stddt.Month))
let dtsvec:float[] = Array.zeroCreate nrmonths
dtsvec.[0] <- vecstart.ToOADate()
for i=1 to (nrmonths-1) do
let temp = System.DateTime.FromOADate dtsvec.[i-1]
let temp2 = temp.AddMonths 1
dtsvec.[i] = temp2.ToOADate()
dtsvec
In regards to getting rid of the loop, maybe something like this?
type Vector(x: float, y : float) =
member this.x = x
member this.y = y
member this.xDate = System.DateTime.FromOADate(this.x)
member this.yDate = System.DateTime.FromOADate(this.y)
member this.differenceDuration = this.yDate - this.xDate
member this.difference = System.DateTime.Parse(this.differenceDuration.ToString()).ToOADate
type Program() =
let vector = new Vector(34.0,23.0)
let difference = vector.difference
Does the compiler create a new location in memory when a record is extended (deep copy?) or does the compiler make the record mutable and modify the value?
For example:
type MyRecord = { A : string
; B : string
}
let record = { A = "A"; B = "B" }
let record = { record with A = "new A" } //copy or overwrite?
Since I am overwriting record does the compiler copy or overwrite? Are there performance concerns either way?
It makes the copy.
Copy-and-update Record expression
*A copy-and-update record expression elaborates as if it were a record expression written as follows:
let v = expr in { field-label1 = expr1 ; … ; field-labeln = exprn; F1 = v.F1; ... ; FM = v.FM }
where F1 ... FM are the fields of R that are not defined in field-initializers and v is a fresh variable.*
This
type T = {
A : string
B : string
}
let x = { A = "a"; B = "b" }
let y = { x with A = "aa" }
is equivalent to this
class T {
public readonly string A;
public readonly string B;
public T(string a, string b) {
A = a;
B = b;
}
}
var x = new T("a", "b");
var y = new T("aa", x.B);