【问题标题】:How can I get values with discriminited union type from recursive function如何从递归函数中获取具有区分联合类型的值
【发布时间】:2021-12-30 10:15:37
【问题描述】:

我正在尝试从一个具有多重递归的列表中获取特定值,所以我有:

    type PowerSystem =
      | System of string * int
      | Junction of string * List<PowerSystem>
    
    let Starship =
      Junction("Core", 
        [ 
          Junction("Users",
                [
                System("Main Computer",-10);
                System("Library Computer",-10);
                Junction("Defence",)]
 let rec JunctionPath (pSystem:PowerSystem) =
    match pSystem with
    | Junction(name,aList) ->  SplitList2 aList
    | System(name,aNumber) ->   [name]

 
  
and SplitList2 list =
    match list with 
    | [] -> printfn "%A" []
    | head::tail -> printfn "%A" List.filter (fun e->e="Port Phasers" (JunctionPath head)@(SplitList2 tail))

JunctionPath Starship

我收到错误 FS0001:类型“a -> 字符串列表”与类型“单元”不匹配

我想在系统调用主计算机时获取连接的名称,但我不能调用其他函数。我尝试以不同的方式获得这些值,但我找不到方法。提前致谢

【问题讨论】:

  • 顺便说一句,您错过了 let Startship = ... 中的右方括号

标签: f# f#-interactive


【解决方案1】:

SplitList2 仅具有 printfn 的副作用,因此返回单位 ()

JunctionPath 中,第一个分支返回一个字符串列表 - [name] - 而第二个分支返回一个 unit,因为调用了 SplitList2。这是不允许的,因为两个(通常所有)模式匹配分支都应该返回相同的类型。这就是为什么您会收到错误“错误 FS0001:类型 ''a -> string list' 与类型 'unit' 不匹配” (如果您以后注意错误中的行引用,因为它指向有问题的行,会更清楚)。

现在回答你的最后一点:

我想在系统调用 Main 时获取联结的名称 电脑,但我不能调用其他功能。我尝试了不同的方式 获取这些值,但我找不到方法。

这是没有意义的,因为什么是“端口移相器”?无论如何,未经测试,我已修改 SplitList2 以返回任一分支上的列表。然后我们将JunctionPath 的结果通过管道传输到 printfn 中。但是List.filter (fun e-&gt;e="Port Phasers" (JunctionPath head)@(SplitList2 tail)) 行的逻辑仍然没有意义,所以我更新了它,因为我认为你的意思是它(尽管你应该有另一个错误?)。 (这不是尾递归,可以改进,但一步一步)

  type PowerSystem =
      | System of string * int
      | Junction of string * List<PowerSystem>
    
    let Starship =
      Junction("Core", 
        [ 
          Junction("Users",
                [
                System("Main Computer",-10);
                System("Library Computer",-10);
                Junction("Defence",)]
 let rec JunctionPath (pSystem:PowerSystem) =
    match pSystem with
    | Junction(name,aList) ->  SplitList2 aList
    | System(name,aNumber) ->   [name]

 and SplitList2 list =
    match list with 
    | [] ->  []
    | head::tail -> List.filter (fun e->e="Port Phasers") (JunctionPath head)@(SplitList2 tail))

JunctionPath Starship |> printfn "%A%

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    • 2017-05-12
    • 1970-01-01
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    相关资源
    最近更新 更多