Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 非常非类型化的递归类定义,可以编译,但对我来说似乎是一个极端的例子_F# - Fatal编程技术网

F# 非常非类型化的递归类定义,可以编译,但对我来说似乎是一个极端的例子

F# 非常非类型化的递归类定义,可以编译,但对我来说似乎是一个极端的例子,f#,F#,这4行代码可以编译,但对我来说没有意义: open System type mclas (y) = member x.m = x.m let z = mclas (1:>obj) 问题:在什么情况下我们需要以这种方式编码?我是否激活了我不知道的微妙的类功能 编辑:如果没有用例,这段代码关于编译器警告/错误的状态是什么,是否符合github上提出的一些问题 注意:在运行时,调试器无法对变量z求值,并说“函数求值超时”。成员m实际上在IL中编译成如下内容: .property i

这4行代码可以编译,但对我来说没有意义:

open System

type mclas (y) =
    member x.m = x.m

let z = mclas (1:>obj)
问题:在什么情况下我们需要以这种方式编码?我是否激活了我不知道的微妙的类功能

编辑:如果没有用例,这段代码关于编译器警告/错误的状态是什么,是否符合github上提出的一些问题


注意:在运行时,调试器无法对变量z求值,并说“函数求值超时”。

成员m实际上在IL中编译成如下内容:

.property instance object m {
    .get instance object Program/mclas::get_m()
}
所以m是object类型的属性,它有一个递归的getter。C#等价物是:

公共类mclas
{
公共mclas(对象y){}
公共对象x{
得到{
返回x;
}
}
}
因为递归永远不会结束,需要花费太长的时间和/或当调试器尝试计算m时发生StackOverflowException,所以它取消并指出计算超时

至于你的实际问题:我不认为你在F#中需要这种自我参照,至少我想不出任何可能的用途


我认为编译器的这种行为是有意义的,因为没有参数的成员将始终编译为get only属性,然后这将是定义无限递归属性的最明显方式(仅仅因为这没有用处并不意味着你不能这样做)。

感谢Gentlecat。对于函数,由于rec关键字,让fx=fx不编译,但让rec fx=fx编译。我希望对类有相同的语法限制,或者至少有警告。顺便说一下,在let rec fx=fx之后,如果我有let y=f1,它不会编译,这与let z=。。。在我最初的问题中。因此,在我的类定义案例中,编译器的行为对我来说没有意义,应该拒绝它,或者为类定义等效的rec关键字或警告。R:我不打算创建递归类类型;这只是一个实验。有关“缺少”rec关键字的问题,请参阅链接。至于let y=f 1示例,它没有编译,因为类型推断无法决定函数f应该具有哪种返回类型,因此给它一个泛型返回类型“b”(函数f是“a->”b),并且由于您不能存储泛型类型的实例,它没有编译。感谢您的努力,我接受你的回答,因为你最后的评论中有链接。