Is there a bug in Series.hasNot? - f#

The help for function Series.hasNot in Deedle says:
Returns true when the series does not contains value for the specified key
The function does not seem to be working this way in the following example:
let election =
[ "Party A", 304
"Party B", 25
"Party C", 570
"Party Y", 2
"Party Z", 258 ]
|> series
let bhnt =
election
|> Series.hasNot "Party A"
printfn "%A" <| bhnt
// true
// val bhnt : bool = true
// val it : unit = ()
Am I missing something?

I just looked at the Deedle source and saw the following:
let has key (series:Series<'K, 'T>) = series.TryGet(key).HasValue
let hasNot key (series:Series<'K, 'T>) = series.TryGet(key).HasValue
Yes, you've found a bug. The hasNot function should have looked like not (series.TryGet(key).HasValue).
Workaround: Until this bug is fixed, you can work around it by replacing all occurrences of Series.hasNot key in your code by Series.has key and then piping through the not function. E.g.,
let bhnt =
election
|> Series.has "Party A"
|> not
Or, if you think it looks better, you could also write that as:
let bhnt =
election
|> (not << Series.has "Party A")
These two ways of writing it are equivalent; which one you prefer to use will depend on how comfortable you are with functional programming. Some people find the << syntax more natural to read, while others find it completely weird and want to stick to using only |>. It all depends on how experienced you are with functional programming; pick whichever of these two feels the most natural to you.

Related

Declaring a variable without assigning workaround

i'm writing a small console application in F#.
[<EntryPoint>]
let main argv =
high_lvl_funcs.print_opt
let opt = Console.ReadLine()
match opt with
| "0" -> printfn "%A" (high_lvl_funcs.calculate_NDL)
| "1" -> printfn ("not implemented yet")
| _ -> printfn "%A is not an option" opt
from module high_lvl_funcs
let print_opt =
let options = [|"NDL"; "Deco"|]
printfn "Enter the number of the option you want"
Array.iteri (fun i x -> printfn "%A: %A" i x) options
let calculate_NDL =
printfn ("enter Depth in m")
let depth = lfuncs.m_to_absolute(float (Console.ReadLine()))
printfn ("enter amount of N2 in gas (assuming o2 is the rest)")
let fn2 = float (Console.ReadLine())
let table = lfuncs.read_table
let tissue = lfuncs.create_initialise_Tissues ATM WATERVAPOUR
lfuncs.calc_NDL depth fn2 table lfuncs.loading_constantpressure tissue 0.0
lfuncs.calc_NDL returns a float
this produces this
Enter the number of the option you want
0: "NDL"
1: "Deco"
enter Depth in m
which means it prints what it's suppose to then jumps straight to high_lvl_funcs.calculate_NDL
I wanted it to produce
Enter the number of the option you want
0: "NDL"
1: "Deco"
then let's assume 0 is entered, and then calculate high_lvl_funcs.calculate_NDL
after some thinking and searching i assume this is because F# wants to assign all values before it starts the rest. Then i thought that i need to declaring a variable without assigning it. but people seem to agree that this is bad in functional programming. From another question: Declaring a variable without assigning
so my question is, is it possible to rewrite the code such that i get the flow i want and avoid declaring variables without assigning them?
You can fix this by making calculate_NDL a function of no arguments, instead of a closure that evaluates to a float:
let calculate_NDL () =
Then call it as a function in your match like this:
match opt with
| "0" -> printfn "%A" (high_lvl_funcs.calculate_NDL())
However I'd suggest refactoring this code so that calculate_NDL takes any necessary inputs as arguments rather than reading them from the console i.e. read the inputs from the console separately and pass them to calculate_NDL.
let calculate_NDL depth fn2 =
let absDepth = lfuncs.m_to_absolute(depth)
let table = lfuncs.read_table
let tissue = lfuncs.create_initialise_Tissues ATM WATERVAPOUR
lfuncs.calc_NDL absDepth fn2 table lfuncs.loading_constantpressure tissue 0.0
It's generally a good idea to write as much code as possible as pure functions that don't rely on I/O (like reading from stdin).

Deedle Equivalent to pandas.merge

