如何从递归函数中获取可辨识联合类型的值?F#递归代码类型不匹配错误排查与节点名称提取需求实现
Fixing FS0001 Type Mismatch & Building Paths to Target Systems in F#
Let's break down what's going wrong with your code and adjust it to get the full path from the root to the "Main Computer" system you're targeting.
First, Why the FS0001 Error Happens
Your SplitList2 function is mixing incompatible return types:
- When the input list is empty, you call
printfn "%A" []which returnsunit(no meaningful value), butJunctionPathis supposed to return astring list. - In the
head::tailbranch, you're trying to return a filtered list but still mixing it withprintfn—again forcingunitinto a function that needs to output a list.
Also, your Starship definition has a syntax error: Junction("Defence",) is missing the required list argument (use Junction("Defence", []) if it's an empty junction).
Revised Code to Get the Full Target Path
Here's a corrected version that properly builds the path from the root junction to your target system:
type PowerSystem = | System of string * int | Junction of string * List<PowerSystem> // Fixed syntax error in the Defence junction let Starship = Junction("Core", [ Junction("Users", [ System("Main Computer", -10); System("Library Computer", -10); Junction("Defence", []) // Added empty list parameter here ]) ]) // Recursive function to find all paths to a target system by name let rec findSystemPath targetName (pSystem: PowerSystem) = match pSystem with | System(name, _) -> // If this is our target, return a path containing just its name if name = targetName then [ [name] ] else [] | Junction(name, subSystems) -> // For each subsystem, get all matching paths, then prepend the current junction name to each path subSystems |> List.collect (findSystemPath targetName) |> List.map (fun path -> name :: path) // Retrieve paths to "Main Computer" let mainComputerPaths = findSystemPath "Main Computer" Starship printfn "%A" mainComputerPaths // Output: [["Core"; "Users"; "Main Computer"]]
Key Changes Explained
- Unified Return Type: The function returns
string list list(a list of paths, in case multiple systems share the same target name). Each path is astring listtracing from root to target. - Path Construction: When processing a
Junction, we recursively fetch paths from all its subsystems, then add the current junction's name to the start of each of those paths. - Target Matching: For
Systemnodes, we check if it's our target—if yes, return a single-element path; if not, return an empty list. - Syntax Fix: Corrected the incomplete
Defencejunction definition to avoid compilation errors.
Quick Usage Tip
If you only expect one matching system (like "Main Computer"), you can grab the first path directly:
let mainComputerPath = mainComputerPaths |> List.head printfn "Path to Main Computer: %A" mainComputerPath // Output: ["Core"; "Users"; "Main Computer"]
内容的提问来源于stack exchange,提问作者Alejandro Carvajal
相关产品推荐
相关产品推荐

