Accessing specific case from F# DU - f#

Suppose I have the following DU:
type Something =
| A of int
| B of string * int
Now I use it in a function like this:
let UseSomething = function
| A(i) -> DoSomethingWithA i
| B(s, i) -> DoSomethingWithB s i
That works, but I've had to deconstruct the DU in order to pass it to the DoSomethingWith* functions. It feels natural to me to try to define DoSomethingWithA as:
let DoSomethingWithA (a: Something.A) = ....
but the compiler complains that the type A is not defined.
It seems entirely in keeping with the philosophy of F# to want to restrict the argument to being a Something.A, not just any old int, so am I just going about it the wrong way?

The important thing to note is that A and B are constructors of the same type Something. So you will get inexhaustive pattern matching warning if you try to use A and B cases separately.
IMO, deconstructing all cases of DUs is a good idea since it is type-safe and forces you to think of handling those cases even you don't want to. The problem may arise if you have to deconstruct DUs repetitively in the same way. In that case, defining map and fold functions on DUs might be a good idea:
let mapSomething fa fb = function
| A(i) -> fa i
| B(s, i) -> fb s i
Please refer to excellent Catamorphism series by #Brian to learn about fold on DUs.
That also said that your example is fine. What you really process are string and int values after deconstruction.
You can use Active Patterns to consume two cases separately:
let (|ACase|) = function A i -> i | B _ -> failwith "Unexpected pattern B _"
let (|BCase|) = function B(s, i) -> (s, i) | A _ -> failwith "Unexpected pattern A _"
let doSomethingWithA (ACase i) = ....
but inferred type of doSomethingWithA is still the same and you get an exception when passing B _ to the function. So it's a wrong thing to do IMO.

The other answers are accurate: in F# A and B are constructors, not types, and this is the traditional approach taken by strongly typed functional languages like Haskell or the other languages in the ML family. However, there are other approaches - I believe that in Scala, for example, A and B would actually be subclasses of Something, so you could use those more specific types where it makes sense to do so. I'm not completely sure what tradeoffs are involved in the design decision, but generally speaking inheritance makes type inference harder/impossible (and true to the stereotype type inference in Scala is much worse than in Haskell or the ML languages).

A is not a type, it is just a constructor for Something. There's no way you can avoid pattern matching, which is not necessarily a bad thing.
That said, F# does offer a thing called active patterns, for instance
let (|AA|) = function
| A i -> i
| B _ -> invalidArg "B" "B's not allowed!"
which you can then use like this:
let DoSomethingWithA (AA i) = i + 1
But there's no real reason why you would want to do that! You still do the same old pattern matching under the hood, plus you risk the chance of a runtime error.
In any case, your implementation of UseSomething is perfectly natural for F#.

Related

What are the alternatives to returning a discriminated union from a function?

