F # член внутренняя функция, вычисляется только при первом вызове - PullRequest
0 голосов
/ 26 апреля 2019

Я пытаюсь использовать своего рода агрегат с классом в F #, как это member this.FullName with get() = fullName().Вы можете видеть, что я разработал его как член, который вызывает внутреннюю функцию let fullName() = (string Id) +" "+ Name, и кажется, что значение оценивается при первом вызове и сохраняется внутри.Если я изменю значения, из которых состоит функция, она продолжит возвращать значение первого вызова.Как я могу изменить его?

В то же время, если я обновляю объект в LiteDB и снова читаю его, если кажется, что или значение обновляется.

И другой вопрос: чтоявляются членами и внутренними переменными, которые хранятся в LiteDB.Каждый?,Как я могу взять это под контроль?

Полный код:

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

Ответы [ 2 ]

3 голосов
/ 26 апреля 2019

Вы написали let fullName = (string Id) + " " + Name. После fullName параметра нет, поэтому вместо того, чтобы быть функцией (вычисляемой каждый раз, когда она вызывается), это значение (вычисляется только один раз). Если вы хотите, чтобы он оценивался при каждом вызове, включите его в функцию, добавив параметр:

let fullName () = (string Id) + " " + Name
0 голосов
/ 26 апреля 2019

Решено вот так

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

Добавление self как решение

...