f# linked list implementing with records - f#

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

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.

Related

How do I make a mutable argument in a function through F#?

Sorry for my question but I did not understand the answers that was related to this question so I hope someone can enlighten me further.
I am a new data science student and we are going to learn how to program in the functional language F#. We are learning about algorithms and I wanted to write the algorithms as F# functions to check if my calculations on paper were correct.
I get the following error saying:
"This value is not mutable. Consider using the mutable keyword let mutable n = expression"
My code looks like this:
let loop5( n ) =
let mutable x = 0
while n > 0 do
x <- x + 1
n <- n + 1
printfn "loop5(): x=%i for n=%i" x n
loop5(4)
I'm trying to write a function looking like this (pseudocode):
loop5(n)
x = 0
while n > 0
x = x + 1
n = n + 1
return x
Hope I made a clear question and someone can help me out here :-) Have a nice weekend
You're trying to mutate the loop's parameter n. The parameter is not mutable, so the compiler doesn't let you. That's exactly what the error tells you.
Now, normally, to make the error go away, you'd make the variable mutable. However, you can't make a function parameter mutable, so that's not an option.
Here you want to think what the meaning of your program should be. Does the loop function need to pass the updated value of n back to its caller, or is the whole mutation its internal business? If it's the former, please see #AnyMoose's answer, but from your example and explanation, I suspect it's the latter. If that is the case, simply make a mutable copy of the parameter and work with it:
let loop n' =
let mutable x = 0
let mutable n = n'
...
Separately, I want to point out that your program, as written, would actually loop indefinitely (or until it wraps around the max int value anyway), because instead of decreasing n at each step you're increasing it. If you want your program to actually finish before the next Ice Age, you need to make n decrease with each iteration:
n <- n - 1
Ref cells
Ref cells get around some of the limitations of mutables. In fact, ref cells are very simple datatypes which wrap up a mutable field in a record type. Ref cells are defined by F# as follows:
type 'a ref = { mutable contents : 'a }
The F# library contains several built-in functions and operators for working with ref cells:
let ref v = { contents = v } (* val ref : 'a -> 'a ref *)
let (!) r = r.contents (* val (!) : 'a ref -> 'a *)
let (:=) r v = r.contents <- v (* val (:=) : 'a ref -> 'a -> unit *)
The ref function is used to create a ref cell, the ! operator is used to read the contents of a ref cell, and the := operator is used to assign a ref cell a new value. Here is a sample in fsi:
let x = ref "hello";;
val x : string ref
x;; (* returns ref instance *)
val it : string ref = {contents = "hello";}
!x;; (* returns x.contents *)
val it : string = "hello"
x := "world";; (* updates x.contents with a new value *)
val it : unit = ()
!x;; (* returns x.contents *)
val it : string = "world"
Since ref cells are allocated on the heap, they can be shared across multiple functions:
open System
let withSideEffects x =
x := "assigned from withSideEffects function"
let refTest() =
let msg = ref "hello"
printfn "%s" !msg
let setMsg() =
msg := "world"
setMsg()
printfn "%s" !msg
withSideEffects msg
printfn "%s" !msg
let main() =
refTest()
Console.ReadKey(true) |> ignore
main()
The withSideEffects function has the type val withSideEffects : string ref -> unit.
This program outputs the following:
hello
world
Assigned from withSideEffects function
The withSideEffects function is named as such because it has a side-effect, meaning it can change the state of a variable in other functions. Ref Cells should be treated like fire. Use it cautiously when it is absolutely necessary but avoid it in general. If you find yourself using Ref Cells while translating code from C/C++, then ignore efficiency for a while and see if you can get away without Ref Cells or at worst using mutable. You would often stumble upon a more elegant and more maintanable algorithm
Aliasing Ref Cells
Note: While imperative programming uses aliasing extensively, this practice has a number of problems. In particular it makes programs hard to follow since the state of any variable can be modified at any point elsewhere in an application. Additionally, multithreaded applications sharing mutable state are difficult to reason about since one thread can potentially change the state of a variable in another thread, which can result in a number of subtle errors related to race conditions and dead locks.
A ref cell is very similar to a C or C++ pointer. Its possible to point to two or more ref cells to the same memory address; changes at that memory address will change the state of all ref cells pointing to it. Conceptually, this process looks like this:
Let's say we have 3 ref cells looking at the same address in memory:
Three references to an integer with value 7
cell1, cell2, and cell3 are all pointing to the same address in memory. The .contents property of each cell is 7. Let's say, at some point in our program, we execute the code cell1 := 10, this changes the value in memory to the following:
Three references to an integer with value 10
By assigning cell1.contents a new value, the variables cell2 and cell3 were changed as well. This can be demonstrated using fsi as follows:
let cell1 = ref 7;;
val cell1 : int ref
let cell2 = cell1;;
val cell2 : int ref
let cell3 = cell2;;
val cell3 : int ref
!cell1;;
val it : int = 7
!cell2;;
val it : int = 7
!cell3;;
val it : int = 7
cell1 := 10;;
val it : unit = ()
!cell1;;
val it : int = 10
!cell2;;
val it : int = 10
!cell3;;
val it : int = 10

