【问题标题】:Value restriction in F#F# 中的值限制
【发布时间】:2013-01-26 21:09:41
【问题描述】:

我有一个 F# 任务,我正在尝试计算矩阵的转置。很简单,但我不断收到价值限制错误,我不知道为什么。我咨询了许多存在的 VR 错误问题,但我仍然一无所知。这是我的代码:

let transpose = function
    | [xs ; ys] -> 
                let rec transpose_helper = function
                    | [],[] -> []
                    | x::xs , y::ys -> [x;y] :: transpose_helper (xs,ys)
                    | _ -> failwith "The matrix is not a square matrix"
                transpose_helper(xs,ys)
    | _ -> failwith "Incorrectly formatted input"

transpose ([[1;2;3];[2;3;4]]);;

我认为错误的部分原因是空列表,但我所做的似乎无济于事。任何指针将不胜感激。

编辑:以下版本的代码有效。谁能解释一下为什么

let transpose zs =
    match zs with 
    | [xs;ys] -> 
                let rec transpose_helper (xs, ys) = 
                    match (xs,ys) with
                    | ([],[]) -> []
                    | (x::xs , y::ys) -> [x;y] :: transpose_helper (xs,ys)
                    | _ -> failwith "The matrix is not a square matrix"
                transpose_helper(xs,ys)
    | _ -> failwith "Incorrectly formatted input"

transpose ([[1;2;3];[2;3;4]]);;

val transpose : zs:'a list list -> 'a list list
val it : int list list = [[1; 2]; [2; 3]; [3; 4]]

但是,编译器仍然抱怨上面的转置调用应该有一个单元类型,除非我使用 let 绑定它。谁能澄清一下这里发生了什么?

【问题讨论】:

  • 出于好奇,哪所学校会给你一个 F# 作业?

标签: f# value-restriction


【解决方案1】:

我的猜测是你最初写了这个let rec transpose zs = match zs with ...,后来改用function,这样就不需要显式参数了。由于zs 仍然存在,您的函数接受两个参数,这意味着您只是部分应用它。由于 zs 未使用,其类型未知,因此您的部分应用函数返回通用函数 value(值限制)。删除zs,一切正常。

【讨论】:

  • 我为迟到的评论道歉:不幸的是,这似乎并没有解决问题,价值限制错误仍然存​​在。我已经使初始函数成为非递归函数,因为我发现它也没有必要。将其强制转换(可能是 int 列表)似乎也不起作用。
  • 我添加了一个使用 match ... with ... 模式的代码的工作版本,但我不确定 为什么 它首先可以工作当我仍然收到有关类型的警告时。如果您能澄清一下,我将不胜感激!
  • 编辑后,您的transpose 函数是等效的并且可以工作。可以通过使用 let 或管道忽略 (|> ignore) 绑定结果来修复最新的错误。
  • 感谢您的跟进。
猜你喜欢
  • 2011-05-03
  • 1970-01-01
  • 2020-07-29
  • 2012-03-13
  • 2015-06-15
  • 2010-11-11
  • 1970-01-01
相关资源
最近更新 更多