I'm fairly new to F# and I wanted to compare two values with the (match ... with ...) syntax
The problem arises when I attempt to compare two values like this:
let value1 = 19
let isValue1 y =
match y with
| value1 -> y + 1
| _ -> y
I get a warning that the "| _ -> y" portion of the code will never be reached. Why is this?
I know that I can do the following to get the function to work the way I want it to:
let value1 = 19
let isValue1 y =
match y with
| _ when y = value1 -> true
| _ -> false
This works as well
let value1 = 19
let isValue1 y =
match y with
| 19 -> true
| _ -> false
I'm just curious about why I can't do that, and how match actually works.
The value1 within the match statement is defined as a new variable, the value of which is set to y (as a match). The value1 you define just above is ignored, just as if you were declaring a local variable in a C# function with the same name as a class variable. For this reason, the first match condition will match everything, not just the previously defined value of value1, hence the error. Hope that clarifies matters.
Pattern-matching is both a control construct (what code executes next) and a binding construct (like 'let', bind a name to a value). So when you do
match expr with
| name -> ...
the pattern ("name") always matches and the identifier 'name' just gets bound to the value of the expression. This is why pattern-matching is mostly used with discriminated unions (case types), where you match based on the structure. E.g.
match someOption with
| Some(x) -> ... // binds x
| None -> ...
match someList with
| h :: t -> ... // binds h and t to head/tail
| [] -> ...
You can just match the Input to Literals/Identifiers marked by the [<Literal>] Attribute without binding it.
For Example:
#light
[<Literal>]
let E = 2.718281828459
let isE x =
match x with
| E -> true
| _ -> false
print_any (isE 3.2)
print_any (isE E)
According to Crish Smith
Related
I have the following Discriminated Union (DU) declaration:
type Book =
| Dictionary of string[]
| Novel of int[]
| Comics of bool[]
An example:
let x = Dictionary [|"a"; "b"|]
How can I extract the length of the array inside without doing pattern matching and without caring about the data type of the array (in this case: string, int, bool). Note: I have no control over the DU declaration; as a result, I can't write new member method within Book, like getArrayLength()
Of course, we can do it in some way as followed:
match x with
| Dictionary (x: _[]) -> x |> Array.length
| Novel (x: _[]) -> x |> Array.length
| Comics (x: _[]) -> x |> Array.length
But typing x |> Array.length a lot is incovenient. This is a simple example, but we can think of a general problem:
type Animal =
| Dog of DogClass
| Cat of CatClass
| Cow of CowClass
...
... and DogClass, CatClass, etc. may share something. We want to get that shared thing. E.g. those classes inherit from AnimalClass, within which there is countLegs() method. Suppsed there are many animals, pattern matching for all of them while the code block after -> is almost the same. I love the principle DRY (Don't Repeat Yourself).
Is there any convenient way to tackle such problem?
==
EDITED 21.10.2019
I was also looking for some syntax like:
let numEles =
match x with
| _ (arr: _[]) -> x |> Array.Length
| _ -> failwith "No identifiers with fields as Array."
let numLegs =
match anAnimall with
| _ (animal: ?> Animal) -> animal.countLegs()
| _ -> failwith "Can't count legs because of not being an animal."
I think this still follows the spirit of matching, but seem like this approach is not supported.
Realistically, there's no getting around pattern matching here. DUs were, in a way, built for it. Since you don't control the type, you can always add a type extension:
type Book with
member this.Length =
match this with
| Dictionary d -> d.Length
| Novel n -> n.Length
| Comics c -> c.Length
let x = Dictionary [|"a"; "b"|]
printfn "%d" x.Length // Prints 2
Though it's also equally valid to define a Book module with a length function on it if you prefer that:
module Book =
let length b =
match b with
| Dictionary d -> d.Length
| Novel n -> n.Length
| Comics c -> c.Length
let x = Dictionary [|"a"; "b"|]
printfn "%d" (x |> Book.length) // prints 2
But you'll need to write a pattern match expression on the Book type at least once. The fact that every case is made up of data that all has the same property doesn't really help the fact that you need to still identify every case individually.
I implemented a Discriminated Union type that would be used to select a function:
type BooleanCombinator =
| All
| Some
| None
| AtLeast of int
| MoreThan of int
| NotMoreThan of int
| LessThan of int
| ExactlyOne
| ExactlyTwo
| AllButOne
| AllButTwo
let boolToInt (b: bool) : int = if b then 1 else 0
let combineBooleans (combinator : BooleanCombinator)
(bools : bool list)
: bool =
let n = List.sumBy boolToInt bools
match combinator with
| BooleanCombinator.All -> List.forall id bools
| BooleanCombinator.Some -> bools |> List.exists id
| BooleanCombinator.None -> bools |> List.exists id |> not
| BooleanCombinator.AtLeast i -> n >= i
| BooleanCombinator.MoreThan i -> n > i
| BooleanCombinator.NotMoreThan i -> n <= i
| BooleanCombinator.LessThan i -> n < i
| BooleanCombinator.ExactlyOne -> n = 1
| BooleanCombinator.ExactlyTwo -> n = 2
| BooleanCombinator.AllButOne -> n = bools.Length - 1
| BooleanCombinator.AllButTwo -> n = bools.Length - 2
This looked Ok to me but the compiler started to look at all instances of Some and None as belonging to this DU, instead of the Option DU.
I do not want to go through all of my code replacing Some with Option.Some and None with Option.None.
Is there a way to tell the compiler that unqualified Some and None are actually Option.Some and Option.None?
Or should I just give different names to these DU cases, like AtLeastOne and ExactlyZero
The general rule for resolving name collisions in F# is "last declaration wins". Because your custom DU is declared after Option, its constructors Some and None win over those of Option.
But this rule offers a way to fix the problem: you just need to "reassert" the declarations after your custom DU:
type Bogus = Some of int | None
let g = function Some _ -> 42 | None -> 5
let x = Some 42
let inline Some a = Option.Some a
let inline None<'a> = Option.None : 'a option
let (|Some|None|) = function | Option.Some a -> Some a | Option.None -> None
let f = function Some _ -> 42 | None -> 5
let y = Some 42
If you inspect the types of g, x, f, and y in the above code:
> g
g : Bogus -> int
> f
f : 'a option -> int
> x
Bogus
> y
int option
The function g and value x were inferred to have type Bogus -> int and Bogus respectively, because Some and None in their bodies refer to Bogus.Some and Bogus.None.
The function f and value y were inferred to have Option-related types, because Some and None in their bodies refer to the Some function and the (|Some|None|) active pattern that I defined just above.
Of course, this is a rather hacky way to restore status quo. This will convince the compiler, but humans will still have a hard time reading your code. I suggest you rename the cases of your DU instead.
You can mark your DU with [<RequireQualifiedAccess>] attribute.
This means that you will be required to qualify the case name with the type whenever you use it in the code - which is something you do now anyway in your match expression.
That way an unqualified Some would still be resolved to mean Option.Some, despite the fact that you reuse the name.
It's a useful technique to know when you want to use a snappy name for a DU case - like None, Yes, Failure etc. - that by itself would be ambiguous or confusing to the reader (or the compiler, for that matter).
I was browsing through the source code for FSharp.Data when I came across this line of code
let (|Singleton|) = function [l] -> l | _ -> failwith "Parameter mismatch"
The function [l] is what I don't understand. More specifically, I don't understand how the [l] parameter works.
From experimenting in the FSI, I can determine that it starts a form of pattern matching similar to match [l] with .... However, I can't figure out how the F# compiler interprets the expression.
What I'd like to know is how it actually works and what rules it follows.
It is equivalent to
let (|Singleton|) lst =
match lst with
| [l] -> l
| _ -> failwith "Parameter mismatch"
so it extracts the element from a single-element list or throws an exception if the list has any other number of elements.
See the docs on pattern matching syntax. function is a shorthand syntax for taking a single argument and immediately pattern matching:
let foo x =
match x with
| CaseA -> 1
| CaseB -> 2
Is the equivalent of
let foo = function
| CaseA -> 1
| CaseB -> 2
Note that function just adds one argument, it doesn't enforce that there is exactly one argument. For example, this is acceptable:
let foo x y = function
| CaseA -> x + y
| CaseB -> x - y
And is equivalent to
let foo x y z =
match z with
| CaseA -> x + y
| CaseB -> x - y
Edit:
(For completeness) And as for [l], like Lee said, that's just a match pattern. Specifically, a structural match pattern on lists which matches lists with a single element, and binds that element to the identifier l. See "List Pattern" here.
I am looking for a shorter/neater way of doing the equivalent of the following (for any pattern known at compile time):
let f x = match x with | ['A'::_] -> true ; | _ -> false
is there a way of doing this in general, i.e. return true iff an expression matches a given pattern?
You could shorten it slightly using function:
let f = function ['A'::_] -> true | _ -> false
In f#, patterns are not values themselves, and there is no mechanism for converting them to values(*). So, no, there is no neater way.
That said, you may have other options depending on why you're interested in checking whether a pattern matches. Caring about whether a pattern matches but not about which values were matched seems a bit unusual to me, so maybe there's an opportunity for refactoring.
As a simple example, suppose you're doing this:
let t = match e with <pattern> -> true | _ -> false
...
if t then
(* Do something. *)
else
(* Do something else. *)
...
In that case, you could consider instead doing this:
...
match e with
<pattern> -> (* Do something. *)
| _ -> (* Do something else. *)
...
(Supposing the test happens only once, of course.)
(*) Ignoring reflection and quotations.
You may be thinking of an Active Pattern here, specifically its single-case form. It would allow you to create a pattern which returns a boolean value:
let (|F|) = function
| ['A'::_] -> true
| _ -> false
let (F x) = [['A']] // val x : bool = true
The Active Pattern can be parameterized. Of the (n + 1) arguments it accepts, the first n get passed to the syntactic function, and the last argument is the value matched.
let (|G|) e = function
| [d::_] when d = e -> true
| _ -> false
let (G 'A' y) = [['A']] // val y : bool = true
I've spent a few hours trying to get to grips with F# Quotations, but I've come across a bit of a road block. My requirement is to take simple functions (just integers,+,-,/,*) out of a discriminated union type and generate an expression tree that will eventually be used to generate C code. I know this is possible using Quotations with 'direct' functions.
My problem is that the expression tree seems to terminate with a "Value", and I can't figure out how to traverse into that value.
My questions is
whether this is actually possible in this situation? or are there any other approaches that are worth considering.
type FuncType =
| A of (int -> int -> int)
| B
| C
[<ReflectedDefinition>]
let add x y = x + y
let myFunc1 = A (fun x y -> x + y )
let myFunc2 = A add
let thefunc expr =
match expr with
| A(x) ->
<# x #>
| _ ->
failwith "fail"
printfn "%A" (thefunc myFunc1) // prints "Value (<fun:myFunc1#14>)"
printfn "%A" (thefunc myFunc2) // prints "Value (<fun:myFunc2#15>)"
printfn "%A" <# fun x y -> x + y #> // generates usable expression tree
Quotations represent the F# code that was quoted syntactically. This means that if you write something like <# x #>, the quotation will contain just Value case specifying that you quoted something which has the specified value. (Variables are automatically replaced with values if the variable is defined outside of the quotation).
You can only get quotation of code that was explicitly quoted using <# .. #> or of a function that was marked as ReflectedDefinition and is referred to by name in a quotation (e.g. <# add #> but not for example let f = add in <# f #>).
To be able to do what your snippet suggests, you'll need to store quotations in your FuncType too (so that the lambda function that you write is also quoted and you can get its body). Something like:
type FuncType =
| A of Expr<int -> int -> int>
| B | C
[<ReflectedDefinition>]
let add x y = x + y
let myFunc1 = A <# fun x y -> x + y #>
let myFunc2 = A <# add #>
let thefunc expr =
match expr with
| A(x) -> x
| _ -> failwith "fail"
This should work for functions marked as ReflectedDefinition too. To extract the body of the function you need to add something like (you'll need to substitute arguments of the function for parameters, but this should give you some idea):
match expr with
| Lambdas(_, body) ->
match body with
| Call(_, mi, _) when Expr.TryGetReflectedDefinition(mi) <> None ->
let func = Expr.TryGetReflectedDefinition(mi)
match func with
| Some(Lambdas(_, body)) ->
// 'body' is the quotation of the body
| _ -> failwith "Not supported function"
| _ -> failwith "Not supported function"
| _ -> failwith "Not supported expression"