4

I'm trying to implement a linked list in f# using records. I know I can use the build in list type but this is for learning purposes. My type is:

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

And I'd like to make a simple insert function, but I'm told that f# is expecting a boolean but was given an expression of type unit. I'm wondering if this means I've formatted my if/else statement incorrectly

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

Note: comp is any comparison function taking (item, d) as input and outputting true or false ex:

let compare (x, y) = x > y

My goal is simply to insert a new cell with data = item if compare outputs true. In the example above it could be used to insert into a sorted list and maintain sorted-ness. The entire function should return type unit. Any hint as to why my interpreter is looking for a boolean would be appreciated!

Note: I'm very new to F#

====

Fixed with improvements Courtesy of Foggy, Mikhail, and 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
Sunny
  • 53
  • 6

1 Answers1

4

You return a bool from your None match:

| None -> list = cellToRList c

Equals sign is a comparison operator here. So the compiler infers the function to return bool, while I guess your intention is to return unit.

In any case, whenever you don't understand the inferred types of your functions, try annotating them explicitly. In your case, make it

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

And you will see the problem that I described above.

You may want to remove type annotation once everything compiles.

Mikhail Shilkov
  • 34,128
  • 3
  • 68
  • 107
  • That makes perfect sense now! Also FYI when I annotate it explicitly the compiler will find the error on the correct line. – Sunny Mar 06 '16 at 21:06