Behaviour of greater than (and equivalent) for Option - f#

I'm working on something for an image processing task (it's not greatly relevant here), and I stumbled across behaviour of F#'s Option type that surprised me, regarding performing greater than (>) comparisons. I couldn't find anything that directly explained what I should expect (more on that below) on Stack Overflow, the F# docs or the wider web.
The specific part I am looking at looks something like:
let sort3Elems (arr: byte option []) =
if arr.[0] > arr.[1] then swap &arr.[0] &arr.[1]
if arr.[1] > arr.[2] then swap &arr.[1] &arr.[2]
if arr.[0] > arr.[1] then swap &arr.[0] &arr.[2]
where I will be passing in arrays of four byte options (if you're wondering why this looks weird and is super-unfunctional, right now I'm deliberately trying to re-implement the non-functional-language implementation of an algorithm in a textbook). I was expecting this to cause a compiler error, where it would complain that the options couldn't be directly compared. To my surprise, this compiled fine. Intrigued, I tested it out in F# Interactive, the results of which look something like the below:
let arr: byte option [] = Array.zeroCreate 4;;
val arr : byte option [] = [|None; None; None; None|]
> arr.[0] <- Some(127uy);;
val it : unit = ()
> arr.[2] <- Some(55uy);;
val it : unit = ()
> arr.[0] > arr.[2];;
val it : bool = true
> arr.[0] < arr.[2];;
val it : bool = false
> arr.[0] < arr.[1];;
val it : bool = false
> arr.[0] > arr.[1];;
val it : bool = true
> arr.[2] > arr.[1];;
val it : bool = true
> arr.[3] > arr.[1];;
val it : bool = false
> arr.[3] < arr.[1];;
val it : bool = false
> arr.[3] > arr.[1];;
val it : bool = false
It seems to me that essentially the comparison operators must always return true (false) when asking whether a Some is greater (less) than a None, two Nones always return false, and two Somes of the same contained type compare the contained values (assuming that they can be compared I imagine). This makes sense, though I was surprised.
Wanting to confirm this, I attempted to track something down that would explain the behaviour I should expect, but I couldn't find anything that addressed the point. The Option page in the MS F# Guide docs doesn't make any mention of it, and I couldn't find anything in places like F# for fun and profit. I couldn't even manage to find a page about Option anywhere in the MS API docs... Looking at the source for Option in the F# GitHub repo doesn't tell me anything. The best I could find was a blog post by Don Syme from years ago, which didn't actually answer my question. There were a smattering of Stack Overflow questions that discussed topics to do with the comparison operators or Option types, but I didn't find anything that dealt with the combination of the two.
So, my question is, does performing greater than/less than comparisons on the Option type return the results I have speculated about above? I'm guessing that this is reasonably common knowledge amongst F# programmers, but it was news to me. As a sub-/related question, does anyone know where I could/should have looked to for more information? Thanks.

The F# compiler automatically generates comparison for discriminated unions and record types. Since option is just a discriminated union, this also means that you get an automatic comparison for unions. I'm not sure if there is a good web page documenting this, but you can find a description in section 8.15.4 in the F# specification:
8.15.4 Behavior of the Generated CompareTo Implementations
For a type T, the behavior of the generated System.IComparable.CompareTo implementation is as
follows:
Convert the y argument to type T . If the conversion fails, raise the InvalidCastException.
If T is a reference type and y is null, return 1.
If T is a struct or record type, invoke FSharp.Core.Operators.compare on each corresponding pair
of fields of x and y in declaration order, and return the first non-zero result.
If T is a union type, invoke FSharp.Core.Operators.compare first on the index of the union cases
for the two values, and then on each corresponding field pair of x and y for the data carried by
the union case. Return the first non-zero result.
As documented in the last case, the case for option first compares the cases. None has an index smaller than Some so a None value will always be smaller than any Some value. If the cases match, then None = None and Some n with Some m are compared based on n and m.

Related

This expression was expected to have type bool but here has type unit error