F# Append custom table with custom list

I'm trying to make a function that extends a symbolTable with a list of Decl
Definitions:
type Typ = |Integer
|Boolean
|Ft of Typ list * Typ;;
type Decl = string * Typ;;
type symbolTable = Map<string, Typ>;;
I'm trying to do it the following way:
let extendST (st: symbolTable) (lst: Decl list) : symbolTable =
let mutable returnValue = st
for (x,y) in lst do
returnValue = returnValue.Add(x,y)
returnValue;;
But apparently nothing is being added to the returnValue (the function returns the same symbolTable as is being input).
I'm obviously new at F# but this is giving me a headache so I hope someone can help me out.
In F#, assignment (to change the value of a mutable variable) is written using <- rather than using = (which means just equality testing). Your code is comparing the two values and then ignoring the result (which is valid, but not what you wanted). The corrected version looks like this:
let extendST (st: symbolTable) (lst: Decl list) : symbolTable =
let mutable returnValue = st
for (x,y) in lst do
returnValue <- returnValue.Add(x,y)
returnValue
However, if you are looking for a functional solution, you can write this using fold:
let extendST (st: symbolTable) (lst: Decl list) : symbolTable =
lst |> List.fold (fun map (k, v) -> Map.add k v map) st
The fold function takes some state (your symbol table) and calculates a new state for each element of a given list lst. Here, the new state is a new map extended with the key-value pair k,v.

error with f# generic follow Expert Fsharp book example