I am looking to merge two Deedle (F#) frames based on a specific column in each frame in a similar manner as pandas.DataFrame.Merge.The perfect example of this would be a primary frame that contains columns of data and a (city, state) column along with an information frame that contains the following columns: (city, state); lat; long. If I want to add the lat long columns into my primary frame, I would merge the two frames on the (city, state) column.
Here is an example:
let primaryFrame =
[(0, "Job Name", box "Job 1")
(0, "City, State", box "Reno, NV")
(1, "Job Name", box "Job 2")
(1, "City, State", box "Portland, OR")
(2, "Job Name", box "Job 3")
(2, "City, State", box "Portland, OR")
(3, "Job Name", box "Job 4")
(3, "City, State", box "Sacramento, CA")] |> Frame.ofValues
let infoFrame =
[(0, "City, State", box "Reno, NV")
(0, "Lat", box "Reno_NV_Lat")
(0, "Long", box "Reno_NV_Long")
(1, "City, State", box "Portland, OR")
(1, "Lat", box "Portland_OR_Lat")
(1, "Long", box "Portland_OR_Long")] |> Frame.ofValues
// see code for merge_on below.
let mergedFrame = primaryFrame
|> merge_On infoFrame "City, State" null
Which would result in 'mergedFrame' looking like this:
> mergedFrame.Format();;
val it : string =
" Job Name City, State Lat Long
0 -> Job 1 Reno, NV Reno_NV_Lat Reno_NV_Long
1 -> Job 2 Portland, OR Portland_OR_Lat Portland_OR_Long
2 -> Job 3 Portland, OR Portland_OR_Lat Portland_OR_Long
3 -> Job 4 Sacramento, CA <missing> <missing>
I have come up with a way of doing this (the 'merge_on' function used in the example above), but being a Sales Engineer who is new to F#, I imagine there is a more idiomatic/efficient way of doing this. Below is my functions for doing this along with a 'removeDuplicateRows' which does what you would expect and was needed for the 'merge_on' function; if you want to comment on a better way of doing this as well, please do.
let removeDuplicateRows column (frame : Frame<'a, 'b>) =
let nonDupKeys = frame.GroupRowsBy(column).RowKeys
|> Seq.distinctBy (fun (a, b) -> a)
|> Seq.map (fun (a, b) -> b)
frame.Rows.[nonDupKeys]
let merge_On (infoFrame : Frame<'c, 'b>) mergeOnCol missingReplacement
(primaryFrame : Frame<'a,'b>) =
let frame = primaryFrame.Clone()
let infoFrame = infoFrame
|> removeDuplicateRows mergeOnCol
|> Frame.indexRows mergeOnCol
let initialSeries = frame.GetColumn(mergeOnCol)
let infoFrameRows = infoFrame.RowKeys
for colKey in infoFrame.ColumnKeys do
let newSeries =
[for v in initialSeries.ValuesAll do
if Seq.contains v infoFrameRows then
let key = infoFrame.GetRow(v)
yield key.[colKey]
else
yield box missingReplacement ]
frame.AddColumn(colKey, newSeries)
frame
Thanks for your help!
UPDATE:
Switched Frame.indexRowsString to Frame.indexRows to handle cases where the types in the 'mergOnCol' are not strings.
Got rid of infoFrame.Clone() as suggested by Tomas
The way Deedle does joining of frames (only in row/column keys) sadly means that it does not have a nice built-in function to do joining of frames over a non-key column.
As far as I can see, your approach looks very good to me. You do not need Clone on the infoFrame (because you are not mutating the frame) and I think you can replace infoFrame.GetRow with infoFrame.TryGetRow (and then you won't need to get the keys in advance), but other than that, your code looks fine!
I came up with an alternative and a bit shorter way of doing this, which looks as follows:
// Index the info frame by city/state, so that we can do lookup
let infoByCity = infoFrame |> Frame.indexRowsString "City, State"
// Create a new frame with the same row indices as 'primaryFrame'
// containing the additional information from infoFrame.
let infoMatched =
primaryFrame.Rows
|> Series.map (fun k row ->
// For every row, we get the "City, State" value of the row and then
// find the corresponding row with additional information in infoFrame. Using
// 'ValueOrDefault' will automatically give missing when the key does not exist
infoByCity.Rows.TryGet(row.GetAs<string>("City, State")).ValueOrDefault)
// Now turn the series of rows into a frame
|> Frame.ofRows
// Now we have two frames with matching keys, so we can join!
primaryFrame.Join(infoMatched)
This is a bit shorter and maybe more self-explanatory, but I have not done any tests to check which is faster. Unless performance is a primary concern, I think going with the more readable version is a good default choice though!

F# Data: JSON Parser. Using JsonExtensions

It is my first question on SO...so do not judge strictly =)
Usually all my questions techout in chat rooms (believe me, a lot of them =)).
Recently, we are talking about the RosettaCode. And I wondered to complement some of the tasks code to F#
One of them is JSON.
One of the possible solutions is the use of "F# Data: JSON Parser". So my question is linked with it.
This code works well:
open FSharp.Data
open FSharp.Data.JsonExtensions
type Person = {ID: int; Name:string}
let json = """[ { "ID": 1, "Name": "First" }, { "ID": 2, "Name": "Second" }]"""
json |> printfn "%s"
match JsonValue.Parse(json) with
| JsonValue.Array(x) ->
x |> Array.map(fun x -> {ID = System.Int32.Parse((x?ID).ToString()); Name = (string x?Name)})
| _ -> failwith "fail json"
|> Array.iter(fun x -> printfn "%i %s" x.ID x.Name)
Print:
[ { "ID": 1, "Name": "First" }, { "ID": 2, "Name": "Second" }]
1 "First"
2 "Second"
But it
{ID = System.Int32.Parse((x?ID).ToString()); Name = (string x?Name)}
doesn't look good.
This I read about JsonExtensions,
but when I use
{ID = (x?ID.AsInteger()) ; Name = (x?Name.AsString()) }
I get compile errors:
The field, constructor or "AsInteger" is not defined
The field, constructor or "AsString" is not defined
Strangely, thing is that I see accessibility through "open FSharp.Data.JsonExtensions"
So, question: How to use JsonExtensions?
I tried to reproduce this using a minimal example, but I do not get the error - can you try the following minimal sample?
#r "...../FSharp.Data.dll"
open FSharp.Data.JsonExtensions
open FSharp.Data
JsonValue.Parse("A").AsArray()
|> Array.map (fun a -> a?ID.AsInteger())
I do not get auto-completion on a?ID. (which is a limitation of the editor), but it compiles fine.
The only reason why I think this could be not working is if you had another open declaration that would import another implementation of the ? operator that is not returning JsonValue.
The JsonValue API is certainly not as nice as just using the type provider - so if you can, I'd probably go for the type provider instead (the low-level API is good if you need to iterate over everything in JSON recursively).