getting an error when I try to run this line of code and I can't figure out why
let validCol column value : bool =
for i in 0..8 do
if sudokuBoard.[i,column] = value then
false
else true
As Tyler Hartwig says a for loop cannot return a value except unit.
On the other hand, inside a list comprehension or a seq Computation Expression you can use for to yield the values and then test if the one you are looking for exists:
let validCol column value : bool =
seq { for i in 0..8 do yield sudokuBoard.[i,column] }
|> Seq.exists value
|> not
In F#, the last call made is what is returned, you have explicitly declared you are returning a bool.
The for loop is unable to return or aggregate multiple values, bun instead, returns unit.
let validCol column value : bool =
for i in 0..8 do
if sudokuBoard.[i,column] = value then
false
else
true
Here, you'll need to figure out how to aggregate all the bool to get your final result. I'm not quite sure what this is supposed to return, or I'd give an example.
It looks like you are looking for a short-cut out of the loop like in C# you can use continue, break or return to exit a loop.
In F# the way to accomplish that with performance is to use tail-recursion. You could achieve it with while loops but that requires mutable variables which tail-recursion doesn't need (although we sometimes uses it).
A tail-recursive function is one that calls itself at the very end and doesn't look at the result:
So this is tail-recursive
let rec loop acc i = if i > 0 then loop (acc + i) (i - 1) else acc
Where this isn't
let rec loop fib i = if i < 1 then 1 else fib (i - 1) + fib (i - 2)
If F# compiler determines a function is tail-recursive the compiler applies tail-recursion optimization (TCO) on the function, basically it unrolls it into an efficient for loop that looks a lot like the loop would like in C#.
So here is one way to write validCol using tail-recursion:
let validCol column value : bool =
// loops is tail-recursive
let rec loop column value i =
if i < 9 then
if sudokuBoard.[i,column] = value then
false // The value already exists in the column, not valid
else
loop column value (i + 1) // Check next row.
else
true // Reach the end, the value is valid
loop column value 0
Unfortunately; F# compiler doesn't have an attribute to force TCO (like Scala or kotlin does) and therefore if you make a slight mistake you might end up with a function that isn't TCO. I think I saw GitHub issue about adding such an attribute.
PS. seq comprehensions are nice in many cases but for a sudoku solver I assume you are looking for something that is as fast as possible. seq comprehensions (and LINQ) I think adds too much overhead for a sudoku solver whereas tail-recursion is about as quick as you can get in F#.
PS. In .NET 2D arrays are slower than 1D arrays, just FYI. Unsure if it has improved with dotnet core.

When to use ternary operators? [duplicate]

