【问题标题】:F# If-statement type mismatch errorsF# If 语句类型不匹配错误
【发布时间】:2021-01-19 10:48:54
【问题描述】:

我是一个相对较新的 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”,并被隐式忽略。考虑使用 'ignore' 显式丢弃该值,例如'expr |> ignore' 或 'let' 将结果绑定到一个名称,例如'让结果 = expr'。

错误 FS0001:此表达式应具有类型 ''列表列表'
但这里有类型 '结果'

提前致谢

【问题讨论】:

    标签: list recursion error-handling f# type-conversion


    【解决方案1】:

    关键问题是您试图将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) ]
    

    您必须确保处理异常,如果您在整个项目中使用Result,您可能希望将它们转换为Error 值,但这样代码会变得更简单。

    【讨论】:

      猜你喜欢
      • 2021-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-22
      • 1970-01-01
      • 2015-03-18
      • 2013-07-29
      • 1970-01-01
      相关资源
      最近更新 更多