List f#自定义链表和引用
我不熟悉这种语言。为了尝试和理解引用,我尝试用大学一年级计算机科学的方式实现了一个简单的定向列表List f#自定义链表和引用,list,recursion,f#,ref,List,Recursion,F#,Ref,我不熟悉这种语言。为了尝试和理解引用,我尝试用大学一年级计算机科学的方式实现了一个简单的定向列表 type item = { value:float next:ref<item> } type list() = let head:ref<item> = null // tried instantiation so many different ways and it likes none of em let sum i =
type item = {
value:float
next:ref<item>
}
type list() =
let head:ref<item> = null // tried instantiation so many different ways and it likes none of em
let sum i =
if i == null then
0
else
i.value + sum i.next // constructor not defined?
类型项={
值:浮动
下一个:ref
}
类型列表()=
let head:ref=null//尝试了许多不同的实例化方法,但都不喜欢
设和i=
如果i==null,那么
0
其他的
i、 value+sum i.next//未定义构造函数?
请告诉我为什么我在这方面做得不好。首先,您尝试以某种必要的方式实现它——这是可以的,但不是真正起作用的。 无论如何,您遇到的第一个问题是,您不能分配
null
——如果您真的想分配,您必须将[]
添加到项
类型中(当然,您必须将其设为类而不是记录):
现在,如果你仔细观察,你会发现你并不需要裁判,如果你只是附加在前面,瞧。。。您得到了常用的功能列表;)
附言:你还忘了其他一些事情:
- 这里使用的是浮动,因此必须使用
而不是0.0
0
- 您的
-函数必须是递归的(请注意,它不是尾部递归的,因此您将遇到大列表的问题!)sum
- 您必须用
取消引用
-单元格代码>ref
- 必须使用
(例如ref
)构造ref null
-单元格ref
- 你的
对我来说毫无意义,所以我把它转换成了一个模块type list()=
PPS:请不要说这不是F#方式来改变像这样的事情-它只是告诉你如何做到这一点。。。但是,如果您不必首先,您尝试以某种必要的方式实现它-这是可以的,但不是真正的功能。 无论如何,您遇到的第一个问题是,您不能分配
null
——如果您真的想分配,您必须将[]
添加到项
类型中(当然,您必须将其设为类而不是记录):
现在,如果你仔细观察,你会发现你并不需要裁判,如果你只是附加在前面,瞧。。。您得到了常用的功能列表;)
附言:你还忘了其他一些事情:
- 这里使用的是浮动,因此必须使用
而不是0.0
0
- 您的
-函数必须是递归的(请注意,它不是尾部递归的,因此您将遇到大列表的问题!)sum
- 您必须用
取消引用
-单元格代码>ref
- 必须使用
(例如ref
)构造ref null
-单元格ref
- 你的
对我来说毫无意义,所以我把它转换成了一个模块type list()=
PPS:请不要说这不是F#方式来改变像这样的事情-它只是告诉你如何做到这一点。。。但是如果你不必我会让
ref
成为一个选项
,它可能会做你想做的事。我会让ref
成为一个选项,它可能会做你想做的事。我感谢你的回答,但正如问题中所述,我实现了代码,以便掌握引用和实例化。要么我就是不懂你的代码,要么它没有真正回答我的问题?很抱歉,您更改了这么多代码,我现在觉得有点像拉丁语^^问题到底出在哪里?我更改了第一个代码片段,只是为了让您编译代码-例如,您不能将项
实现为记录,因为F#将不允许null
-文本(好的,我也做了大写的类名-类型应为大写;))第二个是null
-问题(使用选项)的典型解决方案,我使类型更具可读性和更清晰-只要问一下您不理解的内容,我会解释这是一个很好的答案,但我不明白您为什么使用“ref”而不是“option”。您能解释一下这一点吗?@FoggyFinder因为我想靠近问题,在命令式(可变)链表中,您通常希望不时更改指向下一个列表元素的指针(正如我在这里所说的,这并不是真正必要的)
引用单元格允许这样做(它是可变的,你可以用listItem重置它。下一步:=某个其他节点
我感谢你的回答,但正如问题中所述,我实现了这样的代码,以便掌握引用和实例。要么我不懂你的代码,要么它没有真正回答我的问题?对不起,你更改了这么多代码,似乎是b现在对我来说就像拉丁语一样^^^问题到底出在哪里?我更改了第一个代码片段,只是为了让您编译代码-例如,您不能将项
实现为记录,因为F#将不允许空
-文本(好的,我也做了大写的类名-类型应该是大写的;)第二个是null
-问题的典型解决方案(使用选项)我使这些类型更具可读性和简洁性——只要问你不懂的地方,我会解释这是一个很好的答案,但我不明白你为什么用“ref”而不是“option”。你能解释一下这一点吗?@foggyinder,因为我想接近这个问题,并且使用命令式(可变)链表您通常希望不时地更改指向下一个列表元素的指针(正如我在这里所说的,这并不是必需的)ref单元格允许这样做(它是可变的,您可以使用listItem.next:=某个其他节点
[<AllowNullLiteral>]
type Item(value, next) =
member this.value = value
member this.next : Item ref = next
let head : ref<Item> = ref null
let rec sum (i : Item) =
if i = null then
0.0
else
i.value + sum !i.next
module List =
type Item = { value : float; next : List }
and List = Item option ref
let empty : List = ref None
let single x = { value = x; next = ref None }
// this is how you can change the list
let rec append x l =
let item = single x
match !l with
| None ->
l := Some item
| Some node ->
append x node.next
let rec sum (l : List) =
match !l with
| None -> 0.0
| Some item -> item.value + sum item.next