F# yield! (yieldbang) operator - f#

I am learning F# at the moment but I'm having a hard time understanding this:
let allPrimes =
let rec allPrimes' n =
seq {
if isPrime n then
yield n
yield! allPrimes' (n + 1) }
allPrimes' 2
I am not able to figure out what the yield! operator exactly does even though I've read other simpler examples and it seems yield! returns an inner sequence.

The yield bang operator merges the sub sequence produced by the called sequence expressions into the final sequence. Or in simpler words: it "flattens" the returned sequence to include the elements of the sub sequence in the final sequence.
For your example: Without the yield bang operator you would get something like
{ prime1 { prime2 { prime3 .... }}}
with the yield bang operator you get
{ prime1 prime2 prime3 ... }
where each { denotes a new sequence. Side node: The actual result from my first example would even include more sequences, as it would return sequences only containing sequences as the prime is only returned if n is prime.

Related

MIX seqbuilder [CustomOperation] attribute method AND vanilla yield IN a single seq expression

This code runs fine except if I uncomment the last line in my custom seq expression :
type T (i: int) =
member x.i = i
override x.ToString() =
sprintf "T is %A " x.i
type TBuilder() =
member x.Yield (()) = Seq.empty
[<CustomOperation("test")>]
member x.Test1 (source : seq<_>, i: int) : seq<T> =
printfn "Calling Test1 with i= %d" i |> ignore
seq { yield! source
yield T(i) }
let t = TBuilder()
let mytest =
t {
test 42
test 43
// yield T(44) // if uncommented, it does not compile
}
If yield T(44) line is uncommented, I get an compiler error like so :
Error This control construct may only be used if the computation expression builder defines a 'For' method.
My question : Is there a way to mix
my [CustomOperation] test (from method Test1) that yields T objects
with
a vanilla yield, for example yield T(44) or any other seq related syntax
inside a unique seq expression BUT without defining any 'For' method ?
Reference : DSL in Action for F# (Chapter 7) by Anh-Dung Phan on github.
Thanks.
Short answer: no. If you change your operators so that they preserve variable bindings (via MaintainsVariableSpace=true or MaintainsVariableSpaceUsingBind=true arguments to the [<CustomOperator>] attribute constructor) then you won't need For but you'll need Bind instead.
What do you expect the computation expression you've written to mean? If you look at how the F# spec specifies the translation for computation expressions, anything of the form
bldr {
op1 x
op2 y
yield z
}
will turn into something like
bldr.For(bldr.Op2(bldr.Op1(bldr.Yield(), x), y), fun () -> b.Yield(z))
so you clearly need a For method and also your Yield method needs to do something different; at the very least it needs to be able to take arguments of arbitrary types (e.g. in the above example it needs to work on an argument of type unit and also on an argument of whatever type the value z has).

Tail recursive mergesort algorithm

I've implemented a recursive mergesort algorithm:
-module(ms).
-import(lists,[sublist/3,delete/2,min/1,reverse/1]).
-export([mergesort/1]).
mergesort([])->
[];
mergesort([N])->
N;
mergesort(L)->
mergesort(split(1,L),split(2,L),[]).
mergesort(L1,L2,[])->
case {sorted(L1),sorted(L2)} of
{true,true}->
merge(L1,L2,[]);
{true,false}->
merge(L1,mergesort(split(1,L2),split(2,L2),[]),[]);
{false,true}->
merge(mergesort(split(1,L1),split(2,L1),[]),L2,[]);
{false,false}->
merge(mergesort(split(1,L1),split(2,L1),[]),mergesort(split(1,L2),split(2,L2),[]),[])
end.
merge([],[],R)->
reverse(R);
merge(L,[],R)->
merge(delete(min(L),L),[],[min(L)|R]);
merge([],L,R)->
merge([],delete(min(L),L),[min(L)|R]);
merge([H1|T1],[H2|T2],R) when H1 < H2 ->
merge(T1,[H2|T2],[H1|R]);
merge([H1|T1],[H2|T2],R) when H1 >= H2 ->
merge([H1|T1],T2,[H2|R]).
split(1,L)->
sublist(L,1,ceiling(length(L)/2));
split(2,L)->
sublist(L,ceiling(length(L)/2+1),length(L)).
ceiling(X) when X < 0 ->
trunc(X);
ceiling(X) ->
T = trunc(X),
case X - T == 0 of
true -> T;
false -> T + 1
end.
However I'm irked by the fact that mergesort/3 is not tail recursive (TR), and is verbose.
I guess the problem here is that I'm not particularly aware of the TR 'template' that I would use here - I understand how I would implement a TR function that can be defined in terms of a series, for example - that would just move the arguments to the function up the series, however for the case in which we merge a sublist conditionally to the natural recursion of the rest of the list, I'm ignorant.
Therefore, I would like to ask:
1) How can I make mergesort/3 TR?
2) What resources can I use to understand erlang tail recursion in-depth?
Your merge-sort is not tail recursive because the last function called in mergesort/3 is merge/3. You call mergesort as arguments of merge so stack has to grow - upper called mergesort/3 is not yet finished and its stack frame can't be reused.
To write it in TR approach you need think of it as much imperatively as you can. Every TR function is easily rewritable to iterational while loop. Consider:
loop(Arg) ->
NewArg = something_happens_to(Arg),
loop(NewArg) or return NewArg.
And:
data = something;
while(1){
...
break loop or modify data block
...
} // data equals to NewArg at the end of iteration
Here is my TR merge-sort example. It's bottom-up way of thinking. I used merge/3 function from your module.
ms(L) ->
ms_iteration([[N] || N <- L], []).
ms_iteration([], []) -> % nothing to do
[];
ms_iteration([], [OneSortedList]) -> % nothing left to do
OneSortedList;
ms_iteration([], MergedLists) ->
ms_iteration(MergedLists, []); % next merging iteration
ms_iteration([L], MergedLists) -> % can't be merged yet but it's sorted
ms_iteration([], [L | MergedLists]);
ms_iteration([L1, L2 | ToMergeTail], MergedLists) -> % merging two sorted lists
ms_iteration(ToMergeTail, [merge(L1, L2, []) | MergedLists]).
It's nicely explained here: http://learnyousomeerlang.com/recursion .

