F # search problems on recursive types

I am trying to create two types where you can remove yourself from another, for example, 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 gives me a compilation error "Search for an object of an indefinite type based on information to this point in the program." Type annotations may be needed before this program point limits the type of object. This may allow the search to be allowed. "

I'm not sure what I'm doing wrong here. Any help would be appreciated

+4
source share
2 answers

You can solve the problem without even reordering the declarations - when the F # compiler type checks the Employee declaration, it still does not know what the workplace.Employees type is (since the type has not been declared), so it does not know where the Remove method comes from. You can fix this by adding a type annotation that indicates that Employees have a 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 is not very functional - if you are going to use a mutable state (for example, ResizeArray ), then the state should be hidden as a private state of the type (so Jobs can have Remove ).

In general, declaring declarations of a recursive type is a little less convenient in F # - however, you do not need them often. Quite often, you can use more general types (i.e. Job may not need to know the type of Employee ).

+4
source

Try it.

 type Job () = let employees = new ResizeArray<employee>() member this.Employees = employees and employee (workplace : Job) = member this.Fire () = workplace.Employees.Remove(this) |> ignore 
+2
source

All Articles