What are the benefits and drawbacks of the ?: operator as opposed to the standard if-else statement. The obvious ones being:
Conditional ?: Operator
Shorter and more concise when dealing with direct value comparisons and assignments
Doesn't seem to be as flexible as the if/else construct
Standard If/Else
Can be applied to more situations (such as function calls)
Often are unnecessarily long
Readability seems to vary for each depending on the statement. For a little while after first being exposed to the ?: operator, it took me some time to digest exactly how it worked. Would you recommend using it wherever possible, or sticking to if/else given that I work with many non-programmers?
I would basically recommend using it only when the resulting statement is extremely short and represents a significant increase in conciseness over the if/else equivalent without sacrificing readability.
Good example:
int result = Check() ? 1 : 0;
Bad example:
int result = FirstCheck() ? 1 : SecondCheck() ? 1 : ThirdCheck() ? 1 : 0;
This is pretty much covered by the other answers, but "it's an expression" doesn't really explain why that is so useful...
In languages like C++ and C#, you can define local readonly fields (within a method body) using them. This is not possible with a conventional if/then statement because the value of a readonly field has to be assigned within that single statement:
readonly int speed = (shiftKeyDown) ? 10 : 1;
is not the same as:
readonly int speed;
if (shifKeyDown)
speed = 10; // error - can't assign to a readonly
else
speed = 1; // error
In a similar way you can embed a tertiary expression in other code. As well as making the source code more compact (and in some cases more readable as a result) it can also make the generated machine code more compact and efficient:
MoveCar((shiftKeyDown) ? 10 : 1);
...may generate less code than having to call the same method twice:
if (shiftKeyDown)
MoveCar(10);
else
MoveCar(1);
Of course, it's also a more convenient and concise form (less typing, less repetition, and can reduce the chance of errors if you have to duplicate chunks of code in an if/else). In clean "common pattern" cases like this:
object thing = (reference == null) ? null : reference.Thing;
... it is simply faster to read/parse/understand (once you're used to it) than the long-winded if/else equivalent, so it can help you to 'grok' code faster.
Of course, just because it is useful does not mean it is the best thing to use in every case. I'd advise only using it for short bits of code where the meaning is clear (or made more clear) by using ?: - if you use it in more complex code, or nest ternary operators within each other it can make code horribly difficult to read.
I usually choose a ternary operator when I'd have a lot of duplicate code otherwise.
if (a > 0)
answer = compute(a, b, c, d, e);
else
answer = compute(-a, b, c, d, e);
With a ternary operator, this could be accomplished with the following.
answer = compute(a > 0 ? a : -a, b, c, d, e);
I find it particularly helpful when doing web development if I want to set a variable to a value sent in the request if it is defined or to some default value if it is not.
A really cool usage is:
x = foo ? 1 :
bar ? 2 :
baz ? 3 :
4;
Sometimes it can make the assignment of a bool value easier to read at first glance:
// With
button.IsEnabled = someControl.HasError ? false : true;
// Without
button.IsEnabled = !someControl.HasError;
I'd recommend limiting the use of the ternary(?:) operator to simple single line assignment if/else logic. Something resembling this pattern:
if(<boolCondition>) {
<variable> = <value>;
}
else {
<variable> = <anotherValue>;
}
Could be easily converted to:
<variable> = <boolCondition> ? <value> : <anotherValue>;
I would avoid using the ternary operator in situations that require if/else if/else, nested if/else, or if/else branch logic that results in the evaluation of multiple lines. Applying the ternary operator in these situations would likely result in unreadable, confusing, and unmanageable code. Hope this helps.
The conditional operator is great for short conditions, like this:
varA = boolB ? valC : valD;
I use it occasionally because it takes less time to write something that way... unfortunately, this branching can sometimes be missed by another developer browsing over your code. Plus, code isn't usually that short, so I usually help readability by putting the ? and : on separate lines, like this:
doSomeStuffToSomething(shouldSomethingBeDone()
? getTheThingThatNeedsStuffDone()
: getTheOtherThingThatNeedsStuffDone());
However, the big advantage to using if/else blocks (and why I prefer them) is that it's easier to come in later and add some additional logic to the branch,
if (shouldSomethingBeDone()) {
doSomeStuffToSomething(getTheThingThatNeedsStuffDone());
doSomeAdditionalStuff();
} else {
doSomeStuffToSomething(getTheOtherThingThatNeedsStuffDone());
}
or add another condition:
if (shouldSomethingBeDone()) {
doSomeStuffToSomething(getTheThingThatNeedsStuffDone());
doSomeAdditionalStuff();
} else if (shouldThisOtherThingBeDone()){
doSomeStuffToSomething(getTheOtherThingThatNeedsStuffDone());
}
So, in the end, it's about convenience for you now (shorter to use :?) vs. convenience for you (and others) later. It's a judgment call... but like all other code-formatting issues, the only real rule is to be consistent, and be visually courteous to those who have to maintain (or grade!) your code.
(all code eye-compiled)
One thing to recognize when using the ternary operator that it is an expression not a statement.
In functional languages like scheme the distinction doesn't exists:
(if (> a b) a b)
Conditional ?: Operator
"Doesn't seem to be as flexible as the if/else construct"
In functional languages it is.
When programming in imperative languages I apply the ternary operator in situations where I typically would use expressions (assignment, conditional statements, etc).
While the above answers are valid, and I agree with readability being important, there are 2 further points to consider:
In C#6, you can have expression-bodied methods.
This makes it particularly concise to use the ternary:
string GetDrink(DayOfWeek day)
=> day == DayOfWeek.Friday
? "Beer" : "Tea";
Behaviour differs when it comes to implicit type conversion.
If you have types T1 and T2 that can both be implicitly converted to T, then the below does not work:
T GetT() => true ? new T1() : new T2();
(because the compiler tries to determine the type of the ternary expression, and there is no conversion between T1 and T2.)
On the other hand, the if/else version below does work:
T GetT()
{
if (true) return new T1();
return new T2();
}
because T1 is converted to T and so is T2
If I'm setting a value and I know it will always be one line of code to do so, I typically use the ternary (conditional) operator. If there's a chance my code and logic will change in the future, I use an if/else as it's more clear to other programmers.
Of further interest to you may be the ?? operator.
The advantage of the conditional operator is that it is an operator. In other words, it returns a value. Since if is a statement, it cannot return a value.
There is some performance benefit of using the the ? operator in eg. MS Visual C++, but this is a really a compiler specific thing. The compiler can actually optimize out the conditional branch in some cases.
The scenario I most find myself using it is for defaulting values and especially in returns
return someIndex < maxIndex ? someIndex : maxIndex;
Those are really the only places I find it nice, but for them I do.
Though if you're looking for a boolean this might sometimes look like an appropriate thing to do:
bool hey = whatever < whatever_else ? true : false;
Because it's so easy to read and understand, but that idea should always be tossed for the more obvious:
bool hey = (whatever < whatever_else);
If you need multiple branches on the same condition, use an if:
if (A == 6)
f(1, 2, 3);
else
f(4, 5, 6);
If you need multiple branches with different conditions, then if statement count would snowball, you'll want to use the ternary:
f( (A == 6)? 1: 4, (B == 6)? 2: 5, (C == 6)? 3: 6 );
Also, you can use the ternary operator in initialization.
const int i = (A == 6)? 1 : 4;
Doing that with if is very messy:
int i_temp;
if (A == 6)
i_temp = 1;
else
i_temp = 4;
const int i = i_temp;
You can't put the initialization inside the if/else, because it changes the scope. But references and const variables can only be bound at initialization.
The ternary operator can be included within an rvalue, whereas an if-then-else cannot; on the other hand, an if-then-else can execute loops and other statements, whereas the ternary operator can only execute (possibly void) rvalues.
On a related note, the && and || operators allow some execution patterns which are harder to implement with if-then-else. For example, if one has several functions to call and wishes to execute a piece of code if any of them fail, it can be done nicely using the && operator. Doing it without that operator will either require redundant code, a goto, or an extra flag variable.
With C# 7, you can use the new ref locals feature to simplify the conditional assignment of ref-compatible variables. So now, not only can you do:
int i = 0;
T b = default(T), c = default(T);
// initialization of C#7 'ref-local' variable using a conditional r-value⁽¹⁾
ref T a = ref (i == 0 ? ref b : ref c);
...but also the extremely wonderful:
// assignment of l-value⁽²⁾ conditioned by C#7 'ref-locals'
(i == 0 ? ref b : ref c) = a;
That line of code assigns the value of a to either b or c, depending on the value of i.
Notes
1. r-value is the right-hand side of an assignment, the value that gets assigned.
2. l-value is the left-hand side of an assignment, the variable that receives the assigned value.

Testing collections with FSUnit.Xunit

I'm trying to test equality of two collections in F# using FSUnit (specifically its Xunit branch) but failing horribly so far.
I have a function that returns an array of certain structs and would like to test whether the returned array is correct. The code I'm testing is in C# so it so the function can't return native F# lists.
The most promising approach I've tried is following:
[<Fact>]
let SimpleTest() =
let parser = new ExpressionParser()
parser.ParseExpression "2" |> should equal [new ParsedItem("2", ParsedItemType.Value)]
...but it results in the the test failing because of:
"Message> FSUnit.Xunit+MatchException: Exception of type 'FsUnit.Xunit+MatchException' was thrown.
Expected value: Equals [(2)]
Actual: was [2]
I can see that it's because the type of native F# list doesn't match a native array but have honestly no idea (nor have I found anything in documentation) how to do it differently (other then creating native array beforehand and populating it one by one...).
I've also tried some other approaches but they usually wouldn't even compile.
PS: I'm completely new to both F# and Xunit so I might be missing something absolutely obvious.
EDIT: A workaround that actually works better was suggested in comments (comparing string representations instead of the objects themselves) and while I will use that in my actual code I'd still appreciate a true solution to my problem above.
Although you can't easily return F# lists from your C# code, one option is to return arrays. These have structural equality, so you can simply compare them to determine if they are equal to each other:
open System.Linq
let csharpArray = Enumerable.Range(0, 10).ToArray()
let fsharpArray = [| 0..9 |]
These two arrays are equal:
> csharpArray = fsharpArray;;
val it : bool = true
If you don't want to return arrays, you can also return IEnumerable<T>, and convert to either lists or arrays in F#:
> let csharpEnumerable = Enumerable.Range(0, 10);;
val csharpEnumerable : System.Collections.Generic.IEnumerable<int>
> csharpEnumerable |> Seq.toList = [0..9];;
val it : bool = true
For a more comprehensive to introduction to unit testing with F#, you may want to view my Pluralsight course on the topic.
Ok, I've found the answer and it's simpler than I thought it'd be. First off the assentation works well the problem was in syntax and me not bothering to read the documentation on how to create an array in F# and just guessing it.
There were two things wrong. First [new ParsedItem("2", ParsedItemType.Value)] doesn't create an array it creates a list. That in itself wouldn't be a problem for FSUnit's should equal but it's enough to make simple structural equality test using = fail.
The second thing that was wrong was that I didn't really compare with [new ParsedItem("2", ParsedItemType.Value)] I compared with [new ParsedItem("2", ParsedItemType.Value), new ParsedItem("+", ParsedItemType.Operator), new ParsedItem("3", ParsedItemType.Value)] and that actually creates a list containing one touple. And that - unsurprisingly - didn't assert well :).
Simply reading the documentation and learning that an array is supposed to be created [|new ParsedItem("2", ParsedItemType.Value); new ParsedItem("+", ParsedItemType.Operator); new ParsedItem("3", ParsedItemType.Value)|] fixed the issue.
Anyway, thanks for the comments and the other answer. Though they didn't answer my question they increased my knowledge about F# and gave me a new idea how to test :).