Is a pattern match the only way to get data associated with a union case?

Let's say you have this union:
type Thing =
| Eagle
| Elephant of int
And your code has a list of Elephants, as in
let l = [Elephant (1000); Elephant (1200)]
And you wanted to iterate over l, and print out the data associated with each Elephant. Is there a way to do so without using a pattern match?
In your example, you say that you have a list of elephants - which is true in this case - but the type of l is really a list of Thing values and so it can contain both elephants and eagles. This is why you need to use pattern matching - to handle all possible cases.
If you regularly need to use list that contain only elephants, then it might make sense to define a separate type of elephants. Something like:
type ElephantInfo = { Size : int }
type Thing =
| Elephant of ElephantInfo
| Eagle
Now you can create a list of type list<ElephantInfo> which can contain just elephants and so you don't need pattern matching:
let l1 = [ {Size=1}; {Size=2} ]
for el in l1 do printfn "%d" el.Size
On the other hand, if you want to mix elephants and eagles, you'll create list<Thing> and then use pattern matching:
let l2 = [ Elephant {Size=1}; Eagle ]
You could do this:
l
|> List.collect (function Elephant x -> [x] | _ -> [])
|> List.iter (printfn "%i")
Prints
1000
1200
It still uses pattern matching, but it's fairly minimal.
You have of course the option of going full Ivory Tower (® Scott Wlaschin)
As in about:
type Thing =
| Eagle
| Elephant of int
type MaybeElephantBuilder() =
member this.Bind(x, f) =
match x with
| Eagle -> 0
| Elephant a -> f a
member this.Return(x) = x
let maybeElephant = new MaybeElephantBuilder()
let l =
[ Elephant(1000)
Elephant(1200)
]
let printIt v =
let i =
maybeElephant {
let! elephantValue = v
return elephantValue
}
printfn "%d" i
l |> Seq.iter printIt
It will even handle the stuff with the Eagles thrown in there!
Well...
Remove the non-Eagles and the code will fly...
let l =
[ Eagle
Leadon
Elephant(1000)
Eagle
Meisner
Elephant(1200)
Eagle
Felder
]
l |> Seq.iter printIt
But no. Its not nice. Its not short. Its more for fun (if that!) than anything else. Its probably the worst misuse of F# computation expressions ever too!
And you will need pattern matching somewhere.
Thx Scott! And Petricek.
Computation Expression Zoo for real! ;-)
You can use reflection from Microsoft.FSharp.Reflection Namespace but it is much more cumbersome and slow.
Pattern matching is probably the easiest way to get data from discriminated union.
(Also you have a list of Things all its members happen to be of Elephant union case).
There's a way to place the pattern match into the header of the function (or a let binding). It is still a pattern match, though.
// This function takes a tuple:
// the first argument is a Thing,
// the second is "default" weight to be processed if the first one is NOT an Elephant
let processElephant (Elephant weight, _ | _, weight) =
weight
let [<Literal>] NON_ELEPHANT_WEIGHT = -1
// usage:
let totalWeight =
[Elephant (1000); Elephant (1200)]
|> List.sumBy (fun el -> processElephant(el, NON_ELEPHANT_WEIGHT))
This question and its answers provide with more details.

