f# , Why embed async in async?


Why embed async in async?

Question:

Tag: f#

I read the following code from the book Expert f#,

  1. Why the function collectLinks embeds let! html = async { .... } in the outer async block? How about just flat it by removing the inner async?

  2. Same question for the function waitForUrl in urlCollector which has a do! Async.StartChild (async {....}) |> Async.Ignore in an outer async block. How about flat it?

  3. How is the implementation comparing with the one implemented with block queue? https://msdn.microsoft.com/en-us/library/vstudio/hh297096(v=vs.100).aspx Creating a block queue with 5, and en-queue the link to producer.

Code:

open System.Collections.Generic
open System.Net
open System.IO
open System.Threading
open System.Text.RegularExpressions

let limit = 50
let linkPat = "href=\s*\"[^\"h]*(http://[^&\"]*)\""
let getLinks (txt:string) =
    [ for m in Regex.Matches(txt,linkPat)  -> m.Groups.Item(1).Value ]

// A type that helps limit the number of active web requests
type RequestGate(n:int) =
    let semaphore = new Semaphore(initialCount=n, maximumCount=n)
    member x.AsyncAcquire(?timeout) =
        async { let! ok = Async.AwaitWaitHandle(semaphore,
                                                ?millisecondsTimeout=timeout)
                if ok then
                   return
                     { new System.IDisposable with
                         member x.Dispose() =
                             semaphore.Release() |> ignore }
                else
                   return! failwith "couldn't acquire a semaphore" }

// Gate the number of active web requests
let webRequestGate = RequestGate(5)

// Fetch the URL, and post the results to the urlCollector.
let collectLinks (url:string) =
    async { // An Async web request with a global gate
            let! html =
                async { // Acquire an entry in the webRequestGate. Release
                        // it when 'holder' goes out of scope
                        use! holder = webRequestGate.AsyncAcquire()

                        let req = WebRequest.Create(url,Timeout=5)

                        // Wait for the WebResponse
                        use! response = req.AsyncGetResponse()

                        // Get the response stream
                        use reader = new StreamReader(response.GetResponseStream())

                        // Read the response stream (note: a synchronous read)
                        return reader.ReadToEnd()  }

            // Compute the links, synchronously
            let links = getLinks html

            // Report, synchronously
            do printfn "finished reading %s, got %d links" url (List.length links)

            // We're done
            return links }

/// 'urlCollector' is a single agent that receives URLs as messages. It creates new
/// asynchronous tasks that post messages back to this object.
let urlCollector =
    MailboxProcessor.Start(fun self ->

        // This is the main state of the urlCollector
        let rec waitForUrl (visited : Set<string>) =

           async { // Check the limit
                   if visited.Count < limit then

                       // Wait for a URL...
                       let! url = self.Receive()
                       if not (visited.Contains(url)) then
                           // Start off a new task for the new url. Each collects
                           // links and posts them back to the urlCollector.
                           do! Async.StartChild
                                   (async { let! links = collectLinks url
                                            for link in links do
                                               self.Post link }) |> Async.Ignore

                       // Recurse into the waiting state
                       return! waitForUrl(visited.Add(url)) }

        // This is the initial state.
        waitForUrl(Set.empty))

Answer:

I can think of one reason why async code would call another async block, which is that it lets you dispose of resources earlier - when the nested block completes. To demonstrate this, here is a little helper that prints a message when Dispose is called:

let printOnDispose text = 
  { new System.IDisposable with
      member x.Dispose() = printfn "%s" text }

The following uses nested async to do something in a nested block and then cleanup the local resources used in the nested block. Then it sleeps some more and cleans up resources used in the outer block:

async { 
  use bye = printOnDispose "bye from outer block"
  let! r = async {
    use bye = printOnDispose "bye from nested block"
    do! Async.Sleep(1000)
    return 1 }
  do! Async.Sleep(1000) }
|> Async.Start

Here, the "nested block" resources are disposed of after 1 second and the outer block resources are disposed of after 2 seconds.