I'm experimenting with rewriting a complicated piece of code using F#.
For this particular code base, discriminated unions help me a lot, so I'm focusing on using them as much as possible. Specifically, exhaustiveness checks on DUs is helping me avoid lots and lots of bugs.
However, I'm facing a repeating pattern of having to use match ... with to the extent that the clutter in the code is offsetting the benefit I'm getting from exhaustiveness check.
I simplified the pattern I'm dealing with as much as I can and tried to come up with an example that demonstrates the structure of the code I'm writing. The real code base is a lot more complicated and it is in a completely different domain but at the language level, this example represents the issue.
Let's say we want to get some about shoppers based on a classification of shoppers: they're either cat people or dog people. The key thing here is classifying some types (tuples) via DUs.
Here are the domain types:
type PetPerson =
|CatPerson
|DogPerson
type CatFood =
|Chicken
|Fish
type DogFood =
|Burger
|Steak
//some cat food, shopper's age and address
type CatFoodShopper = CatFoodShopper of (CatFood list * int * string)
//some dog food, shopper's age and number of children
type DogFoodShopper = DogFoodShopper of (DogFood list * int * int)
Leaving aside the horrible way we're feeding the poor animals, this domain model needs a function to map PetPerson to CatFoodShopper or DogFoodShopper
At this point, my initial thought is to define a Shopper type, since I cannot return two different types from the following function, based on the results of pattern matching:
type Shopper =
|CatFShopper of CatFoodShopper
|DogFShopper of DogFoodShopper
let ShopperViaPersonality = function
|CatPerson -> CatFShopper (CatFoodShopper ([Chicken;Fish], 32, "Hope St"))
|DogPerson -> DogFShopper (DogFoodShopper ([Burger;Steak], 45, 1))
This solves the problem but then I have lots of places in the code (really a lot) where I end up with a PetPerson and need to get a CatFoodShopper or a DogFoodShopper based on what the PetPerson value is. This leads to unnecessary pattern matching for cases I know I don't have at hand. Here is an example:
let UsePersonality (x:int) (y:PetPerson) =
//x is used in some way etc. etc.
match y with
|CatPerson as c -> //how can I void the following match?
match (ShopperViaPersonality c) with
|CatFShopper (CatFoodShopper (lst,_,_))-> "use lst and return some string "
| _ -> failwith "should not have anything but CatFShopper"
|DogPerson as d -> //same as before. I know I'll get back DogFShopper
match (ShopperViaPersonality d) with
|DogFShopper (DogFoodShopper (lst, _,_)) -> "use lst and return other string"
|_ -> failwith "should not have anything but DogFShopper"
As you can see, I have to write pattern matching code even when I know I'll be getting back a particular value. I have no way of concisely associating the CatPerson value to CatFoodShopper value.
In order to improve things at the call site, I considered using F#'s way of mimicking type classes via interfaces, based on lots of example available here:
type IShopperViaPersonality<'T> =
abstract member ShopperOf: PetPerson -> 'T
let mappingInstanceOf<'T> (inst:IShopperViaPersonality<'T>) p = inst.ShopperOf p
let CatPersonShopper =
{new IShopperViaPersonality<_> with
member this.ShopperOf x =
match x with
|CatPerson -> CatFoodShopper ([Chicken;Fish], 32, "Hope St")
| _ -> failwith "This implementation is only for CatPerson"}
let CatPersonToShopper = mappingInstanceOf CatPersonShopper
let DogPersonShopper =
{new IShopperViaPersonality<_> with
member this.ShopperOf x =
match x with
|DogPerson -> DogFoodShopper ([Burger;Steak], 45, 1)
| _ -> failwith "This implementation is only for DogPerson"}
let DogPersonToShopper = mappingInstanceOf DogPersonShopper
So I no longer have a Shopper type to represent both cat food shoppers and dog food shoppers, but instead an interface defines the mapping from PetPerson values to specific shopper types. I also have individual partially applied functions to make things even easier at the call site.
let UsePersonality1 (x:int) (y:PetPerson) =
match y with
|CatPerson as c ->
let (CatFoodShopper (lst,_,_)) = CatPersonToShopper c
"use lst and return string"
|DogPerson as d ->
let (DogFoodShopper (lst,_,_)) = DogPersonToShopper d
"use lst and return string"
This approach works better when using PetPerson values, but I'm now left with the task of defining these individual functions to keep things clean at the call site.
Note that this example is meant to demonstrate the trade off between using a DU and using an interface to return different types based on the classifying DU parameter, if I may call it that. So don't hang up on my meaningless use of return values etc.
My question is: are there any other ways I can accomplish the semantics of classifying a bunch of tuple (or record) types? If you're thinking active patterns, they're not an option because in the real code base the DUs have more than seven cases, which is the limit for active patterns, in case they would be of help. So do I have any other options to improve on the above approaches?
One obvious way to go about this is to call ShopperViaPersonality before matching PetPerson, not after:
let UsePersonality (x:int) (y:PetPerson) =
//x is used in some way etc. etc.
match ShopperViaPersonality y with
| CatFShopper (CatFoodShopper (lst,_,_))-> "use lst and return some string "
| DogFShopper (DogFoodShopper (lst, _,_)) -> "use lst and return other string"
Also note that if the sole purpose of ShooperViaPersonality is to support pattern matches, you may be better off making it an active pattern:
let (|CatFShopper|DogFShopper|) = function
| CatPerson -> CatFShopper ([Chicken;Fish], 32, "Hope St")
| DogPerson -> DogFShopper ([Burger;Steak], 45, 1)
Then you can use it like this:
let UsePersonality (x:int) (y:PetPerson) =
//x is used in some way etc. etc.
match y with
| CatFShopper (lst,_,_) -> "use lst and return some string "
| DogFShopper (lst, _,_) -> "use lst and return other string"
Logically, an active pattern is pretty much the same as a DU + a function, but on syntactic level, notice how much less nesting there is now.

