f#自定义链接列表和引用

时间:2014-07-22 13:46:19

标签: 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 = 
        if i == null then
            0
        else 
            i.value + sum i.next // constructor not defined?

请告诉我为什么我这么糟糕

1 个答案:

答案 0 :(得分:5)

首先,您尝试以某种必要的方式实现它 - 这没关系,但不是真正的功能。 无论如何,你遇到问题的首要问题是,你无法分配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 = singleton 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

现在,如果你仔细观察,你会看到你真的不需要裁判如果你只是在前面附加并且瞧...你得到了通常的功能列表;)

PS:你也忘记了其他一些事情:

  • 你在那里使用花车,所以你必须使用0.0而不是0
  • 你的sum - 函数必须是递归的(请注意,它不是尾递归的,所以你会遇到大列表的问题!)
  • 您必须取消引用 ref - !
  • 的单元格
  • 您必须使用ref构建ref - 单元格(例如ref null
  • 你的type list() =对我毫无意义,因此我将其转换为模块

PPS:请注意,不是 F#-Way 改变这样的事情 - 它只是告诉你如何做到这一点......但如果你没有这样做就不要到