F# 可变列表返回错误,指出它不可变

F# Mutable list is returning an error stating it is not mutable

提问人:Nick 提问时间:11/14/2019 更新时间:11/14/2019 访问量:158

问:

我正在尝试在 F# 中实现队列。我想到的一种方法是使用可变列表。我相信逻辑是正确的,但是当我运行代码时,我得到了错误

/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

这是我的实现代码

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"

错误告诉我使用,但我正在使用let mutable queue = expressionlet mutable queue = []

我哪里出错了? 谢谢

调试 f# 队列 可变

评论


答:

2赞 3615 11/14/2019 #1

您已将队列声明为可变的,但您将其作为不再可变的参数传递。由于您的变量在 push 和 pop 中可见,因此您不需要将其作为参数。queue

这应该编译:

  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"
2赞 torbonde 11/14/2019 #2

您需要的是通过引用传递。然后,函数应如下所示:queuepush

let push x (queue: byref<_>) =
    printfn "%A" x
    queue <- (x::queue)

诸如此类jobQueue

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"

我还没有尝试过这段代码,但它至少应该让你入门。

顺便说一句,我想您知道 .Net 已经有一个 Queue 实现吗?