Reputation: 141
I am stuck trying to write in F# something that I conceive well in C++: a class that has as a member a list of pointers to objects of the same type. Because I haven't succeeded, I'm only posting my chimeric attempt, with the list of pointers included (which obviously is not correct F# and does not compile).
As the stylized chimeric wish below shows, the idea would be to create a bunch of Freds, and then build assign their myListOfPointers as needed, before calculating f() of one particular Fred. I've added a large data member to make the case that Freds shouldn't be copied, but in my target application calling f() changes the state of the Fred, so it seems yet more important that each Fred should not store a copy of the others its f requires to compute but only a "reference or pointer" to those. If this calls for a complete redesign, please succinctly state the path to follow.
type Fred(bigData:float[]) =
{
let data_ = bigData
let mutable l = [] // list of "pointers to Fred", if there were such a thing
member s.myListOfPointers with set(z) = l <- z
member s.f() =
match l with
| [] -> Array.sum data_
| _ -> l |> List.map (fun p -> (*p).f()) //This dereferencing * operator is C++ language for what I would like to do.
|> List.map (fun x -> x * x) |> List.sum
}
Thanks!
Upvotes: 0
Views: 693
Reputation: 43076
You can't have pointers to Fred in f#. Instead, you would just have a list of Freds. The actual contents of the list are in fact pointers to Freds, but the language doesn't conceptualize them that way. Instead, they are .NET object references. If you're unfamiliar with the concepts, read up on reference types vs. value types, otherwise known as classes (reference types) and structs (value types):
Classes and Structs (C# Programming Guide)
So your list just becomes a Fred list
and the lambda variable p is not dereferenced; it is not a pointer to a Fred
, its type is simply Fred
. You might therefore rename it as f
.
Upvotes: 1
Reputation: 47914
With a few minor tweaks, your code works:
type Fred(bigData:float[]) =
let data_ = bigData
let mutable l = [] // list of "pointers to Fred", if there were such a thing
member s.myListOfPointers with set(z) = l <- z
member s.f() =
match l with
| [] -> Array.sum data_
| _ -> l |> List.map (fun (p: Fred) -> p.f())
|> List.map (fun x -> x * x) |> List.sum
The notable thing is the need for a type annotation on p
prior to calling f()
. This is because the type of l
is not known at that point.
Upvotes: 1