[英]F# Type Matching - Unable To Create Map Or Match Record
I have tried to adapt a WikiBooks example to accept csv input and types but am struggling with converting the incoming type list to a dictionary and matching user inputs. 我试图改编一个WikiBooks示例,以接受csv输入和类型,但是在将传入的类型列表转换为字典并匹配用户输入方面很费劲。
// 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; } ]
let countryCapitals =
readFromCsvFile sampleCsv
// -> |> Map.ofList
Console.Write("Find capital by country (type 'q' to quit): ")
match Console.ReadLine() with
| "q" -> Console.WriteLine("Bye!")
| country ->
match countryCapitals with
// -> | { Country = country } -> Console.WriteLine("Capital of {0} is {1}\n", country, capital)
| _ -> Console.WriteLine("Country not found.\n")
// Expected Output: Find capital by country (type 'q' to quit): Egypt
// Capital of Egypt is Cairo
What am I missing? 我想念什么?
You need to use a tuple to create the Map
from the List
, so you don't really need the record type at all. 您需要使用一个元组从List
创建Map
,因此您根本不需要记录类型。 Then, you will want to match on Map.tryFind
of the input country. 然后,您将要在输入国家/地区的Map.tryFind
上进行匹配。 Here's an example using the tuple and Map.tryFind
. 这是使用元组和Map.tryFind
。 The only other changes I made were to use printfn
instead of Console.WriteLine
and to simplify your list-generating expression: 我所做的唯一其他更改是使用printfn
而不是Console.WriteLine
并简化了列表生成表达式:
open System
open FSharp.Data
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 -> (row.Country, row.City) ]
let countryCapitals =
readFromCsvFile sampleCsv
|> Map.ofList
printfn "Find capital by country (type 'q' to quit): "
match Console.ReadLine() with
| "q" -> printfn "Bye!"
| country ->
match countryCapitals |> Map.tryFind country with
| Some capital -> printfn "Capital of %s is %s" country capital
| _ -> printfn "Country not found."
EDIT To show continued use of record type: 编辑以显示记录类型的继续使用:
open System
open FSharp.Data
type CountryCaptial = { Country: string; Capital: string }
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 -> { Country = row.Country; Capital = row.City } ]
let countryCapitals =
readFromCsvFile sampleCsv
|> List.map (fun c -> c.Country, c)
|> Map.ofList
printfn "Find capital by country (type 'q' to quit): "
match Console.ReadLine() with
| "q" -> printfn "Bye!"
| country ->
match countryCapitals |> Map.tryFind country with
| Some countryCapital -> printfn "Capital of %s is %s" countryCapital.Country countryCapital.Capital
| _ -> printfn "Country not found."
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.