Reputation: 93
I'm trying to implement a queue in F#. One way I thought about going about it is using a mutable list. I believe the logic is all right, however when I run the code I get the error
/home/runner/main.fs(12,5): error FS0027: This value is not mutable. Consider using the mutable keyword, e.g. 'let mutable queue = expression'.
compiler exit status 1
^[[3;1R
This is my implementation code
let create_job_list jobCount resultLis =
let resultLis =
[for i in 1..jobCount do yield System.Random().Next(10)]
resultLis
let job_list = create_job_list 10 []
let mutable queue = []
let push x queue =
printfn "%A" x
queue <- (x::queue)
let pop resQueue =
let resQ = resQueue |> List.rev
match resQ with
| head::tail -> printfn "%A" head; queue <- (tail |> List.rev)
| [] -> failwith "No more jobs to do right now."
let rec jobQueue job_list =
match job_list with
| head::tail when head%2=1 -> (push head queue) |> ignore; jobQueue tail
| head::tail when head%2=0 -> (pop queue) |> ignore; jobQueue tail
| _ -> failwith "Empty list"
The error tells me to use let mutable queue = expression
but I'm using let mutable queue = []
Where am I going wrong? Thanks
Upvotes: 1
Views: 163
Reputation: 2459
What you need is to pass queue
by reference. Your push
function should then look something like this:
let push x (queue: byref<_>) =
printfn "%A" x
queue <- (x::queue)
and the jobQueue
like this
let rec jobQueue job_list =
match job_list with
| head::tail when head%2=1 -> (push head &queue) |> ignore; jobQueue tail
| head::tail when head%2=0 -> (pop queue) |> ignore; jobQueue tail
| _ -> failwith "Empty list"
I haven't tried this code, but it should at least get you started.
By the way, I guess you are aware that .Net already has a Queue implementation?
Upvotes: 2
Reputation: 3875
You have declared queue as mutable, but you are passing it as an argument that isn't mutable anymore. Since your queue
variable is visible inside the push and pop you don't need to have it as parameters.
This should compile:
let create_job_list jobCount resultLis =
let resultLis =
[for i in 1..jobCount do yield System.Random().Next(10)]
resultLis
let job_list = create_job_list 10 []
let mutable queue = []
let push x=
printfn "%A" x
queue <- (x::queue)
let pop resQueue =
let resQ = resQueue |> List.rev
match resQ with
| head::tail -> printfn "%A" head; queue <- (tail |> List.rev)
| [] -> failwith "No more jobs to do right now."
let rec jobQueue job_list =
match job_list with
| head::tail when head%2=1 -> (push head) |> ignore; jobQueue tail
| head::tail when head%2=0 -> (pop) |> ignore; jobQueue tail
| _ -> failwith "Empty list"
Upvotes: 2