There are other cases where nesting async is useful (like returning from an asynchronous block containing try .. with), but I don't think that applies here.


Related:


F# task parallelism under mono doesn't “appear” to execute in parallel


asynchronous,f#,mono,task-parallel-library
I have the following dummy code to test out TPL in F#. (Mono 4.5, xmarin studio, quard core macbook pri) To my surprise, all the processes are done on the same thread. there is not parallelism at all. open System open System.Threading open System.Threading.Tasks let doWork (num:int) (taskId:int) : unit...

FParsec parses only first half


parsing,f#,dsl,fparsec
In my AST, I have something like this: type Program = Declaration list and Declaration = | TypedefDeclaration of TypedefDeclaration and TypedefDeclaration = | Typedef1 of Name * TypeName | Typedef2 of Name * Name For parsing both of the statements, I have used something like this: let tdefpartial =...

Post messages from async threads to main thread in F#


.net,powershell,f#,system.reactive,f#-async
There is a subscription to an observable that sends out log messages. Some of the log messages come from other threads because they are are in F# async blocks. I need to be able to write out the messages from the main thread. Here is the code that currently filters...

FsXaml load error


.net,wpf,f#
I am trying to use FSXaml to create a gui in F#. I get the following error while compiling. I get the same error on the sample demo program from FsXaml as well. Thank you in advance for all the help. The error I am getting is: FSC: error FS3031:...

Duck typing with type provider instances [duplicate]


f#,type-providers,duck-typing
This question already has an answer here: How do I write this member constraint in F#? 1 answer I am writing an F# script to operating on tables in a database. All of the tables have a Guid Id property. I want to make use of duck typing to...

Duplicate Key in index of Deedle Series


f#,deedle
I have a list of events that occur in a system. My goal is to take the list of events and create a sliding window of the series to determine rate event occurrences. The events are loaded into the events list from an application outside of this scope of the...

F# Custom operators


f#,operator-overloading
I've defined a custom operator in F# like this: static member (&?) value defaultValue = if value = null then defaultValue else value The operator is defined within a type and should be called in the following scenario: I'm retrieving information about the system processors using WMI. Now i want...

Tail Recursive Combinations


f#
I have this code: let rec combinations acc listC = match listC with | [] -> acc | h::t -> let next = [h]::List.map (fun t -> h::t) acc @ acc combinations next t It looks tail recursive, but I keep getting stack overflows with it. Any ideas on how...

How do I ignore escape characters in command line arguments?


command-line,f#
Consider a simple F# console application that echoes the command line arguments passed to it, one command per line: [<EntryPoint>] let main argv = argv |> Array.iter (printfn "%s") 0 If I pass this program a directory path with a trailing slash, it treats the slash as an escape character...

Can you list the contents of a namespace or module in F#


f#
Similar to this question about clojure, is it possible to list the contents of a namespace or module in F#? When I open a namespace for a loaded DLL I'm not receiving an error that the namespace doesn't exist, but then when I try to use the documented functions I'm...

How to recursively identify cells of specific type in grid?


recursion,f#,tail-recursion
I'm learning F# and I'm building a minesweeper app. As part of that, I'm trying to have a method that detonates all adjacent mines if a mine is detonated, recursively. So if I have a grid like: | 0 | 1 | 2 | ------------------------ 0 | E-1 | M...

How convert any record into a map/dictionary in F#?


dictionary,f#,converter,record
I need to serialize arbitrary records into maps/dictionary. I imagine my end type look like this: type TabularData= array<Map<string, obj>> But I have problems in build a generic function that accept any record and turn them into Map....

Why sequence expressions for arrays are so slow in F#?


.net,f#
The code: #time "on" let newVector = [| for v in 1..10000000 -> v |] let newVector2 = let a = Array.zeroCreate 10000000 for v in 1..10000000 do a.[v-1] <- v a let newVector3 = let a = System.Collections.Generic.List() // do not set capacity for v in 1..10000000 do a.Add(v)...