Optionally taking the first item in a sequence

I need a function like Seq.head, but returning None instead of throwing an exception when the sequence is empty, i.e., seq<'T> -> 'T option.
There are a jillion ways to do this. Here are several:
let items = Seq.init 10 id
let a = Seq.tryFind (fun _ -> true) items
let b = Seq.tryPick Some items
let c = if Seq.isEmpty items then None else Some (Seq.head items)
let d =
use e = items.GetEnumerator()
if e.MoveNext() then Some e.Current
else None
b is the one I use. Two questions:
Is there a particularly idiomatic way to do this?
Since there's no built-in Seq.tryHead function, does that indicate this shouldn't be necessary, is uncommon, or is better implemented without a function?
UPDATE
tryHead has been added to the standard library in F# 4.0.
I think (b) is probably the most idiomatic, for the same reason #Ramon gave.
I think the lack of Seq.tryHead just means that it is not super common.
I'm not sure, but my guess is that functional languages with Hindley-Milner type inference in general are sparse about implementing such specific functions on collection types because overloading isn't available and composing higher-order functions can be done tersely.
For example, C# Linq extensions are much more exhaustive than functions in F#'s Seq module (which itself is more exhaustive than functions on concrete collection types), and even has IEnumerable.FirstOrDefault. Practically every overload has a variation which performs a map.
I think emphasis on pattern matching and concrete types like list is also a reason.
Now, most of the above is speculation, but I think I may have a notion closer to being objective. I think a lot of the time tryPick and tryFind can be used in the first place instead of filter |> tryHead. For example, I find myself writing code like the following fairly frequently:
open System.Reflection
let ty = typeof<System.String> //suppose this type is actually unknown at compile time
seq {
for name in ["a";"b";"c"] do
yield ty.GetMethod(name)
} |> Seq.tryFind((<>)null)
instead of like
...
seq {
for name in ["a";"b";"c"] do
match ty.GetMethod(name) with
| null -> ()
| mi -> yield mi
} |> tryHead
You could define:
let seqTryHead s = Seq.tryPick Some s
It is of type seq<'a> -> 'a option. Note that I don't beta-reduce because of the generic value limitation.

Evaluate function inside quotation

