Still in the process of turning my code more and more functional in style as well as in look.
Here I have a function which I try to keep as generic as I can, passing a filter function and a calculation function as parameters.
let calcError filter (fcalc:'a -> float) (arr:'a array) =
arr |> Array.filter filter
|> Array.map fcalc
|> Array.average
The signature is:
val calcError : filter:('a -> bool) -> fcalc:('a -> float) -> arr:'a array -> float
I believe this is quite standard, using calcError with partial applications.
However Array.average will raise exceptions is array is of size 0 or if null (which will not happen in my case).
Not a big fan of Exceptions in F#, I would prefer using either a (float output) or a Result.
I would then think of writing the code this way but I am not sure it is a proper way to do within a functional mindset (that I am trying to acquire). Any other solution, which I could probably be able to adapt for other similar issues, is of course welcome.
Thanks all
Solution I have in mind:
let calcError2 filter (fcalc:'a -> float) (arr:'a array) =
let subarr = arr |> Array.filter filter
match subarr.Length with
| 0 -> Result.Error "array length 0"
| _ -> subarr |> Array.map fcalc
|> Array.average
|> Result.Ok
Here is another version with a helper function.
let calcError filter (fcalc:'a -> float) (arr:'a array) =
let safeAverage ar = if Array.isEmpty ar then None else Some(Array.average ar)
arr |> Array.filter filter
|> Array.map fcalc
|> safeAverage
Moreover you can transform array to option to use it with any other unsafe array function.
let nat arr = if Array.isEmpty arr then None else Some(arr)
let calcError filter (fcalc:'a -> float) (arr:'a array) =
arr |> Array.filter filter
|> Array.map fcalc
|> nat
|> Option.bind (Some << Array.average )
Here is a more compact and efficient version using point free style
let calcError filter (fcalc:'a -> float) =
Option.bind (Some << (Array.averageBy fcalc)) << nat << Array.filter filter
It took me a while to truly appreciate the value of creating lots of small functions. Hope it helps.
This is one way to do it:
let tryCalcError filter (fcalc:'a -> float) (arr:'a array) =
arr |> Array.filter filter
|> Array.map fcalc
|> function
| [||] -> None
| arr -> Array.average arr |> Some
It follows the convention of prefixing with try to indicate that the return value is an option. You can see that convention in several Seq.try... functions like tryFind, tryHead, tryLast, tryItem, tryPick.
Your code looks good to me. The only thing I'd do differently is that I wouldn't use match to test whether the array is empty - you are not binding any variables and you have just two cases, so you really can just use the if expression here.
Two other minor tweaks are that I'm using Array.isEmpty to see if the array is empty (this probably has no effect here, but if you were using sequences, it would be faster than checking the length) and I also use averageBy rather than map followed by average:
let calcError2 filter (fcalc:'a -> float) (arr:'a array) =
let subarr = arr |> Array.filter filter
if Array.isEmpty subarr then Result.Error "array length 0"
else subarr |> Array.averageBy fcalc |> Result.Ok
Related
I am trying to iterate through a stream in order to print the content.
type 'a stream = Nil | Cons of 'a * 'a stream thunk and 'a thunk = unit -> 'a
This is where my function is called
|> iter_stream ~f:(fun (f,c,l) -> printf "%s %s %s\n" f c l)
And this is the type
let rec iter_stream st ~f
(* val iter_stream : 'a stream -> ('a -> unit) -> unit *)
I can't seem to find any examples on how to implement it. The only idea I have is to think about it like a list which is obviously wrong since I get type errors.
let rec iter_stream st ~f =
match st with
| None -> ()
| Some(x, st') -> f x; iter_stream st' ~f
Your stream is extremely similar to a list, except that you need to call a function to get the tail of the list.
Your proposed code has many flaws. The main two flaws that I see are:
You're using the constructors None and Some while a stream has constructors Nil and Cons.
You're not calling a function to get the tail of the stream. Note that in Cons (a, b), b is a "stream thunk", i.e., it's a function that you can call to get a stream.
(Perhaps these are the only two flaws :-)
I hope this helps.
I have a function f: 'a -> Async<'b option> that I want to call with 'a option instead of 'a. Now, if I had a function g that returned Async<'b> instead of f's Async<'b option>, I could write a standard traverse implementation and I would then have Async<'b option> at the end. But if I use traverse with f, the result is Async<'b option option>.
It seems to me I need something like this:
module Option =
let traverseBindAsync (f: 'a -> Async<'b option>) (opt: 'a option) : Async<'b option> =
async {
match opt with
| None -> return None
| Some x -> return! f x
}
I don't think traverseBind is a recognized concept (no search results). Is it known under another name, or alternatively, is there another way to think about this in terms of recognized FP concepts one can express in F#? If so, could I use those concepts in a way that is more or less as syntactically concise as the above Option.traverseBindAsync?
I'm not aware of any standard name for a function of a type like this. However, there are two changes you can do to the code that might be somewhat revealing. First, you can implement it without the use of the async block, just by using either f x or by returning async.Unit(None), i.e. an asynchronous computation that immediately returns None:
let traverseBindAsync (f: 'a -> Async<'b option>) (opt: 'a option) : Async<'b option> =
match opt with
| None -> async.Return None
| Some x -> f x
Now you can also rewrite this as doing Option.map on the input and using async.Return(None) as the default value when the input option (and therefore also the result of the map operation) is None:
let traverseBindAsync (f: 'a -> Async<'b option>) (opt: 'a option) : Async<'b option> =
opt |> Option.map f |> Option.defaultValue (async.Return None)
I don't think this has any name, but you can think of your function as Option.map with a particular default value when the input is not available.
I'm playing around asynchronous programming and was wondering if there's a function that exists that can take a value of type 'T and transform it to an Async<'T>, similar to C#'s Task.FromResult that can take a value of type TResult and transform it to a Task<TResult> that can then be awaited.
If such a function does not exist in F#, is it possible to create it? I can kind of emulate this by using Async.AwaitTask and Task.FromResult, but can I do this by only using Async?
Essentially, I'd like to be able to do something like this:
let asyncValue = toAsync 3 // toAsync: 'T -> Async<'T>
let foo = async{
let! value = asyncValue
}
...or just async.Return
let toAsync = async.Return
let toAsync` x = async.Return x
moreover there is async.Bind (in tupled form)
let asyncBind
(asyncValue: Async<'a>)
(asyncFun: 'a -> Async<'b>) : Async<'b> =
async.Bind(asyncValue, asyncFun)
you could use them to make pretty complicated async computation without builder gist link
let inline (>>-) x f = async.Bind(x, f >> async.Return)
let requestMasterAsync limit urls =
let results = Array.zeroCreate (List.length urls)
let chunks =
urls
|> Seq.chunkBySize limit
|> Seq.indexed
async.For (chunks, fun (i, chunk) ->
chunk
|> Seq.map asyncMockup
|> Async.Parallel
>>- Seq.iteri (fun j r -> results.[i*limit+j]<-r))
>>- fun _ -> results
You can use return within your async expression:
let toAsync x = async { return x }
I'm a beginner in F# and I'm trying to write a function to subset a dictionary given list, and return the result.
I tried this, but it doesn't work.
let Subset (dict:Dictionary<'T,'U>) (sub_list:list<'T>) =
let z = dict.Clear
sub_list |> List.filter (fun k -> dict.ContainsKey k)
|> List.map (fun k -> (k, dict.TryGetValue k) )
|> List.iter (fun s -> z.Add s)
|> List.iter (fun s -> z.Add s);;
--------------------------------------^^^
stdin(597,39): error FS0039: The field, constructor or member 'Add' is not defined
Perhaps there is a native function in F# to do that ?
thanks
EDIT
thanks to #TheInnerLight for his answer below
can you just educate me a bit more, and tell me how i should adapt that function if i want to return the original variable being modified ?
(of course it would be possible to go from where we call that function, call it with a temp variable, and reassign)
You have written:
let z = dict.Clear
z is of type unit->unit yet you are calling z.Add.
I suspect you want to write
let subset (dict:Dictionary<'T,'U>) (sub_list:list<'T>) =
let z = Dictionary<'T,'U>() // create new empty dictionary
sub_list |> List.filter (fun k -> dict.ContainsKey k)
|> List.map (fun k -> (k, dict.[k]) )
|> List.iter (fun s -> z.Add s)
z
TryGetValue is going to return something of type bool*'U in F#, which I suspect you don't want if already filtering by ContainsKey so you probably want to look up directly with dict.[k].
Note that Dictionary is a mutable collection so if you were to actually call dict.Clear(), it wouldn't return a new empty dictionary, it would mutate the existing one by clearing all elements. The immutable F# data structure usually used for key-value relationships is Map, see https://msdn.microsoft.com/en-us/library/ee353880.aspx for things you can do with Map.
Here is a map version (this is the solution I recommend):
let subset map subList =
subList
|> List.choose (fun k -> Option.map (fun v -> k,v) (Map.tryFind k map))
|> Map.ofList
Edit (in response to the question edit about modifying the input variable):
It's possible to update an existing dictionary using the destructive update operator <- on a mutable variable.
Option 1:
let mutable dict = Dictionary<Key,Value>() // replace this with initial dictionary
let lst = [] // list to check against
dict <- sublist dict lst
Likewise, my first function could be changed to perform only a side effect (removing unwanted elements).
Option 2:
let subset (d : System.Collections.Generic.Dictionary<'T,'U>) (sub_list : list<'T>) =
sub_list
|> List.filter (d.ContainsKey >> not)
|> List.iter (d.Remove >> ignore)
For an F# beginner I don't really recommend Option 1 and I really don't recommend Option 2.
The functional approach is to favour immutable values, pure functions, etc. This means you will be better off thinking of your functions as defining data transformations rather than as defining a list of instructions to be performed.
Because F# is a multi-paradigm language, it's easy to fall back on the imperative in the early stages but you will probably gain the most from learning your new language if you force yourself to adopt the standard paradigm and idioms of that language even if those idioms feel strange and uncomfortable to begin with.
The immutable data structures like Map and list are pretty efficient at sharing data as well as providing good time complexity so these are really the go-to collections when working in F#.
I have a recursive function that contains a series of matches that either make the recursive call back to the function, or make a call to failwith.
This is basically a hybrid implementation of the recursive descent parser descibed in Don Syme's Expert F# book (page 180) and the parsing example shown here: http://fsharpforfunandprofit.com/posts/pattern-matching-command-line/
Here is a snippet of my own code.
let rec parseTokenListRec tokenList optionsSoFar =
match tokenList with
| [] -> optionsSoFar
| SOURCE::t ->
match t with
| VALUE x::tt -> parseTokenListRec (returnNonValueTail t) {optionsSoFar with Source = (returnConcatHeadValues t)}
| _ -> failwith "Expected a value after the source argument."
| REGISTRY::t ->
...
A full code listing can be found at http://fssnip.net/nU
The way the code is currently written, when the function has finished working its way through the tokenList, it will return the optionsSoFar record that has been compiled via the object expression {optionsSoFar with Source = (returnConcatHeadValues t)}, or it will throw an exception if an invalid argument is found.
I want to refactor this so that the function does not rely on an exception, but will always return a value of some sort that can be handled by the calling function. The idea I have is to return a discriminated union rather than a record.
This discriminated union would be something like
type Result =
|Success of Options
|Failure of string
The problem I had when I tried to refactor the code was that I couldn't figure out how to get the success value of the DU to initialize via an object expression. Is this possible?
The examples I've looked at on MSDN (http://msdn.microsoft.com/en-us/library/vstudio/dd233237(v=vs.100).aspx), fsharpforfunandprofit (http://fsharpforfunandprofit.com/posts/discriminated-unions/) and elsewhere haven't quite cleared this up for me.
I'm worried that I'm not making any sense here. I'm happy to clarify if needed.
If I understand it correctly, in you current solution, the type of optionsSoFar is Options. The code becomes trickier if you change the type of optionsSoFar to your newly defined Result.
However, I think you do not need to do that - you can keep optionsSoFar : Options and change the function to return Result. This works because you never need to call the function recursively after it fails:
let rec parseTokenListRec tokenList optionsSoFar =
match tokenList with
| [] -> Success optionsSoFar
| SOURCE::t ->
match t with
| VALUE x::tt ->
{optionsSoFar with Source = (returnConcatHeadValues t)}
|> parseTokenListRec (returnNonValueTail t)
| _ -> Failure "Expected a value after the source argument."
| REGISTRY::t -> ...
If you actually wanted to update Source in a Result value, then I'd probably write something like:
module Result =
let map f = function
| Success opt -> f opt
| Failure msg -> Failure msg
Then you could write a transformation as follows:
resultSoFar
|> Result.map (fun opts -> {opts with Source = returnConcatHeadValues t})
|> parseTokenListRec (returnNonValueTail t)