Hide this comment

When you define a method using "member", its content is computed every time you access it. Here, you're creating a new lazy value each time.

Use a "let" to define a local value (that will be evaluated only during the constructor).

By on 12/8/2009 10:18 AM ()Reply
Hide this comment

Well, my actual code is a discriminated union type. Such a type allows members, but apparently not let declarations ("This declaration element is not permitted in an augmentation"). I don't suppose there's any way around that?

By on 12/8/2009 10:54 AM ()Reply
Hide this comment

Sure, you can "add" let bindings by defining a module of the same name as the type, then tagging it ModuleSuffix:

1
2
3
4
5
6
7
8
 

type DU = | DU

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module DU = 
    let x = 1

If you want to expose members instead of let bindings (or if you want instance members on your DU), you can do this:

1
2
3
4
5
6
7
8
9
 

type DU = | DU 
    with
    member x.X = DUStatics.X
and internal DUStatics() = 
    static let x = 1
    static member X = x
By on 12/8/2009 1:13 PM ()Reply
Hide this comment

Michael, I don't think either of these do what the original asker wants though (my read is that he wants each instance to carry around a lazy object that can change state).

There's no way to 'add extra state' to instances of a DU without exposing it as part of the data carried by the DU.

By on 12/8/2009 1:51 PM ()Reply
Hide this comment

Michael, I don't think either of these do what the original asker wants though (my read is that he wants each instance to carry around a lazy object that can change state).

There's no way to 'add extra state' to instances of a DU without exposing it as part of the data carried by the DU.

Oh, my mistake then. If that's the case then the problem is the same as it is anywhere else in .NET when you want to add on information to an arbitrary object. I suppose some sort of dictionary holding a weakreference to the original object and the additional information could work, assuming performance isn't important. Then access could be done with normal members.

By on 12/9/2009 5:43 PM ()Reply
Hide this comment

my read is that he wants each instance to carry around a lazy object that can change state

That's correct.

There's no way to 'add extra state' to instances of a DU without exposing it as part of the data carried by the DU.

I really don't know what this means. Does it mean there's no way to add a lazy member to a DU?

By on 12/8/2009 2:02 PM ()Reply
Hide this comment

You can only do it by e.g. doing what's done in the second example below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 

type MyDU =
    | Num of int
    member this.X =
        match this with
        | Num(x) -> x

let x1 = Num 1        
printfn "%d" x1.X 
printfn "%d" x1.X 

type MyLazyDU =
    | LNum of Lazy<int>
    member this.X =
        match this with
        | LNum(x) -> x.Force()

let x2 = LNum(lazy(printfn "calculate..."; 1))
printfn "%d" x2.X 
printfn "%d" x2.X 

Does it make sense?

By on 12/8/2009 2:19 PM ()Reply
Hide this comment

Yes, thanks.

By on 12/8/2009 2:27 PM ()Reply
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper

Logging in...