【问题标题】:f# linked list implementing with recordsf#链表实现与记录
【发布时间】:2016-03-10 07:48:53
【问题描述】:

我正在尝试使用记录在 f# 中实现一个链表。我知道我可以使用内置列表类型,但这是出于学习目的。我的类型是:

type Cell = { data : int; next : RList}
and RList = Cell option ref

我想做一个简单的插入函数,但有人告诉我 f# 期待一个布尔值,但得到了一个单位类型的表达式。我想知道这是否意味着我的 if/else 语句格式不正确

let rec insert comp (item: int) (list: RList) =
    let c = {data = item; next = ref None}
    match !list with
     | None -> list = cellToRList c
     | Some {data = d; next = remaining} -> 
        if (comp(item, d)) then
            c.next := !remaining
            remaining := ref c (* compiler indicates error here *)
        else insert comp item remaining

注意:comp 是任何以 (item, d) 为输入并输出真假的比较函数,例如:

let compare (x, y) = x > y

如果比较输出为真,我的目标只是插入一个带有 data = item 的新单元格。在上面的示例中,它可用于插入排序列表并保持排序。整个函数应该返回类型单位。任何关于我的解释器为什么要寻找布尔值的提示都将不胜感激!

注意:我对 F# 很陌生

====

由 Foggy、Mikhail 和 Fyodor 修复并进行了改进

type Cell = { data : int; next : (Cell option) ref}

let rec insert compare (item: int) (list: (Cell option) ref) : unit =
    let c = {data = item; next = ref None}
    match !list with
    | None -> list := Some c
    | Some {data = d; next = remaining} -> 
        if (compare(d, item)) then
            c.next := !remaining
            remaining := Some c
        else insert compare item remaining

【问题讨论】:

  • 这不能回答你的问题,但你不需要 RList :type Cell = { data : int; next : Cell option}dotnetfiddle.net/VzZwnb
  • 它更像是一个方便的包装器,除非你认为它不太方便?
  • 当然,RList 多余。
  • 昨天还有一个非常相似的问题:stackoverflow.com/q/35816215/180286
  • 我认为在开始学习 F# 时使用 'mutable' 只会有害。

标签: f# linked-list


【解决方案1】:

您从 None 匹配返回一个布尔值:

| None -> list = cellToRList c

等号在这里是比较运算符。所以编译器推断函数返回bool,而我猜你的意图是返回unit

无论如何,只要您不了解函数的推断类型,请尝试显式注释它们。在你的情况下,做它

let rec insert comp (item: int) (list: RList) : unit =

你会看到我上面描述的问题。

您可能希望在所有内容编译完成后删除类型注释。

【讨论】:

  • 现在说得通了!仅供参考,当我明确注释时,编译器会在正确的行上找到错误。
猜你喜欢
  • 1970-01-01
  • 2011-08-17
  • 2011-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-06
  • 1970-01-01
相关资源
最近更新 更多