I'm at the moment doing some very basic pattern matching with quotations.
My code:
let rec test e =
match e with
| Patterns.Lambda(v,e) -> test e
| Patterns.Call(_, mi, [P.Value(value, _); P.Value(value2, _)]) ->
printfn "Value1: %A | Value2 : %A" value value2
| Patterns.Call(_, mi, [P.Value(value, _); P.PropertyGet(_, pi, exprs)]) ->
printfn "Value1: %A | Value2 : %A" value (pi.GetValue(pi, null))
| _ -> failwith "Expression not supported"
let quot1 = <# "Name" = "MyName" #>
(* Call (None, Boolean op_Equality[String](System.String, System.String),
[Value ("Name"), Value ("lol")]) *)
let quot2 = <# "Name" = getNameById 5 #>
(* Call (None, Boolean op_Equality[String](System.String, System.String),
[Value ("Name"),
Call (None, System.String getNameById[Int32](Int32), [Value (5)])]) *)
test quot1 // Works!
test quot2 // Fails.. Dosent match any of the patterns.
Is it possible to somehow evaluate the result of the getNameById function first, so that it will match one of the patterns, or am I doomed to assign a let binding with the result of the function outside the quotation?
I've tried playing with the ExprShape patterns, but without luck..
You can use PowerPack's Eval to evaluate only the arguments to the Call expression:
match e with
| Call(_,mi,[arg1;arg2]) ->
let arg1Value, arg2Value = arg1.Eval(), arg2.Eval()
...
And similarly for Lambda expressions, etc. Noticed this frees you from enumerating permutations of Value, Property, and other argument expressions.
Update
Since you want to avoid using Eval (for good reason if you are implementing a performance conscious application), you'll need to implement your own eval function using reflection (which is still not lightening fast, but should be faster than PowerPack's Eval which involves an intermediate translation of F# Quotations to Linq Expressions). You can get started by supporting a basic set of expressions, and expand from there as needed. Recursion is the key, the following can help you get started:
open Microsoft.FSharp.Quotations
open System.Reflection
let rec eval expr =
match expr with
| Patterns.Value(value,_) -> value //value
| Patterns.PropertyGet(Some(instance), pi, args) -> //instance property get
pi.GetValue(eval instance, evalAll args) //notice recursive eval of instance expression and arg expressions
| Patterns.PropertyGet(None, pi, args) -> //static property get
pi.GetValue(null, evalAll args)
| Patterns.Call(Some(instance), mi, args) -> //instance call
mi.Invoke(eval instance, evalAll args)
| Patterns.Call(None, mi, args) -> //static call
mi.Invoke(null, evalAll args)
| _ -> failwith "invalid expression"
and evalAll exprs =
exprs |> Seq.map eval |> Seq.toArray
And then wrapping this in an Active Pattern will improve syntax:
let (|Eval|) expr =
eval expr
match e with
| Patterns.Call(_, mi, [Eval(arg1Value); Eval(arg2Value)]) -> ...
Update 2
OK, this thread got me motivated to try and implement a robust reflection based solution, and I've done so with good results which are now part of Unquote as of version 2.0.0.
It turned out not to be as difficult as I thought it would be, currently I am supporting all quotation expressions except for AddressGet, AddressSet, and NewDelegate. This is already better than PowerPack's eval, which doesn't support PropertySet, VarSet, FieldSet, WhileLoop, ForIntegerRangeLoop, and Quote for example.
Some noteworthy implementation details are with VarSet and VarGet, where I need to pass around an environment name / variable lookup list to each recursive call. It is really an excellent example of the beauty of functional programming with immutable data-structures.
Also noteworthy is special care taken with issues surrounding exceptions: striping the TargetInvokationExceptions thrown by reflection when it catches exceptions coming from methods it is invoking (this is very important for handling TryWith evaluation properly, and also makes for better user handling of exceptions which fly out of the quotation evaluation.
Perhaps the most "difficult" implementation detail, or really the most grueling, was the need to implement all of the core operators (well, as most I could discover: the numeric and conversion operators, checked versions as well) since most of them are not given dynamic implementations in the F# library (they are implemented using static type tests with no fallback dynamic implementations), but also means a serious performance increase when using these functions.
Some informal benchmarking I observe performance increases of up to 50 times over PowerPack's (not pre-compiled) eval.
I am also confident that my reflection-based solution will be less bug prone then PowerPack's, simply because it is less complicated than the PowerPack's approach (not to mention I've backed it up with about 150 unit tests, duly fortified by Unquotes additional 200+ unit tests which now is driven by this eval implementation).
If you want to peek at the source code, the main modules are Evaluation.fs and DynamicOperators.fs (I've locked the links into revision 257). Feel free to grab and use the source code for your own purposes, it licensed under Apache License 2.0! Or you could wait a week or so, when I release Unquote 2.0.0 which will include evaluation operators and extensions publicly.
You can write an interpreter that will evaluate the quotation and call the getNameById function using Reflection. However, that would be quite a lot of work. The ExprShape isn't going to help you much - it is useful for simple traversing of quotations, but to write an interpreter, you'll need to cover all patterns.
I think the easiest option is to evaluate quotations using the PowerPack support:
#r "FSharp.PowerPack.Linq.dll"
open Microsoft.FSharp.Linq.QuotationEvaluation
let getNameById n =
if n = 5 then "Name" else "Foo"
let quot1 = <# "Name" = "MyName" #>
let quot2 = <# "Name" = getNameById 5 #>
quot1.Eval()
quot2.Eval()
This has some limitations, but it is really the easiest option. However, I'm not really sure what are you trying to achieve. If you could clarify that, then you may get a better answer.

Pattern Matching of Units of Measure in F#

This function:
let convert (v: float<_>) =
match v with
| :? float<m> -> v / 0.1<m>
| :? float<m/s> -> v / 0.2<m/s>
| _ -> failwith "unknown"
produces an error
The type 'float<'u>' does not have any proper subtypes and cannot be used as the source of a type test or runtime coercion.
Is there any way how to pattern match units of measure?
As #kvb explains in detail, the problem is that units of measure are a part of the type. This means that float<m> is different type than float<m/s> (and unfortunately, this information isn't stored as part of the value at runtime).
So, you're actually trying to write a function that would work with two different types of input. The clean functional solution is to declare a discriminated union that can hold values of either the first type or the second type:
type SomeValue =
| M of float<m>
| MPS of float<m/s>
Then you can write the function using ordinary pattern matching:
let convert v =
match v with
| M v -> v / 0.1<m>
| MPS v -> v / 0.2<m/s>
You'll need to explicitly wrap the values into the discriminated union value, but it's probably the only way to do this directly (without making some larger changes in the program structure).
For normal types like int and float, you could also use overloaded members (declared in some F# type), but that doesn't work for units of measure, because the signature will be the same after the F# compiler erases the unit information.
There are two problems with your approach. First of all, when you use an underscore in the definition of your function, that's the same as using a fresh type variable, so your definition is equivalent to the following:
let convert (v: float<'u>) = //'
match v with
| :? float<m> -> v / 0.1<m>
| :? float<m/s> -> v / 0.2<m/s>
| _ -> failwith "unknown"
What the error message is telling you is that the compiler know that v is of type float<'u>, and float<'u> has no proper subtypes, so there's no point in doing a type test to determine if it's a float<m> or any other type.
You might try to get around this by first boxing v into an object and then doing a type test. This would work, for instance, if you had a list<'a> and wanted to see if it were a list<int>, because full type information about generic objects is tracked at runtime including generic type parameters (notably, this is different from how some other runtimes like Java's work). Unfortunately, F# units of measure are erased at runtime, so this won't work here - there is no way for the system to infer the correct measure type given a boxed representation, since at runtime the value is just a plain float - F#'s system for units of measure is actually quite similar in this respect to how Java handles generic types.
As an aside, what you're trying to do seems quite suspect - functions which are generic in the unit of measure shouldn't do different things depending on what the measure type is; they should be properly parametric. What exactly are you trying to achieve? It certainly doesn't look like an operation which corresponds to physical reality, which is the basis for F#'s measure types.
See the Units at Runtime Section at http://msdn.microsoft.com/en-us/library/dd233243.aspx.
I agree with #kvb, I think the best way around this is to pass an object.
What I would like to do, using your code structure:
let convert (v: float<_>) =
match v with
| :? float<m> -> v<m>
| :? float<inches> -> v * 2.54 / 100.0<m>

Using a variable in pattern matching in Ocaml or F#

I have a function of the form
'a -> ('a * int) list -> int
let rec getValue identifier bindings =
match bindings with
| (identifier, value)::tail -> value
| (_, _)::tail -> getValue identifier tail
| [] -> -1
I can tell that identifier is not being bound the way I would like it to and is acting as a new variable within the match expression. How to I get identifier to be what is passed into the function?
Ok! I fixed it with a pattern guard, i.e. | (i, value)::tail when i = indentifier -> value
but I find this ugly compared to the way I originally wanted to do it (I'm only using these languages because they are pretty...). Any thoughts?
You can use F# active patterns to create a pattern that will do exactly what you need. F# supports parameterized active patterns that take the value that you're matching, but also take an additional parameter.
Here is a pretty stupid example that fails when the value is zero and otherwise succeeds and returns the addition of the value and the specified parameter:
let (|Test|_|) arg value =
if value = 0 then None else Some(value + arg)
You can specify the parameter in pattern matching like this:
match 1 with
| Test 100 res -> res // 'res' will be 101
Now, we can easily define an active pattern that will compare the matched value with the input argument of the active pattern. The active pattern returns unit option, which means that it doesn't bind any new value (in the example above, it returned some value that we assigned to a symbol res):
let (|Equals|_|) arg x =
if (arg = x) then Some() else None
let foo x y =
match x with
| Equals y -> "equal"
| _ -> "not equal"
You can use this as a nested pattern, so you should be able to rewrite your example using the Equals active pattern.
One of the beauties of functional languages is higher order functions. Using those functions we take the recursion out and just focus on what you really want to do. Which is to get the value of the first tuple that matches your identifier otherwise return -1:
let getValue identifier list =
match List.tryFind (fun (x,y) -> x = identifier) list with
| None -> -1
| Some(x,y) -> y
//val getValue : 'a -> (('a * int) list -> int) when 'a : equality
This paper by Graham Hutton is a great introduction to what you can do with higher order functions.
This is not directly an answer to the question: how to pattern-match the value of a variable. But it's not completely unrelated either.
If you want to see how powerful pattern-matching could be in a ML-like language similar to F# or OCaml, take a look at Moca.
You can also take a look at the code generated by Moca :) (not that there's anything wrong with the compiler doing a lot of things for you in your back. In some cases, it's desirable, even, but many programmers like to feel they know what the operations they are writing will cost).
What you're trying to do is called an equality pattern, and it's not provided by Objective Caml. Objective Caml's patterns are static and purely structural. That is, whether a value matches the pattern depends solely on the value's structure, and in a way that is determined at compile time. For example, (_, _)::tail is a pattern that matches any non-empty list whose head is a pair. (identifier, value)::tail matches exactly the same values; the only difference is that the latter binds two more names identifier and value.
Although some languages have equality patterns, there are non-trivial practical considerations that make them troublesome. Which equality? Physical equality (== in Ocaml), structural equality (= in Ocaml), or some type-dependent custom equality? Furthermore, in Ocaml, there is a clear syntactic indication of which names are binders and which names are reference to previously bound values: any lowercase identifier in a pattern is a binder. These two reasons explain why Ocaml does not have equality patterns baked in. The idiomatic way to express an equality pattern in Ocaml is in a guard. That way, it's immediately clear that the matching is not structural, that identifier is not bound by this pattern matching, and which equality is in use. As for ugly, that's in the eye of the beholder — as a habitual Ocaml programmer, I find equality patterns ugly (for the reasons above).
match bindings with
| (id, value)::tail when id = identifier -> value
| (_, _)::tail -> getValue identifier tail
| [] -> -1
In F#, you have another possibility: active patterns, which let you pre-define guards that concern a single site in a pattern.
This is a common complaint, but I don't think that there's a good workaround in general; a pattern guard is usually the best compromise. In certain specific cases there are alternatives, though, such as marking literals with the [<Literal>] attribute in F# so that they can be matched against.

Resources