简体   繁体   中英

Member variables in F#

let eval a b = 
    let r = a + b
    printf "calculate.."
    r
type Foo() =
    member this.Eval = eval 5 10
[<EntryPoint>]
let main argv = 
    let f = Foo()
    let a = f.Eval
    let b = f.Eval
    0

This calls eval 2 times instead of one time. It seems this.Eval is a function pointer that calls eval every time I call .Eval.

What I really want to have is a variable.

I solved it by doing this...

let eval a b = 
    let r = a + b
    printf "calculate.."
    r
type Foo() =
    let e = eval 5 10
    member this.Eval = e
[<EntryPoint>]
let main argv = 
    let f = Foo()
    let a = f.Eval
    let b = f.Eval
    0

Is this the correct way of doing this if I just want to have a member variable instead of method?

The behaviour you describe is the way .NET properties always work, whether in C# or F#. The body of the property is evaluated each time the property is read.

In addition to your solution, which is correct, I'd add that it calculates the value when Foo is constructed. You might only want the value to be calculated when you read the property the first time, and if so you can use Lazy to do that:

let eval a b = 
    let r = a + b
    printf "calculate.."
    r
type Foo() =
    // a lazy computation that will be evaluated the first time .Value is called
    let e = lazy eval 5 10
    member this.Eval = e.Value
[<EntryPoint>]
let main argv = 
    let f = Foo()
    let a = f.Eval
    let b = f.Eval
    0

I think that the more idimatic F# style would be:

type Foo() =
    let eval a b = 
        let r = a + b
        printf "calculate.."
        r
    let e = eval 5 10
    member this.Eval = e
[<EntryPoint>]
let main argv = 
    let f = Foo()
    let a = f.Eval
    let b = f.Eval
    0

ie you put the eval inside the class with a let binding to hide the implementation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM