Using incomplete pattern matching as filter? - f#

Suppose I have the following code:
type Vehicle =
| Car of string * int
| Bike of string
let xs = [ Car("family", 8); Bike("racing"); Car("sports", 2); Bike("chopper") ]
I can filter above list using incomplete pattern matching in an imperative for loop like:
> for Car(kind, _) in xs do
> printfn "found %s" kind;;
found family
found sports
val it : unit = ()
but it will cause a:warning FS0025: Incomplete pattern matches on this expression. For example, the value 'Bike (_)' may indicate a case not covered by the pattern(s). Unmatched elements will be ignored.
As the ignoring of unmatched elements is my intention, is there a possibility to get rid of this warning?
And is there a way to make this work with list-comprehensions without causing a MatchFailureException? e.g. something like that:
> [for Car(_, seats) in xs -> seats] |> List.sum;;
val it : int = 10

Two years ago, your code was valid and it was the standard way to do it. Then, the language has been cleaned up and the design decision was to favour the explicit syntax. For this reason, I think it's not a good idea to ignore the warning.
The standard replacement for your code is:
for x in xs do
match x with
| Car(kind, _) -> printfn "found %s" kind
| _ -> ()
(you could also use high-order functions has in pad sample)
For the other one, List.sumBy would fit well:
xs |> List.sumBy (function Car(_, seats) -> seats | _ -> 0)
If you prefer to stick with comprehensions, this is the explicit syntax:
[for x in xs do
match x with
| Car(_, seats) -> yield seats
| _ -> ()
] |> List.sum

You can silence any warning via the #nowarn directive or --nowarn: compiler option (pass the warning number, here 25 as in FS0025).
But more generally, no, the best thing is to explicitly filter, as in the other answer (e.g. with choose).

To explicitly state that you want to ignore unmatched cases, you can use List.choose and return None for those unmatched elements. Your codes could be written in a more idomatic way as follows:
let _ = xs |> List.choose (function | Car(kind, _) -> Some kind
| _ -> None)
|> List.iter (printfn "found %s")
let sum = xs |> List.choose (function | Car(_, seats)-> Some seats
| _ -> None)
|> List.sum

Related

Trying to compare length of each sub-list (learning about lambda and list modules)

I'm trying to make a function that checks a lists sublists to see if they have equal length and returns a bool value.
[ [1;2;3]; [4;5;6] ] (return true)
[ [1;2;3]; [4;5] ] (return false)
I'm trying to learn about lambda's and list modules.
So far I have:
let isTable (lst : 'a list list) : bool =
List.forall (fun x -> x.Length = 2) ([ [1;2;3]; [4;5;6] ])
It says x.Length is wrong somehow.
Can someone explain what I am doing wrong?
The problem with your code is that the F# type inference does not know what is type of x when checking the lambda function and so it cannot check whether the object will have a member Length. The type inference checks your program from left to right and so it only figures out that x will be a list when it gets to the argument [ [1;2;3]; [4;5;6] ] later in your code.
There is a couple of ways to fix this. You can use List.length which is a function and not an instance member, so the inference can check that:
let isTable (lst : 'a list list) : bool =
List.forall (fun x -> List.length x = 2) [ [1;2;3]; [4;5;6] ]
A nicer alternative is to use the |> operator which passes the thing on the left to the function on the right, so writing x |> f is the same as calling f x. This puts the input to the left, so the inference will work:
let isTable (lst : 'a list list) : bool =
[ [1;2;3]; [4;5;6] ] |> List.forall (fun x -> x.Length x = 2)
Finally, you could also add a type annotation:
let isTable (lst : 'a list list) : bool =
List.forall (fun (x:_ list) -> x.Length = 2) [ [1;2;3]; [4;5;6] ]
Out of these three, I think the most idiomatic solution is to use |>, but List.length is also common.
Try this code:
let isTable (lst: 'a list list) =
match lst with
| [] | [[]] -> false
| []::t -> false
| [_] -> true
| h::t -> t |> List.forall(fun l -> l.Length = h.Length)
The issue you are having is that the type inference system of F# does not firmly recognize x as being a list at the point where you want to do x.Length. That may seem strange because if you use Intellisense (for instance by hovering over x) it will tell you that it is a list, yet the compiler complains.
The reason for that is that F#'s type inference does not work as well when working with Object Oriented (OO) dot . notation, it does much better when using functional dot . notation. To differentiate between the two, the convention in F# (and .Net) is that class members (methods and properties) start with a capital letter (also known as Pascal Case) hence x.Length. On the other hand, functional style code (like functions in a module and/or record members) start with a lower case (known as Camel Case) like List.length.
Notice the difference between the 2 styles:
OO, invoke a method: x.Length
Functional, call a function: List.length x
If you want to use the OO style, typically the solution is to add a type annotation, which you can do in several ways:
fun (x:_ list) -> x.Length = 2
fun x -> (x:_ list).Length = 2
In general, it is better practice to use the functional style. But, you do not always have a choice. For instance there are many String methods that do not have a functional equivalent:
fun (s:string) -> s.StartsWith "Hello"
I also would like to point out that your code as stated does not really do what you want. It returns true only if all lists are of length 2, not if all of them are the same length.
kagetoki's solution works and also demonstrates the use of pattern matching for lists.
Here is a simplified version:
let isTable lst =
match lst with
| h::t -> t |> List.forall(fun (l:_ list) -> l.Length = h.Length)
| _ -> true
Notice that by stating that l is a list, it already knows that h is also a list.
Finally, just for fun, a super compact (but obscure) version :
let isTable =
function
| h::t -> t |> List.forall (List.length >> (=) h.Length)
| _ -> true

Match with empty sequence

I'm learning F# and I've started to play around with both sequences and match expressions.
I'm writing a web scraper that's looking through HTML similar to the following and taking the last URL in a parent <span> with the paging class.
<html>
<body>
<span class="paging">
Link to Google
The Link I want
</span>
</body>
</html>
My attempt to get the last URL is as follows:
type AnHtmlPage = FSharp.Data.HtmlProvider<"http://somesite.com">
let findMaxPageNumber (page:AnHtmlPage)=
page.Html.Descendants()
|> Seq.filter(fun n -> n.HasClass("paging"))
|> Seq.collect(fun n -> n.Descendants() |> Seq.filter(fun m -> m.HasName("a")))
|> Seq.last
|> fun n -> n.AttributeValue("href")
However I'm running into issues when the class I'm searching for is absent from the page. In particular I get ArgumentExceptions with the message: Additional information: The input sequence was empty.
My first thought was to build another function that matched empty sequences and returned an empty string when the paging class wasn't found on a page.
let findUrlOrReturnEmptyString (span:seq<HtmlNode>) =
match span with
| Seq.empty -> String.Empty // <----- This is invalid
| span -> span
|> Seq.collect(fun (n:HtmlNode) -> n.Descendants() |> Seq.filter(fun m -> m.HasName("a")))
|> Seq.last
|> fun n -> n.AttributeValue("href")
let findMaxPageNumber (page:AnHtmlPage)=
page.Html.Descendants()
|> Seq.filter(fun n -> n.HasClass("paging"))
|> findUrlOrReturnEmptyStrin
My issue is now that Seq.Empty is not a literal and cannot be used in a pattern. Most examples with pattern matching specify empty lists [] in their patterns so I'm wondering: How can I use a similar approach and match empty sequences?
The suggestion that ildjarn gave in the comments is a good one: if you feel that using match would create more readable code, then make an active pattern to check for empty seqs:
let (|EmptySeq|_|) a = if Seq.isEmpty a then Some () else None
let s0 = Seq.empty<int>
match s0 with
| EmptySeq -> "empty"
| _ -> "not empty"
Run that in F# interactive, and the result will be "empty".
You can use a when guard to further qualify the case:
match span with
| sequence when Seq.isEmpty sequence -> String.Empty
| span -> span
|> Seq.collect (fun (n: HtmlNode) ->
n.Descendants()
|> Seq.filter (fun m -> m.HasName("a")))
|> Seq.last
|> fun n -> n.AttributeValue("href")
ildjarn is correct in that in this case, an if...then...else may be the more readable alternative, though.
Use a guard clause
match myseq with
| s when Seq.isEmpty s -> "empty"
| _ -> "not empty"
Building on the answer from #rmunn, you can make a more general sequence equality active pattern.
let (|Seq|_|) test input =
if Seq.compareWith Operators.compare input test = 0
then Some ()
else None
match [] with
| Seq [] -> "empty"
| _ -> "not empty"

fold or choose till None?

Is there already a way to do something like a chooseTill or a foldTill, where it will process until a None option is received? Really, any of the higher order functions with a "till" option. Granted, it makes no sense for stuff like map, but I find I need this kind of thing pretty often and I wanted to make sure I wasn't reinventing the wheel.
In general, it'd be pretty easy to write something like this, but I'm curious if there is already a way to do this, or if this exists in some known library?
let chooseTill predicate (sequence:seq<'a>) =
seq {
let finished = ref false
for elem in sequence do
if not !finished then
match predicate elem with
| Some(x) -> yield x
| None -> finished := true
}
let foldTill predicate seed list =
let rec foldTill' acc = function
| [] -> acc
| (h::t) -> match predicate acc h with
| Some(x) -> foldTill' x t
| None -> acc
foldTill' seed list
let (++) a b = a.ToString() + b.ToString()
let abcdef = foldTill (fun acc v ->
if Char.IsWhiteSpace v then None
else Some(acc ++ v)) "" ("abcdef ghi" |> Seq.toList)
// result is "abcdef"
I think you can get that easily by combining Seq.scan and Seq.takeWhile:
open System
"abcdef ghi"
|> Seq.scan (fun (_, state) c -> c, (string c) + state) ('x', "")
|> Seq.takeWhile (fst >> Char.IsWhiteSpace >> not)
|> Seq.last |> snd
The idea is that Seq.scan is doing something like Seq.fold, but instead of waiting for the final result, it yields the intermediate states as it goes. You can then keep taking the intermediate states until you reach the end. In the above example, the state is the current character and the concatenated string (so that we can check if the character was whitespace).
A more general version based on a function that returns option could look like this:
let foldWhile f initial input =
// Generate sequence of all intermediate states
input |> Seq.scan (fun stateOpt inp ->
// If the current state is not 'None', then calculate a new one
// if 'f' returns 'None' then the overall result will be 'None'
stateOpt |> Option.bind (fun state -> f state inp)) (Some initial)
// Take only 'Some' states and get the last one
|> Seq.takeWhile Option.isSome
|> Seq.last |> Option.get

Confused with F# List.Fold (powerset function)

I understand and wrote a typical power set function in F# (similar to the Algorithms section in Wikipedia)
Later I found this implementation of powerset which seems nice and compact, expect that I do not understand it.
let rec powerset = function
| [] -> [[]]
| h::t -> List.fold (fun xs t -> (h::t)::t::xs) [] (powerset t);
I broke this down to a 1 step non-recursive function to find the powerset of [1;2] and hardcoded the value of power set of 2 at the end [[2]; []]
let right = function
| [] -> [[]]
| h::t -> List.fold (fun acc t -> (h::t)::t::acc) [] [[2]; []];
The output is [[1]; []; [1; 2]; [2]] which is correct.
However I was expecting List.Fold to output [[1; 2]; []; [1; 2]; [2]].
Since I was not certain about the 't', I modified the variable names, and I did get what I had expected. Of course this is not the correct powerset of [1;2].
let wrong = function
| [] -> [[]]
| h::t -> List.fold (fun acc data -> (h::t)::data::acc) [] [[2]; []];
For me 't' (the one withing fun and not the h::t) is simply a name for the second argument to 'fun' but that is obviously not the case. So what is the difference in the "right" and "wrong" F# functions I have written ? And what exactly does 't' here refer to ?
Thank you ! (I am new to F#)
In your "right" example, t is originally the name of the value bound in the pattern match, but it is hidden by the parameter t in the lambda expression passed to List.fold. Whereas in your "wrong" example, t is captured as a closure in the lambda expression. I think maybe you don't intend this capture, instead you want:
//now it works as you expect, replaced "t" with "data" in your lambda expression.
let wrong = function
| [] -> [[]]
| h::t -> List.fold (fun acc data -> (h::data)::data::acc) [] [[2]; []];
let rec powerset = function
| [] -> [[]]
| h::t -> List.fold (fun xs t -> (h::t)::t::xs) [] (powerset t);
here is the understanding/english translation of the code:
if the list (you want to power) is empty, then return a list, which contains an empty list in it
if the list is h::t (with head h and the rest as t, so h is an element and t is a list). then:
A. (powerset t): calculate the power set of t
B. (fun xs t -> (h::t)::t::xs) means that you apply/fold this function to the (powerset t). more details: xs is an accumulator, it is initialized to []. xxx::xs means you add something to an existing powerest xs. Here xxx is (h::t)::t, which are two elements to be added to the head of xs. (h::t) means add head to t and t means each element in (powerset t). <- the confusing part lies in t, the t in (powerset t) is the rest of the list, while the other t means an element in (powerset t).
here is an imperative translation of the fold function :
let h::t = list
let setfort = powerset t
xs <- []
foreach s in setfort do
xs <- xs.add(t) // t is a valid subset of list
xs <- xs.add(h::t) // t with h is also a valid subset of list
t is a variable bound by pattern matching. List.fold is a fancy way of avoiding explicit looping. Now, go and read some introductory tutorials about F#.

How to code Fizzbuzz in F#

I am currently learning F# and have tried (an extremely) simple example of FizzBuzz.
This is my initial attempt:
for x in 1..100 do
if x % 3 = 0 && x % 5 = 0 then printfn "FizzBuzz"
elif x % 3 = 0 then printfn "Fizz"
elif x % 5 = 0 then printfn "Buzz"
else printfn "%d" x
What solutions could be more elegant/simple/better (explaining why) using F# to solve this problem?
Note: The FizzBuzz problem is going through the numbers 1 to 100 and every multiple of 3 prints Fizz, every multiple of 5 prints Buzz, every multiple of both 3 AND 5 prints FizzBuzz. Otherwise, simple the number is displayed.
Thanks :)
I think you already have the "best" solution.
If you want to show off more functional/F#-isms, you could do e.g.
[1..100]
|> Seq.map (function
| x when x%5=0 && x%3=0 -> "FizzBuzz"
| x when x%3=0 -> "Fizz"
| x when x%5=0 -> "Buzz"
| x -> string x)
|> Seq.iter (printfn "%s")
and use lists, sequences, map, iter, patterns, and partial application.
[1..100] // I am the list of numbers 1-100.
// F# has immutable singly-linked lists.
// List literals use square brackets.
|> // I am the pipeline operator.
// "x |> f" is just another way to write "f x".
// It is a common idiom to "pipe" data through
// a bunch of transformative functions.
Seq.map // "Seq" means "sequence", in F# such sequences
// are just another name for IEnumerable<T>.
// "map" is a function in the "Seq" module that
// applies a function to every element of a
// sequence, returning a new sequence of results.
(function // The function keyword is one way to
// write a lambda, it means the same
// thing as "fun z -> match z with".
// "fun" starts a lambda.
// "match expr with" starts a pattern
// match, that then has |cases.
| x when x%5=0 && x%3=0
// I'm a pattern. The pattern is "x", which is
// just an identifier pattern that matches any
// value and binds the name (x) to that value.
// The "when" clause is a guard - the pattern
// will only match if the guard predicate is true.
-> "FizzBuzz"
// After each pattern is "-> expr" which is
// the thing evaluated if the pattern matches.
// If this pattern matches, we return that
// string literal "FizzBuzz".
| x when x%3=0 -> "Fizz"
// Patterns are evaluated in order, just like
// if...elif...elif...else, which is why we did
// the 'divisble-by-both' check first.
| x when x%5=0 -> "Buzz"
| x -> string x)
// "string" is a function that converts its argument
// to a string. F# is statically-typed, so all the
// patterns have to evaluate to the same type, so the
// return value of the map call can be e.g. an
// IEnumerable<string> (aka seq<string>).
|> // Another pipeline; pipe the prior sequence into...
Seq.iter // iter applies a function to every element of a
// sequence, but the function should return "unit"
// (like "void"), and iter itself returns unit.
// Whereas sequences are lazy, "iter" will "force"
// the sequence since it needs to apply the function
// to each element only for its effects.
(printfn "%s")
// F# has type-safe printing; printfn "%s" expr
// requires expr to have type string. Usual kind of
// %d for integers, etc. Here we have partially
// applied printfn, it's a function still expecting
// the string, so this is a one-argument function
// that is appropriate to hand to iter. Hurrah!
My example is just a minor improvement over the code posted by 'ssp'. It uses parameterized active patterns (which take the divisor as an argument). Here is a more in-depth explanation:
The following defines an active pattern that we can later use in the match
expression to test if a value i is divisible by a value divisor. When we write:
match 9 with
| DivisibleBy 3 -> ...
...it means that the value '9' will be passed to the following function as i and the value 3 will be passed as divisor. The name (|DivisibleBy|_|) is a special syntax, whith means that we're declaring an active pattern (and the name can appear in the
match on the left side of ->. The |_| bit means that the pattern can fail (our example fails when value is not divisible by divisor)
let (|DivisibleBy|_|) divisor i =
// If the value is divisible, then we return 'Some()' which
// represents that the active pattern succeeds - the '()' notation
// means that we don't return any value from the pattern (if we
// returned for example 'Some(i/divisor)' the use would be:
// match 6 with
// | DivisibleBy 3 res -> .. (res would be asigned value 2)
// None means that pattern failed and that the next clause should
// be tried (by the match expression)
if i % divisor = 0 then Some () else None
Now we can iterate over all the numbers and match them against patterns (our active pattern) using match (or using Seq.iter or some other technique as shown in other answers):
for i in 1..100 do
match i with
// & allows us to run more than one pattern on the argument 'i'
// so this calls 'DivisibleBy 3 i' and 'DivisibleBy 5 i' and it
// succeeds (and runs the body) only if both of them return 'Some()'
| DivisibleBy 3 & DivisibleBy 5 -> printfn "FizzBuzz"
| DivisibleBy 3 -> printfn "Fizz"
| DivisibleBy 5 -> printfn "Buzz"
| _ -> printfn "%d" i
For more information on F# active patterns, here is an MSDN documentation link. I think that if you remove all the comments, the code will be slightly more readable than the original version. It shows some quite useful tricks :-), but in your case, the task is relatively easy...
Yet one solution in F# style (i.e. with Active Patterns usage):
let (|P3|_|) i = if i % 3 = 0 then Some i else None
let (|P5|_|) i = if i % 5 = 0 then Some i else None
let f = function
| P3 _ & P5 _ -> printfn "FizzBuzz"
| P3 _ -> printfn "Fizz"
| P5 _ -> printfn "Buzz"
| x -> printfn "%d" x
Seq.iter f {1..100}
//or
for i in 1..100 do f i
To add one more possible answer - here is another approach without pattern matching. It uses the fact that Fizz + Buzz = FizzBuzz, so you don't actually need to test for all three cases, you only need to see if it is divisible by 3 (then print "Fizz") and also see if it is divisible by 5 (then print "Buzz") and finally, print a new line:
for i in 1..100 do
for divisor, str in [ (3, "Fizz"); (5, "Buzz") ] do
if i % divisor = 0 then printf "%s" str
printfn ""
The nested for loop assignes 3 and "Fizz" to divisor and str in the first iteration and then the second pair of values in the second iteration. The beneift is, you could easily add printing of "Jezz" when the value is divisible by 7 :-) ...in case that extensibility of the solution is a concern!
Here's one more:
let fizzy num =
match num%3, num%5 with
| 0,0 -> "fizzbuzz"
| 0,_ -> "fizz"
| _,0 -> "buzz"
| _,_ -> num.ToString()
[1..100]
|> List.map fizzy
|> List.iter (fun (s:string) -> printfn "%s" s)
I find this to be a bit more readable answer edited was inspired a bit by the others
let FizzBuzz n =
match n%3,n%5 with
| 0,0 -> "FizzBuzz"
| 0,_ -> "Fizz"
| _,0 -> "Buzz"
| _,_ -> string n
[1..100]
|> Seq.map (fun n -> FizzBuzz n)
|> Seq.iter (printfn "%s")
Here is my version:
//initialize array a with values from 1 to 100
let a = Array.init 100 (fun x -> x + 1)
//iterate over array and match *indexes* x
Array.iter (fun x ->
match x with
| _ when x % 15 = 0 -> printfn "FizzBuzz"
| _ when x % 5 = 0 -> printfn "Buzz"
| _ when x % 3 = 0 -> printfn "Fizz"
| _ -> printfn "%d" x
) a
This is my first program in F#.
It's not perfect, but I think someone who starts learning F# (like me :)) can figure out what happens here quite fast.
However I am wondering what is the difference between matching to any _ or to x itself in pattern matching above?
I couldn't find a working solution that didn't include testing for i % 15 = 0. I've always felt that not testing for that is part of this "stupid" assignment. Be aware that this is probably not idiomatic F# since it's my first program in the language.
for n in 1..100 do
let s = seq {
if n % 3 = 0 then yield "Fizz"
if n % 5 = 0 then yield "Buzz" }
if Seq.isEmpty s then printf "%d"n
printfn "%s"(s |> String.concat "")
Here's a version emphasizing a generic tuple list of carbonations:
let carbonations = [(3, "Spizz") ; (5, "Fuzz"); (15, "SpizzFuzz");
(30, "DIZZZZZZZZ"); (18, "WHIIIIII")]
let revCarbonated = carbonations |> List.sort |> List.rev
let carbonRoute someCarbonations findMe =
match(List.tryFind (fun (x,_) -> findMe % x = 0) someCarbonations) with
| Some x -> printfn "%d - %s" findMe (snd x)
| None -> printfn "%d" findMe
let composeCarbonRoute = carbonRoute revCarbonated
[1..100] |> List.iter composeCarbonRoute
I don't like all these repeated strings, here's mine:
open System
let ar = [| "Fizz"; "Buzz"; |]
[1..100] |> List.map (fun i ->
match i % 3 = 0, i % 5 = 0 with
| true, false -> ar.[0]
| false, true -> ar.[1]
| true, true -> ar |> String.Concat
| _ -> string i
|> printf "%s\n"
)
|> ignore
Here is an attempt that factors out the modulo checks
let DivisibleBy x y = y % x = 0
[ 1 .. 100 ]
|> List.map (function
| x when DivisibleBy (3 * 5) x -> "fizzbuzz"
| x when DivisibleBy 3 x -> "fizz"
| x when DivisibleBy 5 x -> "buzz"
| x -> string x)
|> List.iter (fun x -> printfn "%s" x)
Here is how I refined it

Resources