Reputation: 303
I am trying to create two types where one is able to remove itself from the other such as in this example.
type employee (workplace : Job) =
member this.Fire () = workplace.Employees.Remove(this) |> ignore
and Job () =
let employees = new ResizeArray<employee>()
member this.Employees = employees
But this gets me the compile error of "Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved."
I'm not sure what I am doing wrong here. Any help would be appreciated
Upvotes: 4
Views: 262
Reputation: 243051
You can solve the problem even without reordering the declarations - when the F# compiler type-checks the Employee
declaration, it doesn't yet know what is the type of workplace.Employees
(because the type hasn't been declared yet), so it doesn't know where does the Remove
method come from. You can correct that by adding type annotation that specifies that Employees
is ResizeArray<Employee>
:
type Employee (workplace : Job) =
member this.Fire () =
let emps : ResizeArray<Employee> = workplace.Employees
emps.Remove(this) |> ignore
and Job () =
let employees = new ResizeArray<Employee>()
member this.Employees = employees
However, this example isn't very functional - if you're going to use mutable state (such as ResizeArray
), then the state should be hidden as private state of the type (so Jobs
could have a Remove
method).
In general, declaring recursive type declarations is a bit less comfortable in F# - however, you shouldn't need them that often. Quite frequently, you can use more generic types (i.e. Job
may not need to know abou the Employee
type).
Upvotes: 4
Reputation: 21
Try this..
type Job () =
let employees = new ResizeArray<employee>()
member this.Employees = employees
and employee (workplace : Job) =
member this.Fire () = workplace.Employees.Remove(this) |> ignore
Upvotes: 2