使用读取文件和列表在F#中进行不完整的模式匹配

时间:2016-02-15 00:57:07

标签: f# functional-programming

所以我有这段代码

let readLines filePath = System.IO.File.ReadLines(filePath);
let lines = Seq.toList (readLines "MovieSmall.txt");
let lines2 = List.map (fun (s:string) -> Array.toList (s.Split([|'\t'|]))) lines;
let imdb = List.map (fun (l1::l2::l3::l4::l5::l6::[]) -> [l1]::[l2]::[l3]:: (Array.toList ((l4:string).Split[|','|])) ::[l5]:: (Array.toList ((l6:string).Split[|','|])) ::[]) lines2;;

从名为MovieSmall的文件中获取数据并将其解析为字符串链接列表。

MovieSmall.txt看起来像这样

The Shawshank Redemption    1994    9.30    Crime, Drama     Frank Darabont  Morgan Freeman
The Godfather   1972    9.20    Crime, Drama     Francis Ford Coppola    Al Pacino,  James Caan,  Robert Duvall,  Diane Keaton,  Talia Shire
Universal's Cinematic Spectacular: 100 Years of Movie Memories  2012    9.20    Documentary, Short   Mike Aiello     Morgan Freeman

我得到了

  let imdb = List.map (fun (l1::l2::l3::l4::l5::l6::[]) -> [l1]::[l2]::[l3]:: (Array.toList ((l4:string).Split[|','|])) ::[l5]:: (Array.toList ((l6:string).Split[|','|])) ::[]) lines2;;
  --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^

stdin(4,27): warning FS0025: Incomplete pattern matches on this expression. For example, the value '[_;_;_;_;_;_;_]' may indicate a case not covered by the pattern(s).

我确信这是好的,因为提供给它的所有数据都具有上面的格式,但是当我运行时

let rec get_rating movie = function
    | [] -> "Not found";
    | [[title]; b; c; d; e; f]::t -> if title=movie then  (string)c else get_rating movie t;

get_rating "Batman Begins" imdb;;

我得到了

let rec get_rating movie = function
  ---------------------------^^^^^^^^

stdin(24,28): warning FS0025: Incomplete pattern matches on this expression. For example, the value '[[_;_;_;_;_;_;_]]' may indicate a case not covered by the pattern(s).

val get_rating :
  movie:'a -> _arg1:'a list list list -> string when 'a : equality
val it : string = "[8.30]"

添加

的情况
let rec get_rating movie = function
    | [] -> "Not found";
    | [[title]; b; c; d; e; f]::t -> if title=movie then  (string)c else get_rating movie t;
    |_-> "Does not match";

get_rating "Batman Begins" imdb;

阻止它发生我不知道如果这是接近这个的正确方法。 想法?

2 个答案:

答案 0 :(得分:4)

当您只想匹配所有可能模式的一小部分时,正如您在此处所做的那样,然后使用match完成_ -> default logic语句正是您想要做的。< / p>

F#编译器正在抛出该警告,因为当您将模式匹配不完整时,您会在意外数据通过时打开代码以运行时失败。在最后添加了| _ ->模式,可以指示在发生意外情况时要采取的操作。

简而言之,您通过在代码中使用_-> "Does not match"来采取正确的方法。

答案 1 :(得分:-1)

您可以禁用编译器警告:

#nowarn "25"