我是一个相对较新的F#程序员,似乎每次我在代码中解决一个问题时,就会出现另一个问题,所以我的问题在转置递归函数内部,我想在其中运行if-else语句来检查输入是否真正有效是否,但是此错误并不能确定原因或解决方法。
我已经有一个问题和标题非常相似的问题,但是由于种种原因,我被告知要提出一个新问题而不是编辑旧问题。
type Result<'T,'TError> =
| Ok of 'T
| Error of 'TError
let isValidTBL list =
match List.map List.length list |> List.distinct |> List.length with
| 1 -> true
| _ -> false
let Column_1 list =
if List.exists List.isEmpty list then [] // return empty list
else
list |> List.map List.head
let Column_2 list =
if List.exists List.isEmpty list then
Error "empty value"
else
list |> List.map List.tail |> Ok
let rec transpose list = [
if (isValidTBL list = false) then Error "Invalid Table"
else
match list with
| []::list -> ()
| list ->
yield Column_1 list
yield! transpose (Column_2 list) ]
警告FS0020:此表达式的结果类型为'Result <'a,string>',并且被隐式忽略。考虑使用“忽略”来显式丢弃该值,例如“ expr |>忽略”,或使用“ let”将结果绑定到名称,例如“ let result = expr”。
错误FS0001:该表达式应具有类型“ a list list”,
但此处具有类型“ Result <'b list list,string>”
提前致谢
关键问题是您正在尝试将其Result
与普通F#混合使用list
。当您处于列表理解内时,只能使用来返回值yield
,因此在编写时:
let rec transpose list = [
if (isValidTBL list = false) then Error "Invalid Table"
else
yield // (...)
]
具有的部分Error "Invalid table"
不是返回值,而只是您创建然后忽略的值。仅在以下Ok
情况下,您可以通过重新排列代码以启动列表理解来解决此问题:
let rec transpose list =
if (isValidTBL list = false) then Error "Invalid Table"
else Ok [
yield // (...)
]
但是,这也不能解决所有问题,因为您希望进行递归调用,transpose
并且如果这也包含在理解范围内,那么返回错误“为时已晚”。
您可以编写此代码而无需理解,但是老实说,如果您仅使用异常处理错误,我认为这样做会容易得多:
exception InvalidTable
exception EmptyValue
let Column_2 list =
if List.exists List.isEmpty list then raise EmptyValue
else list |> List.map List.tail
let rec transpose list = [
if (isValidTBL list = false) then raise InvalidTable
else
match list with
| []::list -> ()
| list ->
yield Column_1 list
yield! transpose (Column_2 list) ]
您必须确保处理异常,并且Error
如果您在Result
整个项目中都在使用它们,则可能需要将它们转换为值,但是这种方式的代码变得更加简单。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句