2

Attempting to find anagrams in a list of words using F Sharps Async Sequences (I am aware there are better algorithms for anagram finding but trying to understand Async Sequneces)

From the 'runTest' below how can I 1. async read the collecion returned and output to screen 2. block until all results return & display final count/collection

  open System
    open System.ServiceModel
    open System.Collections.Generic
    open Microsoft.FSharp.Linq
    open FSharp.Control

    [<Literal>]
    let testWord = "table"

    let testWords =  new List<string>()
    testWords.Add("bleat")
    testWords.Add("blate")
    testWords.Add("junk")


    let hasWord (word:string) =    
        let mutable res = true
        let a = testWord.ToCharArray()  |> Set.ofArray
        let b = word.ToCharArray()  |> Set.ofArray
        let difference = Set.intersect a b
        match difference.Count with
        | 0 ->  false
        | _ ->  true 

    let test2 (words:List<string>, (word:string)) : AsyncSeq<string>  =
        asyncSeq   {
                        let res =
                                (words)
                                |> Seq.filter(fun x-> (hasWord(x)) )
                                |>  AsyncSeq.ofSeq                                                  
                        yield! res
                }

    let runTest = test2(testWords,testWord) 
                                            |> //pull stuff from stream
                                            |> // output to screen   
                                            |> ignore              

    ()
3
  • Are you aware that more traditional indentation is only 4 spaces more than the previous line> Commented Nov 25, 2014 at 2:56
  • yeh - this is the result from moving stuff around - will clean up the end result - curious as to how to read data pulled from the sequence - PS is there an online F# formatter? Commented Nov 25, 2014 at 3:08
  • just reformatted the code :) Commented Nov 27, 2014 at 5:26

1 Answer 1

4

So as you have the test2 function returning an asyncSeq. Your questions:

1. async read the collecion returned and output to screen

If you want to have some side-effecting code (such as outputting to the screen) you can use AsyncSeq.iter to apply a function to each item as it becomes available. Iter returns an Async<unit> so you can then "kick it off" using an appropriate Async method (blocking/non-blocking).

For example:

let processItem i = 
    // Do whatever side effecting code you want to do with an item
    printfn "Item is '%s'" i

let runTestQ1 = 
    test2 (testWords, testWord) 
    |> AsyncSeq.iter processItem 
    |> Async.RunSynchronously

2. block until all results return & display final count/collection

If you want all the results collected so that you can work on them together, then you can convert the AsyncSeq into a normal Seq using AsyncSeq.toBlockingSeq and then convert it to a list to force the Seq to evaluate.

For example:

let runTestQ2 = 
    let allResults = 
        test2 (testWords, testWord) 
        |> AsyncSeq.toBlockingSeq 
        |> Seq.toList
    // Do whatever you would like with your list of results
    printfn "Final list is '%A' with a count of %i" allResults (allResults.Length)
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks - fixed gist is here using an observer gist.github.com/chrismckelt/d9d113edc3d3bf4afe91

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.