Reputation: 241
So i have this code
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;;
That gets data from a file called MovieSmall and parses it into a String Linked List.
MovieSmall.txt looks like this
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
I get
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).
Which I'm sure is ok because all the data fed to it will have the format above, but when I run
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;;
i get
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]"
While adding the case of
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;
Stops it from happening I dunno if this is the correct way to approach this. Thoughts?
Upvotes: 0
Views: 292
Reputation: 1109
When you only want to match on a small subset of all the possible patterns, as you're doing here, then finishing the match
statement with _ -> default logic
is exactly what you want to do.
The F# compiler is throwing that warning because when you leave your pattern matches incomplete you're opening your code up to run time failures when unexpected data comes through. Added the | _ ->
pattern at the end lets you dictate what action to take when something unexpected happens.
Long story short, you're taking the right approach by having the _-> "Does not match"
in your code.
Upvotes: 4