F# curried function

Anyone have a decent example, preferably practical/useful, they could post demonstrating the concept?
(Edit: a small Ocaml FP Koan to start things off)
The Koan of Currying (A koan about food, that is not about food)
A student came to Jacques Garrigue and said, "I do not understand what currying is good for." Jacques replied, "Tell me your favorite meal and your favorite dessert". The puzzled student replied that he liked okonomiyaki and kanten, but while his favorite restaurant served great okonomiyaki, their kanten always gave him a stomach ache the following morning. So Jacques took the student to eat at a restaurant that served okonomiyaki every bit as good as the student's favorite, then took him across town to a shop that made excellent kanten where the student happily applied the remainder of his appetite. The student was sated, but he was not enlightened ... until the next morning when he woke up and his stomach felt fine.
My examples will cover using it for the reuse and encapsulation of code. This is fairly obvious once you look at these and should give you a concrete, simple example that you can think of applying in numerous situations.
We want to do a map over a tree. This function could be curried and applied to each node if it needs more then one argument -- since we'd be applying the one at the node as it's final argument. It doesn't have to be curried, but writing another function (assuming this function is being used in other instances with other variables) would be a waste.
type 'a tree = E of 'a | N of 'a * 'a tree * 'a tree
let rec tree_map f tree = match tree with
| N(x,left,right) -> N(f x, tree_map f left, tree_map f right)
| E(x) -> E(f x)
let sample_tree = N(1,E(3),E(4)
let multiply x y = x * y
let sample_tree2 = tree_map (multiply 3) sample_tree
but this is the same as:
let sample_tree2 = tree_map (fun x -> x * 3) sample_tree
So this simple case isn't convincing. It really is though, and powerful once you use the language more and naturally come across these situations. The other example with some code reuse as currying. A recurrence relation to create prime numbers. Awful lot of similarity in there:
let rec f_recurrence f a seed n =
match n with
| a -> seed
| _ -> let prev = f_recurrence f a seed (n-1) in
prev + (f n prev)
let rowland = f_recurrence gcd 1 7
let cloitre = f_recurrence lcm 1 1
let rowland_prime n = (rowland (n+1)) - (rowland n)
let cloitre_prime n = ((cloitre (n+1))/(cloitre n)) - 1
Ok, now rowland and cloitre are curried functions, since they have free variables, and we can get any index of it's sequence without knowing or worrying about f_recurrence.
While the previous examples answered the question, here are two simpler examples of how Currying can be beneficial for F# programming.
open System.IO
let appendFile (fileName : string) (text : string) =
let file = new StreamWriter(fileName, true)
file.WriteLine(text)
file.Close()
// Call it normally
appendFile #"D:\Log.txt" "Processing Event X..."
// If you curry the function, you don't need to keep specifying the
// log file name.
let curriedAppendFile = appendFile #"D:\Log.txt"
// Adds data to "Log.txt"
curriedAppendFile "Processing Event Y..."
And don't forget you can curry the Printf family of function! In the curried version, notice the distinct lack of a lambda.
// Non curried, Prints 1 2 3
List.iter (fun i -> printf "%d " i) [1 .. 3];;
// Curried, Prints 1 2 3
List.iter (printfn "%d ") [1 .. 3];;
Currying describes the process of transforming a function with multiple arguments into a chain of single-argument functions. Example in C#, for a three-argument function:
Func<T1, Func<T2, Func<T3, T4>>> Curry<T1, T2, T3, T4>(Func<T1, T2, T3, T4> f)
{
return a => b => c => f(a, b, c);
}
void UseACurriedFunction()
{
var curryCompare = Curry<string, string, bool, int>(String.Compare);
var a = "SomeString";
var b = "SOMESTRING";
Console.WriteLine(String.Compare(a, b, true));
Console.WriteLine(curryCompare(a)(b)(true));
//partial application
var compareAWithB = curryCompare(a)(b);
Console.WriteLine(compareAWithB(true));
Console.WriteLine(compareAWithB(false));
}
Now, the boolean argument is probably not the argument you'd most likely want to leave open with a partial application. This is one reason why the order of arguments in F# functions can seem a little odd at first. Let's define a different C# curry function:
Func<T3, Func<T2, Func<T1, T4>>> BackwardsCurry<T1, T2, T3, T4>(Func<T1, T2, T3, T4> f)
{
return a => b => c => f(c, b, a);
}
Now, we can do something a little more useful:
void UseADifferentlyCurriedFunction()
{
var curryCompare = BackwardsCurry<string, string, bool, int>(String.Compare);
var caseSensitiveCompare = curryCompare(false);
var caseInsensitiveCompare = curryCompare(true);
var format = Curry<string, string, string, string>(String.Format)("Results of comparing {0} with {1}:");
var strings = new[] {"Hello", "HELLO", "Greetings", "GREETINGS"};
foreach (var s in strings)
{
var caseSensitiveCompareWithS = caseSensitiveCompare(s);
var caseInsensitiveCompareWithS = caseInsensitiveCompare(s);
var formatWithS = format(s);
foreach (var t in strings)
{
Console.WriteLine(formatWithS(t));
Console.WriteLine(caseSensitiveCompareWithS(t));
Console.WriteLine(caseInsensitiveCompareWithS(t));
}
}
}
Why are these examples in C#? Because in F#, function declarations are curried by default. You don't usually need to curry functions; they're already curried. The major exception to this is framework methods and other overloaded functions, which take a tuple containing their multiple arguments. You therefore might want to curry such functions, and, in fact, I came upon this question when I was looking for a library function that would do this. I suppose it is missing (if indeed it is) because it's pretty trivial to implement:
let curry f a b c = f(a, b, c)
//overload resolution failure: there are two overloads with three arguments.
//let curryCompare = curry String.Compare
//This one might be more useful; it works because there's only one 3-argument overload
let backCurry f a b c = f(c, b, a)
let intParse = backCurry Int32.Parse
let intParseCurrentCultureAnyStyle = intParse CultureInfo.CurrentCulture NumberStyles.Any
let myInt = intParseCurrentCultureAnyStyle "23"
let myOtherInt = intParseCurrentCultureAnyStyle "42"
To get around the failure with String.Compare, since as far as I can tell there's no way to specify which 3-argument overload to pick, you can use a non-general solution:
let curryCompare s1 s2 (b:bool) = String.Compare(s1, s2, b)
let backwardsCurryCompare (b:bool) s1 s2 = String.Compare(s1, s2, b)
I won't go into detail about the uses of partial function application in F# because the other answers have covered that already.
It's a fairly simple process. Take a function, bind one of its arguments and return a new function. For example:
let concatStrings left right = left + right
let makeCommandPrompt= appendString "c:\> "
Now by currying the simple concatStrings function, you can easily add a DOS style command prompt to the front of any string! Really useful!
Okay, not really. A more useful case I find is when I want to have a make a function that returns me data in a stream like manner.
let readDWORD array i = array[i] | array[i + 1] << 8 | array[i + 2] << 16 |
array[i + 3] << 24 //I've actually used this function in Python.
The convenient part about it is that rather than creating an entire class for this sort of thing, calling the constructor, calling obj.readDWORD(), you just have a function that can't be mutated out from under you.
You know you can map a function over a list? For example, mapping a function to add one to each element of a list:
> List.map ((+) 1) [1; 2; 3];;
val it : int list = [2; 3; 4]
This is actually already using currying because the (+) operator was used to create a function to add one to its argument but you can squeeze a little more out of this example by altering it to map the same function of a list of lists:
> List.map (List.map ((+) 1)) [[1; 2]; [3]];;
val it : int list = [[2; 3]; [4]]
Without currying you could not partially apply these functions and would have to write something like this instead:
> List.map((fun xs -> List.map((fun n -> n + 1), xs)), [[1; 2]; [3]]);;
val it : int list = [[2; 3]; [4]]
I gave a good example of simulating currying in C# on my blog. The gist is that you can create a function that is closed over a parameter (in my example create a function for calculating the sales tax closed over the value of a given municipality)out of an existing multi-parameter function.
What is appealing here is instead of having to make a separate function specifically for calculating sales tax in Cook County, you can create (and reuse) the function dynamically at runtime.

Resources