Enumerator and disposing in F#

I am trying to draw lessons on the following behaviour from an example I simplified :
let groupedEnum (input: 'a seq) =
using (input.GetEnumerator()) (fun en ->
Seq.unfold(fun _ ->
if en.MoveNext() then
Some(en.Current, ())
else None) ()
)
//WORKS
let c = groupedEnum ("11111122334569999" |> List.ofSeq ) |> List.ofSeq
//BOOM !! System.NullReferenceException
let c = groupedEnum ("11111122334569999" ) |> List.ofSeq
Is the enumerator "en" disposed of independently of it being captured ? (I guess it is but is there anything to say / materials to read on this behaviour beside this msdn doc on ressources)
Why is it working if the sequence is transformed to a list first ?
Edit : this is just a toy example to illustrate a behaviour, not to be followed.
There are very few good reasons to manipulate enumerators directly.
The using function disposes the enumerator as soon as the lambda function returns. However, the lambda function creates a lazy sequence using Seq.unfold and the lazy sequence accesses the enumerator after the sequence is returned from groupedEnum.
You could either fully evaluate the whole sequence inside using (by adding List.ofSeq there) or you need to call Dispose when the end of the generated sequence is reached:
let groupedEnum (input: 'a seq) =
let en = input.GetEnumerator()
Seq.unfold(fun _ ->
if en.MoveNext() then
Some(en.Current, ())
else
en.Dispose()
None)
Exception handling becomes quite difficult in this case, but I guess that one way to do it would be to wrap the body in try .. with and call Dispose if an exception happens (and then return None).
If you use sequence expressions instead, then the meaning of use changes and it automatically disposes the enumerator after the end of sequence is reached (not when the lazy sequence is returned). So using sequence expressions might be a better choice because the hard work is done for you:
let groupedEnum (input: 'a seq) = seq {
use en = input.GetEnumerator()
let rec loop () = seq {
if en.MoveNext() then
yield en.Current
yield! loop () }
yield! loop () }
EDIT And why does it work in your first example? The enumerator returned by F# list type simply ignores Dispose and continues working, while if you call Dispose on an enumerator returned by a string, the enumerator cannot be used again. (This is arguably a bit odd behaviour of the F# list type.)

Error FS0752 in F# declaration of a map over list of functions

I would like to execute a list of functions over a list of corresponding values:
let f1 x = x*2;;
let f2 x = x+70;;
let conslist = [f1;f2];;
let pmap2 list1 list2 =
seq { for i in 0..1 do yield async { return list1.[i] list2.[i] } }
|> Async.Parallel
|> Async.RunSynchronously;;
Result:
seq { for i in 0..1 do yield async { return list1.[i] list2.[i] } }
----------------------------------------------^^^^^^^^^
stdin(213,49): error FS0752: The
operator 'expr.[idx]' has been used an
object of indeterminate type based on
information prior to this program
point. Consider adding further type
constraints
I would like to execute: pmap2 conslist [5;8];; (in parallel)
If you want to use random access then you should use arrays. Random access to elements of list will work, but it is inefficient (it needs to iterate over the list from the start). A version using arrays would look like this:
// Needs to be declared as array
let conslist = [|f1; f2|];;
// Add type annotations to specify that arguments are arrays
let pmap2 (arr1:_[]) (arr2:_[]) =
seq { for i in 0 .. 1 do
yield async { return arr1.[i] arr2.[i] } }
|> Async.Parallel |> Async.RunSynchronously
However, you can also rewrite the example to work with any sequences (including arrays and lists) using the Seq.zip function. I think this solution is more elegant and it doesn't force you to use imperative arrays (and it doesn't have the performance disadvantage):
// Works with any sequence type (array, list, etc.)
let pmap2 functions arguments =
seq { for f, arg in Seq.zip functions arguments do
yield async { return f arg } }
|> Async.Parallel |> Async.RunSynchronously
As the error message suggests, you need to add type annotations to list1 and list2. Once you do that, it works fine (though I would recommend using arrays instead of list since you're random-accessing them).
let pmap2 (list1:_ list) (list2:_ list)

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