F# computation expression transparent state passing with Bind


f#,computation-expression
I have the following code that try to read a possibly incomplete data (image data, for example) from a network stream using usual MaybeBuilder: let image = maybe { let pos = 2 //Initial position skips 2 bytes of packet ID let! width, pos = readStreamAsInt 2 pos let! height,...

Properly implement F# Unit in C#


c#,f#,functional-programming
This question is not about C#/F# compatibility as in this one. I'd like to know the proper way to implement a type like F# Unit in place of using void. Obviously I'll discard this result and I'll not expose this type to the outside world. Wondering if an empty class...

When are let bindings in code quotations replaced with their values?


f#
If I run the first example from MSDN (https://msdn.microsoft.com/en-us/library/dd233212.aspx) in the F# Interactive window, I get the expected output: fun (x:System.Int32) -> x + 1 a + 1 let f = fun (x:System.Int32) -> x + 10 in f 10 But if I run it in the Main from my...

Is this definition of a tail recursive fibonacci function tail-recursive?


scala,f#,functional-programming,tail-recursion,continuation-passing
I've seen around the following F# definition of a continuation-passing-style fibonacci function, that I always assumed to be tail recursive: let fib k = let rec fib' k cont = match k with | 0 | 1 -> cont 1 | k -> fib' (k-1) (fun a -> fib' (k-2)...

Simplify a recursive function from 3 to 2 clauses


recursion,f#
I am doing some exercises on F#, i have this function that calculate the alternate sum: let rec altsum = function | [] -> 0 | [x] -> x | x0::x1::xs -> x0 - x1 + altsum xs;; val altsum : int list -> int The exercise consist in declare...

Redefine jQuery dependency search path


f#,resources,offline,websharper
I have found that a typical Websharper "hello world" application does not work offline due to the inaccessibility of jQuery resource "http://code.jquery.com/jquery-1.11.2.min.js". The question is: can I override this search path to the local folder of my web application?

Asynchronously manipulating data from streamReader in F#


asynchronous,f#,streamreader
On the line of Read large txt file multithreaded?, I have the doubt of whether it is equivalent to pass to each thread an sliced chunk of a Seq and whether it will safely handle the paralellism; is it StreamReader thread-safe? Here is the code I am using to test...

How can I resolve the “Could not fix timestamps in …” “…Error: The requested feature is not implemented.”


linux,build,f#
I have been trying to build a project in F# on Linux that I have located here on github. It's a basic kata project that I am working on as a demo. However on Linux (specifically Ubuntu 14.04 LTS Desktop) I haven't been able to get it to build yet...

F# Discriminated Union - “downcasting” to subtype


f#,discriminated-union
I don't really know what the proper title for this question should be, but: I have a discriminated union called MyDiscriminatedUnion in F#: type MyDiscriminatedUnion = | Foo of Foo | Bar of Bar where Foo and Bar are record types: type Foo = { ... } type Bar =...

Why is FSharp.Data.SqlClient record exposed as object?


f#,fsharp.data.sqlclient
I'm working on a demo where I can show how easy it is to use the SqlClient type provider in a F# library and then consume it from C#, I think this might be one way to get things into projects. Since many people using C# want to use interfaces...

How to handle Arithmetic operation OverflowException in F#?


python,f#
I'm doing Project Euler problem 1 in F#: Multiples of 3 and 5 If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples...

Split string into string list containing strings no greater than n chars


f#
I have a long string that I need to convert to a string list where each string in the list is <= 50 chars. In addition, I don't want words to be split - if the 50th char is a letter in a word, then I want the split to...

F# strange type error message


types,f#,typeerror,discriminated-union
Can anyone tell me what the following error message means in F#: Program.fs(1021,16): error FS0001: This expression was expected to have type FSI_0051.ExprTree but here has type FSI_0061.ExprTree It was the result of executing the following function: let evaluate_tree tree = let rec helper tree = match tree with |...

Why embed async in async?


f#
I read the following code from the book Expert f#, Why the function collectLinks embeds let! html = async { .... } in the outer async block? How about just flat it by removing the inner async? Same question for the function waitForUrl in urlCollector which has a do! Async.StartChild...

Referencing event from .xaml file in .fs file


wpf,xaml,f#,fsxaml
I want to declare an event in a XAML file and then add a handler in a fs file. The upper part of the XAML file would be something like (MouseRightButtonDown): <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="AboutStack" MouseRightButtonDown="AboutStack_MouseRightButtonDown" Title="About" SizeToContent="WidthAndHeight"> <StackPanel>... The F# file contains: open FsXaml type MainWindow = XAML<"MainWindow.xaml", true>...

Signing F# Assembly


.net,f#,strongname,assembly-signing
I'm having a lot of trouble trying to sign a F# class library project. First I've tried this thread, using the AssemblyKeyFileAttribute but had no success. I also tried to add the flag "--keyfile:keyfile.snk" to the project properties ("Other Flags" field in "Build" tab) and It did't worked too. I'm...

interpreting a script through F#


scripting,f#,interpreted-language
I really like F# but I feel like it's not succint and short enough. I want to go further. I do have an idea of how I'd like to improve it but I have no experience in making compilers so I thought I'd make it a scripting language. Then I...

What is the difference between member val and member this in F#?


.net,f#,immutability
When I created a class containing a generic, mutable .NET Stack in F# like the example below, that stack ignores anything I push onto it. open System.Collections.Generic type Interp(code: int array) = member val PC = 0 with get, set member this.stack: Stack<int> = new Stack<int>() member this.Code = code...

F# - Result is list of list of int instead of a list of int


f#
I have quite a complex problem that I have simplified for the purpose of this question. Let's just say the problem is as follow: I want a list of the first 3 numbers (1,2,3) added to all of these numbers: 0,10,20 So I want the following desired output: all =...

All the F# templates in VS 2015 RC disappear


templates,f#,visual-studio-2015
I installed in a fresh Win 8.1 machine VS 2015 RC. I load VS and create a F# project. Fine. Eventually, I do some other stuff (that I have not remember) and then I found that no single F# template (for projects) exist anymore in VS. Only C#/VB ones....

F# - Recursive function to copy a list


list,f#
I wrote this code to recursively copy my list: let sp = [2;4;6;8;10] let copy (s1:'a list) = let rec copy acc ind = if(ind>=0) then copy (s1.[ind]::acc) (ind-1) else acc copy [] (s1.Length-1) sp |> copy |> printfn "%A" How to make this code easier?...

Releasing SQLite resources in F#


sqlite,sqlite3,f#,system.data.sqlite,fsi
Consider the following F# script, which creates a simple SQLite database and table, and then should delete it. However, the SQLite obejct doesn't seem to be disposed of properly and isn't releasing its lock on the file. #r @"C:\Path\To\System.Data.SQLite.dll" open System.Data.SQLite let createTable() = use db = new SQLiteConnection(@"Data Source=test.sqlite")...

Does let!/do! always run the async object in a new thread?


f#
From the wikibook on F# there is a small section where it says: What does let! do?# let! runs an async<'a> object on its own thread, then it immediately releases the current thread back to the threadpool. When let! returns, execution of the workflow will continue on the new thread,...

shift/reduce and reduce/reduce errors in F# using fsyacc and fslex


parsing,f#,dsl,lexer,fsyacc
I'm creating my own external DSL, which I intend to be pretty small and include some basic functionality. When I compile my project, it builds successfully but it shows a lot of shift/reduce and reduce/reduce errors. And most of them are around my binary operators. Here is part of my...

How can I run xunit test in F#


f#,xunit.net
I have Xunit and Xunit(Runner: Visual Studio) installed and he is my simple test: namespace Testing module Tests = open Xunit open Xunit.Extensions [<Fact>] let ``just test`` = Assert.Equal(1, 1) () But I can find Xunit in Test -> Window -> Test explorer and Resharper Unit Tests Window....

Filtering a sequence of options and collecting the values of all the Somes. Is there a built-in function in F# for that?


.net,f#
A common pattern in F# is to want to filter something by whether it is "Some"thing and in case it is, getting its value: module Option = let values s = s |> Seq.filter Option.isSome |> Seq.map Option.get I have the idea I've seen something like that in the F#...

Doc.Checkbox 'change' event does not occur in Websharper.UI.Next


web,f#,websharper
I have reactive Var variable varDone and Doc.Checkbox for its representation named cbDoc. After changing the value of varDone I need to call my function. For this, I wrote the code illustrated in the following pseudo-code: open WebSharper open WebSharper.UI.Next open WebSharper.UI.Next.Html open WebSharper.UI.Next.Notation // declaring reactive bool variable let...

How to combine two seqs (not using Seq.append)


f#
type Message = | Str of string | KeyPress of ConsoleKeyInfo let keyStream = seq { while true do yield KeyPress(Console.ReadKey(true)) } let rec messageStream = keyStream |> Seq.combine (messageStream |> Seq.filter filterer) |> filterALot messageStream |> Seq.iter (fun _ -> ()) Here is my code. Basically I want to...

F# “The value of constructor … not defined”


visual-studio-2010,f#
So, this is my second F# console application. The code goes like this: let rec fact n = if n = 1 then 1.0 else float(n)*fact(n-1);; let rec pow x n = if n = 1 then x else float(x) * pow x (n-1);; let rec func1 eps x n...

how to call function from library in formula with R type provider


r,f#
I am following some R examples from a book on stochastic simulation, and being familiar with F# and not familiar with R -I decided to try out the R type provider. Today I come across a code snippet which I cannot figure out how to execute through the R type...

F# I want to filter my output


f#
I have a problem which I have simplified for the purpose of this question. Let's just say I have 2 lists. The first actually represents a list of classes but for this purpose, let's say it simply represents a list of ints (2,4,6,8,10). I have another list of ints that...

Return a modified version of same type in F#


f#
If I've got a class hierarchy like type Employee(name) = member val name: string = name type HourlyEmployee(name, rate) = inherit Employee(name) member val rate: int = rate type SalariedEmployee(name, salary) = inherit Employee(salary) member val salary: int = salary And I want a function that updates the name field...

F# - writing an (GA) evaluation function in F#


f#
Background: I am currently working on a genetic algorithm (GA) in F#. (I come from a strong C# background and have only been using F# for a day now) Problem: I have an error evaluation function to determine how valid a proposed solution is.Lets assume a simplified error algorithm: Calculate...

How to implement generics with type annotations in F#


generics,f#
I have the following skeleton of code: type MyException<'T> () = inherit Exception() type IMyInterface = abstract member Method<'T when 'T : (new: unit -> 'T) and 'T :> Exception> : string -> int type MyClass = interface IMyInterface with member this.Method s = let i = s.IndexOf "a" if...

How to rewrite this C# code


f#
I have this C# code: const int bufferLen = 4096; byte[] buffer = new byte[bufferLen]; int count = 0; while ((count = stream.Read(buffer, 0, bufferLen)) > 0) { outstream.Write(buffer, 0, count); } I need to rewrite it in F#. I can do it like this: let bufferLen : int =...

How to use F#'s headOrDefault on an empty array?


.net,linq,f#
I want to test the headOrDefault in F# on an empty array, which is supposed to work like FirstOrDefault in C#. So I typed in this code: let arr = [] let res = query { for e in arr do select e headOrDefault } Console.WriteLine("{0}", (res = null)) I...

Conditional Operator in F# (A?B:C) [duplicate]


c#,f#,conditional-operator
This question already has an answer here: Does F# have the ternary ?: operator? 3 answers In C#, we have the conditional operator: [condition] ? [value if true] : [value if false] But I can't seem to find this in F#. Does it exist?...