2016-03-06 50 views
5

我想在f#中使用记录实现链表。我知道我可以使用列表类型的构建,但这是用于学习的目的。我的类型是: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 

注:比较是任何比较函数取(项目,d)作为输入和输出真或假例如:

let compare (x, y) = x > y 

我的目标是简单地插入一个新的单元格与数据=项目,如果比较输出为真。在上面的例子中,它可以用来插入一个排序列表并维护排序。整个函数应该返回类型单位。任何暗示为什么我的解释器正在寻找一个布尔值将不胜感激!

注:我很新的F#

====

有雾,米哈伊尔和费奥多尔改进礼貌

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 
+0

这并不回答你的问题,但你不需要RList:'type Cell = {data:int;下一个:单元格选项}'https://dotnetfiddle.net/VzZwnb –

+0

它更像是一个方便的包装,除非你认为它不太方便? – Sunny

+0

当然,'RList'多余。 –

回答

4

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

| None -> list = cellToRList c 

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

在任何情况下,只要您不理解函数的推断类型,请尝试明确注释它们。在你的情况,使它

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

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

一旦编译完成,您可能需要删除类型注释。

+0

这使得完美的感觉吧!此外,当我明确注释它时,编译器会在正确的行上找到错误。 – Sunny