f#使用记录实现的链表
我正在尝试使用记录在f#中实现一个链表。我知道我可以使用内置列表类型,但这是为了学习。我的类型是:f#使用记录实现的链表,f#,linked-list,F#,Linked List,我正在尝试使用记录在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 = {d
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是以(项,d)为输入并输出真或假的任何比较函数,例如:
let compare (x, y) = x > y
我的目标只是插入一个新的单元格,如果比较输出为true,则data=item。在上面的示例中,它可以用于插入到排序列表中,并保持排序的一致性。整个函数应该返回类型unit。任何关于我的解释器为什么要寻找布尔值的提示都将不胜感激
注:我对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
从
None
匹配中返回布尔值:
| None -> list = cellToRList c
等号在这里是一个比较运算符。因此编译器推断函数返回bool
,而我猜您的意图是返回unit
在任何情况下,如果不理解函数的推断类型,请尝试显式注释它们。就你的情况来说,去做吧
let rec insert comp (item: int) (list: RList) : unit =
您将看到我上面描述的问题
一旦一切都编译完毕,您可能希望删除类型注释。这并不能回答您的问题,但您不需要RList:
type Cell={data:int;next:Cell option}
它更像是一个方便的包装器,除非您认为它不太方便?当然,RList
redundant。就在昨天,还有一个非常类似的问题:我认为在学习F#的开始使用“可变”只会带来伤害。现在这就非常有意义了!另外,仅供参考,当我显式注释它时,编译器将在正确的行中找到错误。