Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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
List f#自定义链表和引用_List_Recursion_F#_Ref - Fatal编程技术网

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