I'm reading Expert F# book and I found this code
open System.Collections.Generic
let divideIntoEquivalenceClasses keyf seq =
// The dictionary to hold the equivalence classes
let dict = new Dictionary<'key,ResizeArray<'T>>()
// Build the groupings
seq |> Seq.iter (fun v ->
let key = keyf v
let ok,prev = dict.TryGetValue(key)
if ok then prev.Add(v)
else let prev = new ResizeArray<'T>()
dict.[key] <- prev
prev.Add(v))
dict |> Seq.map (fun group -> group.Key, Seq.readonly group.Value)
and the example use:
> divideIntoEquivalenceClasses (fun n -> n % 3) [ 0 .. 10 ];;
val it : seq<int * seq<int>>
= seq [(0, seq [0; 3; 6; 9]); (1, seq [1; 4; 7; 10]); (2, seq [2; 5; 8])]
first for me this code is really ugly, even if this is safe, It looks more similar to imperative languages than to functional lang..specially compared to clojure. But the problem is not this...I'm having problems with the Dictionary definition
when I type this:
let dict = new Dictionary<'key,ResizeArray<'T>>();;
I get this:
pruebafs2a.fs(32,5): error FS0030: Value restriction. The value 'dict' has been inferred to have generic type
val dict : Dictionary<'_key,ResizeArray<'_T>> when '_key : equality
Either define 'dict' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.
is It ok?...
thanks so much
improve question:
Ok I've been reading about value restriction and I found this helpfull information
In particular, only function definitions and simple immutable data
expressions are automatically generalized
...ok..this explains why
let dict = new Dictionary<'key,ResizeArray<'T>>();;
doesn't work...and show 4 different techniques, although in my opinion they only resolve the error but aren't solutions for use generic code:
Technique 1: Constrain Values to Be Nongeneric
let empties : int list [] = Array.create 100 []
Technique 3: Add Dummy Arguments to Generic Functions When Necessary
let empties () = Array.create 100 []
let intEmpties : int list [] = empties()
Technique 4: Add Explicit Type Arguments When Necessary (similar to tec 3)
let emptyLists = Seq.init 100 (fun _ -> [])
> emptyLists<int>;;
val it : seq<int list> = seq [[]; []; []; []; ...]
----- and the only one than let me use real generic code ------
Technique 2: Ensure Generic Functions Have Explicit Arguments
let mapFirst = List.map fst //doesn't work
let mapFirst inp = List.map fst inp
Ok, in 3 of 4 techniques I need resolve the generic code before can work with this...now...returning to book example...when the compile knows the value for 'key and 'T
let dict = new Dictionary<'key,ResizeArray<'T>>()
in the scope the code is very generic for let key be any type, the same happen with 'T
and the biggest dummy question is :
when I enclose the code in a function (technique 3):
let empties = Array.create 100 [] //doesn't work
let empties () = Array.create 100 []
val empties : unit -> 'a list []
I need define the type before begin use it
let intEmpties : int list [] = empties()
for me (admittedly I'm a little dummy with static type languages) this is not real generic because it can't infer the type when I use it, I need define the type and then pass values (not define its type based in the passed values) exist other way define type without be so explicit..
thanks so much..really appreciate any help
This line
let dict = new Dictionary<'key,ResizeArray<'T>>();;
fails because when you type the ;; the compiler doesn't know what 'key and 'T are. As the error message states you need to add a type annotation, or allow the compiler to infer the type by using it later or make it a function
Examples
Type annotation change
let dict = new Dictionary<int,ResizeArray<int>>();;
Using types later
let dict = new Dictionary<'key,ResizeArray<'T>>()
dict.[1] <- 2
using a function
let dict() = new Dictionary<'key,ResizeArray<'T>>();;
This actually doesn't cause an issue when it's defined all together. That is, select the entire block that you posted and send it to FSI in one go. I get this:
val divideIntoEquivalenceClasses :
('T -> 'key) -> seq<'T> -> seq<'key * seq<'T>> when 'key : equality
However, if you type these individually into FSI then as John Palmer says there is not enough information in that isolated line for the interpreter to determine the type constraints. John's suggestions will work, but the original code is doing it correctly - defining the variable and using it in the same scope so that the types can be inferred.
for me this code is really ugly, even if this is safe, It looks more similar to imperative languages than to functional lang.
I agree completely – it's slightly tangential to your direct question, but I think a more idiomatic (functional) approach would be:
let divideIntoEquivalenceClasses keyf seq =
(System.Collections.Generic.Dictionary(), seq)
||> Seq.fold (fun dict v ->
let key = keyf v
match dict.TryGetValue key with
| false, _ -> dict.Add (key, ResizeArray(Seq.singleton v))
| _, prev -> prev.Add v
dict)
|> Seq.map (function KeyValue (k, v) -> k, Seq.readonly v)
This allows sufficient type inference to obviate the need for your question in the first place.
The workarounds proposed by the other answers are all good. Just to clarify based on your latest updates, let's consider two blocks of code:
let empties = Array.create 100 []
as opposed to:
let empties = Array.create 100 []
empties.[0] <- [1]
In the second case, the compiler can infer that empties : int list [], because we are inserting an int list into the array in the second line, which constrains the element type.
It sounds like you'd like the compiler to infer a generic value empties : 'a list [] in the first case, but this would be unsound. Consider what would happen if the compiler did that and we then entered the following two lines in another batch:
empties.[0] <- [1] // treat 'a list [] as int list []
List.iter (printfn "%s") empties.[0] // treat 'a list [] as string list []
Each of these lines unifies the generic type parameter 'a with a different concrete type (int and string). Either of these unifications is fine in isolation, but they are incompatible with each other and would result in treating the int value 1 inserted by the first line as a string when the second line is executed, which is clearly a violation of type safety.
Contrast this with an empty list, which really is generic:
let empty = []
Then in this case, the compiler does infer empty : 'a list, because it's safe to treat empty as a list of different types in different locations in your code without ever impacting type safety:
let l1 : int list = empty
let l2 : string list = empty
let l3 = 'a' :: empty
In the case where you make empties the return value of a generic function:
let empties() = Array.create 100 []
it is again safe to infer a generic type, since if we try our problematic scenario from before:
empties().[0] <- [1]
List.iter (printfn "%s") (empties().[0])
we are creating a new array on each line, so the types can be different without breaking the type system.
Hopefully this helps explain the reasons behind the limitation a bit more.

Rewriting simple C# nested class

What would be an elegant way to implement the functionality of this nested class in F#?
private class Aliaser {
private int _count;
internal Aliaser() { }
internal string GetNextAlias() {
return "t" + (_count++).ToString();
}
}
This was my first attempt, but it feels like there should be a sexy one-liner for this:
let aliases = (Seq.initInfinite (sprintf "t%d")).GetEnumerator()
let getNextAlias() =
aliases.MoveNext() |> ignore
aliases.Current
The usual way of writing is to create a function with local state captured in a closure:
let getNextAlias =
let count = ref 0
(fun () ->
count := !count + 1;
sprintf "t%d" (!count))
The type of getNextAlias is simply unit -> string and when you call it repeatedly, it returns strings "t1", "t2", ... This relies on mutable state, but the mutable state is hidden from the user.
Regarding whether you can do this without mutable state - the simple answer is NO, because when you call a purely functional function with the same parameter twice, it must return the same result. Thus, you'd have to write something with the following structure:
let alias, state1 = getNextAlias state0
printf "first alias %s" alias
let alias, state2 = getNextAlias state1
printf "second alias %s" alias
// ...
As you can see, you'd need to keep some state and maintain it through the whole code. In F#, the standard way of dealing with this is to use mutable state. In Haskell, you could use State monad, which allows you to hide the passing of the state. Using the implementation from this question, you could write something like:
let getNextAlias = state {
let! n = getState
do! setState (n + 1)
return sprintf "t%d" n }
let program =
state {
let! alias1 = getNextAlias()
let! alias2 = getNextAlias()
// ...
}
execute progam 0 // execute with initial state
This is quite similar to other computations such as lazy or seq, actually - computations in the state { .. } block have some state and you can execute them by providing initial value of the state. However, unless you have good reasons for requiring purely functional solution, I'd prefer the first version for practical F# programming.
Here is the quick and dirty translation
type Aliaser () =
let mutable _count = 0
member x.GetNextAlias() =
let value = _count.ToString()
_count <- _count + 1
"t" + value
A more functional approach without state is to use continuations.
let createAliaser callWithValue =
let rec inner count =
let value = "t" + (count.ToString())
callWithValue value (fun () -> inner (count + 1))
inner 1
This is a declaration which will call the function callWithValue with both the value and the function to execute to repeat with the next value.
And here's an example using it
let main () =
let inner value (next : unit -> unit )=
printfn "Value: %s" value
let input = System.Console.ReadLine()
if input <> "quit" then next()
createAliaser inner
main()
I would use Seq.unfold : (('a -> ('b * 'a) option) -> 'a -> seq<'b>) to generate the aliases.
Implemented as:
let alias =
Seq.unfold (fun count -> Some(sprintf "t%i" count, count+1)) 0

Cyclic lists in F#

Is it just me, or does F# not cater for cyclic lists?
I looked at the FSharpList<T> class via reflector, and noticed, that neither the 'structural equals' or the length methods check for cycles. I can only guess if 2 such primitive functions does not check, that most list functions would not do this either.
If cyclic lists are not supported, why is that?
Thanks
PS: Am I even looking at the right list class?
There are many different lists/collection types in F#.
F# list type. As Chris said, you cannot initialize a recursive value of this type, because the type is not lazy and not mutable (Immutability means that you have to create it at once and the fact that it's not lazy means that you can't use F# recursive values using let rec). As ssp said, you could use Reflection to hack it, but that's probably a case that we don't want to discuss.
Another type is seq (which is actually IEnumerable) or the LazyList type from PowerPack. These are lazy, so you can use let rec to create a cyclic value. However, (as far as I know) none of the functions working with them take cyclic lists into account - if you create a cyclic list, it simply means that you're creating an infinite list, so the result of (e.g.) map will be a potentially infinite list.
Here is an example for LazyList type:
#r "FSharp.PowerPack.dll"
// Valid use of value recursion
let rec ones = LazyList.consDelayed 1 (fun () -> ones)
Seq.take 5 l // Gives [1; 1; 1; 1; 1]
The question is what data types can you define yourself. Chris shows a mutable list and if you write operations that modify it, they will affect the entire list (if you interpret it as an infinite data structure).
You can also define a lazy (potentionally cyclic) data type and implement operations that handle cycles, so when you create a cyclic list and project it into another list, it will create cyclic list as a result (and not a potentionally infinite data structure).
The type declaration may look like this (I'm using object type, so that we can use reference equality when checking for cycles):
type CyclicListValue<'a> =
Nil | Cons of 'a * Lazy<CyclicList<'a>>
and CyclicList<'a>(value:CyclicListValue<'a>) =
member x.Value = value
The following map function handles cycles - if you give it a cyclic list, it will return a newly created list with the same cyclic structure:
let map f (cl:CyclicList<_>) =
// 'start' is the first element of the list (used for cycle checking)
// 'l' is the list we're processing
// 'lazyRes' is a function that returns the first cell of the resulting list
// (which is not available on the first call, but can be accessed
// later, because the list is constructed lazily)
let rec mapAux start (l:CyclicList<_>) lazyRes =
match l.Value with
| Nil -> new CyclicList<_>(Nil)
| Cons(v, rest) when rest.Value = start -> lazyRes()
| Cons(v, rest) ->
let value = Cons(f v, lazy mapAux start rest.Value lazyRes)
new CyclicList<_>(value)
let rec res = mapAux cl cl (fun () -> res)
res
The F# list type is essentially a linked list, where each node has a 'next'. This in theory would allow you to create cycles. However, F# lists are immutable. So you could never 'make' this cycle by mutation, you would have to do it at construction time. (Since you couldn't update the last node to loop around to the front.)
You could write this to do it, however the compiler specifically prevents it:
let rec x = 1 :: 2 :: 3 :: x;;
let rec x = 1 :: 2 :: 3 :: x;;
------------------------^^
stdin(1,25): error FS0260: Recursive values cannot appear directly as a construction of the type 'List`1' within a recursive binding. This feature has been removed from the F# language. Consider using a record instead.
If you do want to create a cycle, you could do the following:
> type CustomListNode = { Value : int; mutable Next : CustomListNode option };;
type CustomListNode =
{Value: int;
mutable Next: CustomListNode option;}
> let head = { Value = 1; Next = None };;
val head : CustomListNode = {Value = 1;
Next = null;}
> let head2 = { Value = 2; Next = Some(head) } ;;
val head2 : CustomListNode = {Value = 2;
Next = Some {Value = 1;
Next = null;};}
> head.Next <- Some(head2);;
val it : unit = ()
> head;;
val it : CustomListNode = {Value = 1;
Next = Some {Value = 2;
Next = Some ...;};}
The answer is same for all languages with tail-call optimization support and first-class functions (function types) support: it's so easy to emulate cyclic structures.
let rec x = seq { yield 1; yield! x};;
It's simplest way to emulate that structure by using laziness of seq.
Of course you can hack list representation as described here.
As was said before, your problem here is that the list type is immutable, and for a list to be cyclic you'd have to have it stick itself into its last element, so that doesn't work. You can use sequences, of course.
If you have an existing list and want to create an infinite sequence on top of it that cycles through the list's elements, here's how you could do it:
let round_robin lst =
let rec inner_rr l =
seq {
match l with
| [] ->
yield! inner_rr lst
| h::t ->
yield h
yield! inner_rr t
}
if lst.IsEmpty then Seq.empty else inner_rr []
let listcycler_sequence = round_robin [1;2;3;4;5;6]

Resources