How does one override .Equals() for a Discriminated Union? - f#

I have a discriminated union type and want to override .Equals().
In this simple example I could have used the .Equals function for int to solve the problem, but in my code otherStuff does not support structural comparison.
The following code was my best try:
[<CustomEquality>]
type ModelArg = { Name: string; OtherStuff: int}
with override this.Equals (o: obj) = this.Name = (o :?> ModelArg).Name
I then got a red squiggly line and the following message:
"The struct, record or union type 'ModelArg' has an explicit implementation of 'ObjectEquals'. Consider implementing a matching override for 'Object.GetHashCode'."
I would like to avoid doing that because I really only care for the field Name and also, for performance reasons.
Of course I could write an equals function but I would not be able to use it with List functions like List.contains and I need to do that.
Any suggestions?

The error is telling you that, since you're overriding the Equals method, it's a very good idea to override GetHashCode as well.
The reason for this is that in .NET in general (not just in F#), hash codes are often used as an approximation of equality. For example, if you were to put your objects in a hash table, the hash table would distribute them between buckets based on GetHashCode, and would look them up in the buckets that way too. Then, if Equals is implemented differently than GetHashCode, the hash table's behavior will be unpredictable - it might fail to look up an object that was just inserted or something similar.
Further, the error message does not suggest that you include the int in the definition of equality. All it says is that you need to implement GetHashCode, and do it in the same sense as your Equals implementation. There is also no performance penalty for doing this, as long as you never actually call GetHashCode. And if you do - see above.
Since all your Equals implementation does is compare the Name field, it would probably make sense to delegate GetHashCode to the same field as well:
[<CustomEquality>]
type ModelArg = { Name: string; OtherStuff: int}
with
override this.Equals (o: obj) = this.Name = (o :?> ModelArg).Name
override this.GetHashCode() = this.Name.GetHashCode()
Finally, your implementation of Equals would crash when called with a null or with an object of another type. I would suggest that you handle this case if you want your code to be robust:
override this.Equals (o: obj) =
match o with
| :? ModelArg as ma -> this.Name = ma.Name
| _ -> false

Related

Case insensitive comparison on string fields of Record type

Is there a way to substitute the comparison of string fields in a F# record class to be case-insensitive without having to take full custom control of equality/comparison?
Subtracting Records from a Set using case-insensitive comparison is the closest I have found to an answer.
If you want to do it in a clean way, I would suggest introducing a wrapper type for case insensitive strings. That way you can have the notion of case insensitive comparisons reflected in the types, and don't have to change the default structural comparisons on the records.
[<CustomEquality; CustomComparison>]
type CIString =
| CI of string
override x.Equals y = ...
override x.GetHashCode() = ...
interface System.IComparable with
member x.CompareTo y = ...
I left out the implementation of the methods - there's nothing fancy there, just use ToUpperInvariant on the nested string whenever you access it.
Then you can modify your records like this:
type OldRecord = { field : string }
type NewRecord = { field : CIString }
and comparisons on the new type should show that { field = "TEST" } = { field = "test" }.
The other solution I suggested (reflection-based) would be easy to put in place for a simple case, but it's dodgy. Making it work in a sensible way for all the possible cases is a non-trivial exercise, if you can even establish what "sensible way" means here.

Design alternatives to extending object with interface

While working through Expert F# again, I decided to implement the application for manipulating algebraic expressions. This went well and now I've decided as a next exercise to expand on that by building a more advanced application.
My first idea was to have a setup that allows for a more extendible way of creating functions without having to recompile. To that end I have something like:
type IFunction =
member x.Name : string with get
/// additional members omitted
type Expr =
| Num of decimal
| Var of string
///... omitting some types here that don't matter
| FunctionApplication of IFunction * Expr list
So that say a Sin(x) could be represented a:
let sin = { new IFunction() with member x.Name = "SIN" }
let sinExpr = FunctionApplication(sin,Var("x"))
So far all good, but the next idea that I would like to implement is having additional interfaces to represent function of properties. E.g.
type IDifferentiable =
member Derivative : int -> IFunction // Get the derivative w.r.t a variable index
One of the ideas the things I'm trying to achieve here is that I implement some functions and all the logic for them and then move on to the next part of the logic I would like to implement. However, as it currently stands, that means that with every interface I add, I have to revisit all the IFunctions that I've implemented. Instead, I'd rather have a function:
let makeDifferentiable (f : IFunction) (deriv : int -> IFunction) =
{ f with
interface IDifferentiable with
member x.Derivative = deriv }
but as discussed in this question, that is not possible. The alternative that is possible, doesn't meet my extensibility requirement. My question is what alternatives would work well?
[EDIT] I was asked to expand on the "doesn't meet my extenibility requirement" comment. The way this function would work is by doing something like:
let makeDifferentiable (deriv : int -> IFunction) (f : IFunction)=
{ new IFunction with
member x.Name = f.Name
interface IDifferentiable with
member x.Derivative = deriv }
However, ideally I would keep on adding additional interfaces to an object as I add them. So if I now wanted to add an interface that tell whether on function is even:
type IsEven =
abstract member IsEven : bool with get
then I would like to be able to (but not obliged, as in, if I don't make this change everything should still compile) to change my definition of a sine from
let sin = { new IFunction with ... } >> (makeDifferentiable ...)
to
let sin = { new IFunction with ... } >> (makeDifferentiable ...) >> (makeEven false)
The result of which would be that I could create an object that implements the IFunction interface as well as potentially, but not necessarily a lot of different other interfaces as well; the operations I'd then define on them, would potentially be able to optimize what they are doing based on whether or not a certain function implements an interface. This will also allow me to add additional features/interfaces/operations first without having to change the functions I've defined (though they wouldn't take advantage of the additional features, things wouldn't be broken either.[/EDIT]
The only thing I can think of right now is to create a dictionary for each feature that I'd like to implement, with function names as keys and the details to build an interface on the fly, e.g. along the lines:
let derivative (f : IFunction) =
match derivativeDictionary.TryGetValue(f.Name) with
| false, _ -> None
| true, d -> d.Derivative
This would require me to create one such function per feature that I add in addition to one dictionary per feature. Especially if implemented asynchronously with agents, this might be not that slow, but it still feels a little clunky.
I think the problem that you're trying to solve here is what is called The Expression Problem. You're essentially trying to write code that would be extensible in two directions. Discriminated unions and object-oriented model give you one or the other:
Discriminated union makes it easy to add new operations (just write a function with pattern matching), but it is hard to add a new kind of expression (you have to extend the DU and modify all code
that uses it).
Interfaces make it easy to add new kinds of expressions (just implement the interface), but it is hard to add new operations (you have to modify the interface and change all code that creates it.
In general, I don't think it is all that useful to try to come up with solutions that let you do both (they end up being terribly complicated), so my advice is to pick the one that you'll need more often.
Going back to your problem, I'd probably represent the function just as a function name together with the parameters:
type Expr =
| Num of decimal
| Var of string
| Application of string * Expr list
Really - an expression is just this. The fact that you can take derivatives is another part of the problem you're solving. Now, to make the derivative extensible, you can just keep a dictionary of the derivatives:
let derrivatives =
dict [ "sin", (fun [arg] -> Application("cos", [arg]))
... ]
This way, you have an Expr type that really models just what an expression is and you can write differentiation function that will look for the derivatives in the dictionary.

Understanding F# StringConstant

I am trying to understand the following code, particularly StringConstant:
type StringConstant = StringConstant of string * string
[<EntryPoint>]
let main argv =
let x = StringConstant("little", "shack")
printfn "%A" x
0 // return an integer exit code
(By way of context, StringConstant is used in the FParsec tutorial, but this example does not use FParsec.)
What I would like to know is:
what exactly is the type statement doing?
once I instantiate x, how would I access the individual "parts"
("little" or "house")
As others already noted, technically, StringConstant is a discriminated union with just a single case and you can extract the value using pattern matching.
When talking about domain modelling in F#, I like to use another useful analogy. Often, you can start just by saying that some data type is a tuple:
type Person = string * int
This is really easy way to represent data, but the problem is that when you write "Tomas", 42, the compiler does not know that you mean Person, but instead understands it as string * int tuple. One-case discriminated unions are a really nice way to name your tuple:
type Person = Person of string * int
It might be a bit confusing that this is using the name Person twice - first as a type name and second as a name of the case. This has no special meaning - it simply means that the type will have the same name as the case.
Now you can write Person("Tomas", 42) to create a value and it will have a type Person. You can decompose it using match or let, but you can also easily write functions that take Person. For example, to return name, you can write:
let getName (Person(name, _)) =
name
I think single-case discriminated unions are often used mainly because they are really easy to define and really easy to work with. However, I would not use them in code that is exposed as a public API because they are a bit unusual and may be confusing.
PS: Also note that you need to use parentheses when extracting the values:
// Correct. Defines symbols 'name' and 'age'
let (Person(name, age)) = tomas
// Incorrect! Defines a function `Person` that takes a tuple
// (and hides the `Person` case of the discriminated union)
let Person(name, age) = tomas
StringConstant is a discriminated union type, with just a single case (also named StringConstant). You extract the parts via pattern matching, using match/function or even just let, since there is just a single case:
let (StringConstant(firstPart, secondPart)) = x
type StringConstant = StringConstant of string * string
results in a discriminated union with one type.
type StringConstant = | StringConstant of string * string if you execute it in F# interactive.
You can see the msdn documentation on that here.
You can get the value out like this:
let printValue opt =
match opt with
| StringConstant( x, y) -> printfn "%A%A" x y
The other guys already mentioned how you extract the data from a discriminated union, but to elaborate a little more on Discriminated unions one could say that they are sorta like enums on steroids. They are implemented behind the scenes as a type hierarchy where the type is the base class and the cases are subclases of that baseclass with whatever parameter they might have as readonly public variables.
In Scala a similar data-structure is called case classes which might help you convince yourself of this implementationmethod.
One nice property of discriminated unions are that they are self-referenceable and therefor are perfect for defining recursive structures like a tree. Below is a definition of a Hoffman coding tree in just three lines of code. Doing that in C# would probably take somewhere between 5 and 10 times as many lines of code.
type CodeTree =
| Branch of CodeTree * CodeTree * list<char> * int
| Leaf of char * int
For information about Discriminated Unions see the msdn documentation
For an example of using Discriminated Unions as a tree-structure see this gist which is an implementation of a huffman decoder in roughly 60 lines of F#)

Declaring a variable without assigning

Any way to declare a new variable in F# without assigning a value to it?
See Aidan's comment.
If you insist, you can do this:
let mutable x = Unchecked.defaultof<int>
This will assign the absolute zero value (0 for numeric types, null for reference types, struct-zero for value types).
It would be interesting to know why the author needs this in F# (simple example of intended use would suffice).
But I guess one of the common cases when you may use uninitialised variable in C# is when you call a function with out parameter:
TResult Foo<TKey, TResult>(IDictionary<TKey, TResult> dictionary, TKey key)
{
TResult value;
if (dictionary.TryGetValue(key, out value))
{
return value;
}
else
{
throw new ApplicationException("Not found");
}
}
Luckily in F# you can handle this situation using much nicer syntax:
let foo (dict : IDictionary<_,_>) key =
match dict.TryGetValue(key) with
| (true, value) -> value
| (false, _) -> raise <| ApplicationException("Not Found")
You can also use explicit field syntax:
type T =
val mutable x : int
I agree with everyone who has said "don't do it". However, if you are convinced that you are in a case where it really is necessary, you can do this:
let mutable naughty : int option = None
...then later to assign a value.
naughty <- Some(1)
But bear in mind that everyone who has said 'change your approach instead' is probably right. I code in F# full time and I've never had to declare an unassigned 'variable'.
Another point: although you say it wasn't your choice to use F#, I predict you'll soon consider yourself lucky to be using it!
F# variables are by default immutable, so you can't assign a value later. Therefore declaring them without an initial value makes them quite useless, and as such there is no mechanism to do so.
Arguably, a mutable variable declaration could be declared without an initial value and still be useful (it could acquire an initial default like C# variables do), but F#'s syntax does not support this. I would guess this is for consistency and because mutable variable slots are not idiomatic F# so there's little incentive to make special cases to support them.

Best way to determine variable type and treat each one differently in F#

I have a function that will create a select where clause, but right now everything has to be a string.
I would like to look at the variable passed in and determine what type it is and then treat it properly.
For example, numeric values don't have single quotes around them, option type will either be null or have some value and boolean will actually be zero or one.
member self.BuildSelectWhereQuery (oldUser:'a) = //'
let properties = List.zip oldUser.ToSqlValuesList sqlColumnList
let init = false, new StringBuilder()
let anyChange, (formatted:StringBuilder) =
properties |> Seq.fold (fun (anyChange, sb) (oldVal, name) ->
match(anyChange) with
| true -> true, sb.AppendFormat(" AND {0} = '{1}'", name, oldVal)
| _ -> true, sb.AppendFormat("{0} = '{1}'", name, oldVal)
) init
formatted.ToString()
Here is one entity:
type CityType() =
inherit BaseType()
let mutable name = ""
let mutable stateId = 0
member this.Name with get() = name and set restnameval=name <- restnameval
member this.StateId with get() = stateId and set stateidval=stateId <- stateidval
override this.ToSqlValuesList = [this.Name; this.StateId.ToString()]
So, if name was some other value besides a string, or stateId can be optional, then I have two changes to make:
How do I modify ToSqlValuesList to
have the variable so I can tell the
variable type?
How do I change my select function
to handle this?
I am thinking that I need a new function does the processing, but what is the best FP way to do this, rather than using something like typeof?
You can use a type test pattern in a match. Would this meet your needs?
let f (x : obj) =
match x with
| :? int -> "int"
| :? string -> "string"
| :? bool -> "bool"
| _ -> "who knows?"
I think that one clear functional approach would be to define a data type that represents the various (more complicated situations) that you need to handle. You mentioned that a value may be optional and that you need to distinguish numeric and textual values (for the encoding to SQL).
You could define a discriminated union (if there are other cases that you'd like to handle, the definition may be a bit more complicated):
type SqlValue =
| Missing
| Numeric of string
| Textual of string
Note that the Textual case also carries string, because I assume that the client who produces the value takes care of converting it to string - this is only information for your SQL query generator (so that it knows whether it needs to add quotes).
Your ToSqlValuesList member would return a list of values string & SqlValue, so for example, a sample product could be represented using the following list:
columns = [ "Name"; "Price"; "Description" ]
values = [ Textual("Tea"); Numeric(10); Missing ]
In the code that generates the SQL query, you'd use pattern matching to handle all the different cases (most importantly, encode string to avoid SQL injection in case the value is Textual :-)).
EDIT You'd need to implement the conversion from the specific data types to the SqlValue representation in every client. However, this can be simplified by writing a utility type (using the fact that members can be overloaded):
type SqlValue with
static member From(a:int) = Numeric(a.ToString())
static member From(a:int option) =
match a with None -> Missing | Some(n) -> SqlValue.From(n)
// ... similarly for other types
In the implementation of ToSqlValuesList, you would write SqlValue.From(description) and it would deal with the details autoamtically.
A more sophisticated approach would be to annotate public members of the types representing your data entities with .NET attributes and use Reflection to extract the values (and their types) at runtime. This is more advanced, but quite elegant (there is a nice exmaple of this technique in Don Syme's Expert F# book)

Resources