You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

F#类型匹配问题:无法创建映射或匹配记录

解决F#中CSV转Map及用户输入匹配的问题

我看了你这段改编自WikiBooks的代码,问题主要出在两个核心点上:没有把读取到的列表转换成可快速查找的Map,以及匹配用户输入的逻辑完全没关联到数据的查找上。咱们一步步来修正:

问题分析

  1. 你注释掉了|> Map.ofList,导致countryCapitals还是一个普通列表,没法通过国家名快速定位首都;
  2. 匹配部分直接对着整个countryCapitals列表做匹配,没有根据用户输入的国家去检索对应的记录,逻辑完全不对。

修改后的完整代码

// https://en.wikibooks.org/wiki/F_Sharp_Programming/Sets_and_Maps#Examples_2
module SOQN =
    open System
    open FSharp.Data

    type Country = Country of string
    type City = City of string
    type CountryCapital = { Country:Country; City:City }

    let [<Literal>] sampleCsv = @"D:\Country_Capitals.csv"
    type Capitals = CsvProvider<sampleCsv, Separators=",", HasHeaders=true>

    let readFromCsvFile (fileName:string) =
        let data = Capitals.Load(fileName)
        [ for row in data.Rows do
            yield { Country = Country row.Country; City = City row.City; } ]

    // 关键修改1:将列表转换为以Country为键、City为值的Map,实现O(1)查找
    let countryCapitals = 
        readFromCsvFile sampleCsv
        |> List.map (fun capitalEntry -> capitalEntry.Country, capitalEntry.City)
        |> Map.ofList

    // 关键修改2:添加递归循环,支持用户多次查询
    let rec queryCapital () =
        Console.Write("Find capital by country (type 'q' to quit): ")
        match Console.ReadLine().Trim() with
        | "q" -> Console.WriteLine("Bye!")
        | inputCountry ->
            // 将输入字符串包装为Country类型,与Map的键类型匹配
            let targetCountry = Country inputCountry
            match Map.tryFind targetCountry countryCapitals with
            | Some (City capitalName) -> 
                Console.WriteLine($"Capital of {inputCountry} is {capitalName}\n")
                queryCapital () // 继续等待下一次查询
            | None -> 
                Console.WriteLine($"Country '{inputCountry}' not found.\n")
                queryCapital () // 继续等待下一次查询

    // 启动查询交互
    queryCapital ()

核心修改点说明

  • 转换为Map:用List.map把每个CountryCapital对象拆解成(Country, City)键值对,再通过Map.ofList生成Map结构,这样查找首都的效率从列表的O(n)变成了Map的O(1);
  • 正确的匹配逻辑:用Map.tryFind来检索用户输入的国家,它会返回Some City(找到时)或None(未找到时),完美覆盖两种场景;
  • 循环交互:添加了递归函数queryCapital,用户完成一次查询后会回到输入提示,直到输入q才退出,更符合实际使用需求;
  • 类型安全:保持了Country和City的类型包装,避免直接使用裸字符串带来的类型风险,同时确保查找时的键类型一致。

内容的提问来源于stack exchange,提问作者matekus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:13:20