0

I'm trying to use a kind of aggregate to a Class in F# like this member this.FullName with get() = fullName(). You can see I have designed it as a member that calls an internal function let fullName() = (string Id) +" "+ Name, and it seems that the value is evaluated on the first invocation and stored internally. If I modify the values that make up the function, it continues to return the value of the first invocation. How can I change it?

At the same time if I update the Object in LiteDB and read it again, if it seems that, or the value is updated.

And other question: What are the members and internal variables that are stored in LiteDB. Everyone? . How can I take control of it?

The full code is:

open System

open LiteDB
open LiteDB.FSharp

[<StructuredFormatDisplay("Article #{Id}: {Name}")>]
type Article( Id: int, Name: string) as self =
    let fullName  = (string Id) + " " + Name
    member val Id = Id //Read Only
    member val Name = Name with get, set //Mutable
    //[<BsonIgnore>]
    member this.FullName with get() = fullName 
    //[<BsonIgnore>]
    member this.FullName2 = (string Id) + " " + Name

[<EntryPoint>]
let main argv =

    let mapper = FSharpBsonMapper()
    use db = new LiteDatabase("simple.db", mapper)

    let articles = db.GetCollection<Article>("articles")
    let id = BsonValue(2)

    // Insert
    let art2 = new Article(2, "First Name")
    printfn "%A" art2
    printfn "fn: %s" art2.FullName
    articles.Insert(art2) |> ignore
    printfn "==="


    // Find
    let result = articles.FindById(id)
    printfn "%A" result
    printfn "fn: %s" result.FullName
    printfn "==="

    // Modify
    result.Name <- "New Name"
    printfn "%A" result
    printfn "fn: %s" result.FullName //<- No Modified!
    printfn "fn2: %s" result.FullName2 //<- No Modified!
    printfn "==="

    // Update Modified Changes
    articles.Update(result) |> ignore
    let result = articles.FindById(id)
    // printfn "%%O %O" result //.ToString()
    printfn "%A" result 
    printfn "fn: %s" result.FullName


    0 // return an integer exit code
Santi
  • 491
  • 6
  • 14

2 Answers2

3

You have written let fullName = (string Id) + " " + Name. There's no parameter after fullName, so instead of being a function (evaluated every time it's called), it's a value (evaluated just once). If you want it to be evaluated every time it's called, turn it into a function by adding a parameter:

let fullName () = (string Id) + " " + Name
rmunn
  • 34,942
  • 10
  • 74
  • 105
  • Change this line also: `member this.FullName with get() = fullName` – AMieres Apr 26 '19 at 12:29
  • Same result after changing: `let fullName() = (string Id) + " " + Name` and `member this.FullName with get() = fullName()` – Santi Apr 26 '19 at 12:38
  • Even the same result (no reevaluated) with `member this.FullName2() = (string Id) + " " + Name` and `printfn "fn2: %s" (result.FullName2())` – Santi Apr 26 '19 at 12:43
0

Solved like this

type Article( Id: int, Name: string) as self =
    let fullName()  = (string self.Id) + " " + self.Name
    ...
    member this.FullName with get() = fullName()

Adding self as been the solution

Santi
  • 491
  • 6
  • 14