【问题标题】:F# lookup issues on recursive types递归类型的 F# 查找问题
【发布时间】:2011-06-26 17:51:09
【问题描述】:

我正在尝试创建两种类型,其中一种可以从另一种中移除,例如在本示例中。

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

但这给我带来了编译错误“根据此程序点之前的信息查找不确定类型的对象。在此程序点之前可能需要类型注释来约束对象的类型。这可能允许查找要解决。”

我不确定我在这里做错了什么。任何帮助将不胜感激

【问题讨论】:

    标签: f#


    【解决方案1】:

    即使不重新排序声明也可以解决问题 - 当 F# 编译器类型检查 Employee 声明时,它还不知道 workplace.Employees 的类型是什么(因为尚未声明该类型然而),所以它不知道Remove 方法来自哪里。您可以通过添加指定 EmployeesResizeArray&lt;Employee&gt; 的类型注释来纠正此问题:

    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
    

    然而,这个例子不是很实用——如果你打算使用可变状态(例如ResizeArray),那么状态应该被隐藏为类型的私有状态(所以Jobs可以有一个Remove 方法)。

    一般来说,在 F# 中声明递归类型声明不太方便 - 但是,您不应该经常需要它们。很多时候,您可以使用更通用的类型(即Job 可能不需要知道Employee 类型)。

    【讨论】:

    • “经常,您可以使用更通用的类型(即 Job 可能不需要知道 Employee 类型)”是什么意思。我会用什么代替它?在我自己的代码中,我最终在聊天类型中创建了自己的 Fire 方法。
    • 在这种情况下,Job 只是一个通用的集合,所以它不需要知道Employee,但是当然,这只是一个简化的例子——在更复杂的情况下,您也可以使用一些接口并避免递归类型声明。我认为在 OO 设计中可能更经常需要相互递归。
    【解决方案2】:

    试试这个..

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

    【讨论】:

    • 这确实解决了它。你碰巧知道为什么吗?我唯一能想到的是,因为编译器是自上而下的,它根本不知道 Job 是什么。但是,我认为 and 关键字使编译器在编译时再次通过以解决此问题。显然我错了。我想你不知道它是做什么的?
    • “工作”在您引用“员工”时尚未声明。
    • type...and 具有两遍式推理算法;首先,它查看所有显式方法签名,从上到下,然后对方法体进行第二次传递,从上到下。在这里,一种方法的主体需要来自另一种方法的信息。
    • (也可以参见stackoverflow.com/questions/844733/…,虽然这主要是基础知识,但这是递归成员类型推断算法的更高级方面。)
    猜你喜欢
    • 1970-01-01
    • 2018-03-23
    • 1970-01-01
    • 1970-01-01
    • 2012-07-03
    • 2011-07-14
    • 2022-01-18
    • 2023-04-01
    • 2019-01-12
    相关资源
    最近更新 更多