Finding if Integer is Even or Odd

I am learning Erlang and one of the problems as per Joe's book states
The function even(X) should return true if X is an even integer and
otherwise false. odd(X) should return true if X is an odd integer.
The way I solve this is
-module(math_functions).
%% API
-export([even/1, odd/1]).
even(Integer) -> (Integer >= 0) and (Integer rem 2 =:= 0).
odd(Integer) -> (Integer >= 1) and (Integer rem 2 =/= 0).
and run this as
Eshell V6.2 (abort with ^G)
1> math_functions:odd(13).
true
2> math_functions:odd(-13).
false
3> math_functions:odd(1).
true
4> math_functions:even(1).
false
5> math_functions:even(2).
true
6> math_functions:even(-2).
false
7>
The question I have is if there are better ways to do this
Thanks
You could use guards to limit yourself to integers greater than or equal to zero, and then simply check the least-significant bit as suggested in the comment to your question. You can also define odd/1 in terms of even/1:
even(X) when X >= 0 -> (X band 1) == 0.
odd(X) when X > 0 -> not even(X).
The guards are part of the function-head, so if you call even(-1) it will fail to match in exactly the same way as if you called even(1, 2) (i.e. with the wrong number of arguments).
Answer to Daydreamer comment about Steve answer.
When you write a function, a frequent usage in erlang is to code only the "success" cases and let crash the unsuccessful cases (I'll come back later to explain why it is important).
Another criteria, valid for any language, is to avoid surprise when someone use or read your code.
In one of your comment you say that the odd and even functions you want to write are limited to positive or null integers (I won't discuss this choice, and at least the odd and even functions are limited to integers). This means that you have to ask yourself a first question: what is the behavior of my function if it is called with a bad parameter.
First choice: let it crash this the Steve proposition: the function works only with the correct arguments. I always prefer this solution. The only exception is if I do not master the input parameters, for example if they come directly from a file, a user interface ... Then I prefer the third choice.
Second choice: return a result this is your choice: you return false. From a logic point of view, for odd and even function, returning false is valid: is something is not true, it is false :o). I don't like this solution for 2 reasons. The first one is that it is not something you can generalize easily to something else than boolean answer. The second and more important to me, is that it may surprise the user. When the function odd(N) return false, it is reasonable to think that N is even, while in this case odd(-2) and even(-2) will both return false.
third choice: return a tagged result this is something you see very often in erlang: a function return either {ok,Value} or {Error,Term}. doing this you let the choice to the calling function to manage or not a bad arguments errors. the Error variable allows you to have explicit error messages, useful for debug and also user interface. In your example the code becomes:
even(X) when is_integer(X), X >= 0 -> {ok,(X band 1) == 0};
even(X) -> {illegal_param,X}.
odd(X) when is_integer(X), X >= 0 -> {ok,(X band 1) == 1};
odd(X) -> {illegal_param,X}.
When programming, it is important to detect error as soon as possible, in erlang it is even more important. If one process does not detect (and the simplest detection is crash) and error and propagate some invalid information through messages, it may be very difficult to find the root cause of a problem, ignoring which process (maybe died) issued this message. Coding only the success cases is an easy way to detect problems as soon as possible.
Find the no if even
%functions that manipulate functions are called higher-order %functions, and the data type that represents a function in Erlang is %called a fun. here in below example you see FUNCTIONS THAT HAVE %FUNCTIONS AS THEIR ARGUMENTS
% K is an example list
1> K=[4,5,6,8,10].
[4,5,6,8,10]
% Use lisst:filter to perform no/2 and filter if rem=0
2> lists:filter(fun(J)->(J rem 2)=:=0 end, K).
[4,6,8,10]
Another way:
% Function to check even
22> Checkeven=fun(U)->(U rem 2)=:=0 end.
#Fun<erl_eval.7.126501267>
23> Checkeven(5).
false
% Define a test list
25> K=[1,2,3,4,5].
[1,2,3,4,5]
% Use lists filter to apply Checkeven func to all elements of k
26> lists:filter(Checkeven,K).
[2,4]
%Using List comprehension
42> K.
[1,2,3,4,5]
% For all elements of K check remainder of elem/2 is zero
43> [(S rem 2=:=0) || S<-K].
[false,true,false,true,false]

How do I turn this Extension Method into an Extension Property?

I have an extension method
type System.Int32 with
member this.Thousand() = this * 1000
but it requires me to write like this
(5).Thousand()
I'd love to get rid of both parenthesis, starting with making it a property instead of a method (for learning sake) how do I make this a property?
Jon's answer is one way to do it, but for a read-only property there's also a more concise way to write it:
type System.Int32 with
member this.Thousand = this * 1000
Also, depending on your preferences, you may find it more pleasing to write 5 .Thousand (note the extra space) than (5).Thousand (but you won't be able to do just 5.Thousand, or even 5.ToString()).
I don't really know F# (shameful!) but based on this blog post, I'd expect:
type System.Int32 with
member this.Thousand
with get() = this * 1000
I suspect that won't free you from the first set of parentheses (otherwise F# may try to parse the whole thing as a literal), but it should help you with the second.
Personally I wouldn't use this sort of thing for a "production" extension, but it's useful for test code where you're working with a lot of values.
In particular, I've found it neat to have extension methods around dates, e.g. 19.June(1976) as a really simple, easy-to-read way of building up test data. But not for production code :)
It's not beautiful, but if you really want a function that will work for any numeric type, you can do this:
let inline thousand n =
let one = LanguagePrimitives.GenericOne
let thousand =
let rec loop n i =
if i < 1000 then loop (n + one) (i + 1)
else n
loop one 1
n * thousand
5.0 |> thousand
5 |> thousand
5I |> thousand

Resources