繁体   English   中英

f# 自定义链表和引用

[英]f# custom linked list and references

我是这种语言的新手。 为了尝试和理解引用,我尝试以大一大学计算机科学的方式实现一个简单的定向列表。

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?

请告诉我为什么我不擅长这个

首先,您尝试以某种命令式方式实现它 - 这没问题,但不是真正的功能。 无论如何,您遇到的第一件事是,您不能分配null - 如果您真的想要,您必须将[<AllowNullLiteral>]添加到您的item类型(但当然您必须将其设为类而不是记录):

[<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

现在,如果您仔细观察,您会发现如果您只是在前面附加,那么您实际上并不需要 refs,瞧……您得到了通常的功能列表 ;)

PS:你也忘记了一些其他的东西:

  • 你在那里使用浮点数,所以你必须使用0.0而不是0
  • 你的sum函数必须是递归的(注意它不是尾递归的,所以你会遇到大列表的问题!)
  • 你必须取消引用ref -细胞有!
  • 你必须用ref构造ref -cells (例如ref null
  • 你的type list() =对我来说毫无意义所以我把它转换成一个模块

PPS:请不要因为F#-Way来改变这样的事情 - 这只是向您展示如何做到这一点......但如果您不必,请不要这样做

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM