Namin, it just occurred to me to mention that if your goal is to extract the "value"s from a sequence of "Some value"s, the Seq class has a function "choose" that helps do that. See library documentation at:
[link:research.microsoft.com]

You could do this:
Seq.choose (fun x -> x) (Array.to_seq x)
or
(Array.to_seq x) |> Seq.choose (fun x -> x)

(fun x -> x) is the identity function -- it returns whatever is passed to it. "choose" is designed to apply a function to each element of a sequence, so we provide this function to return each element unchanged. Then "choose" strips off the Some and appends to result, tossing any Nones it encounters. That is the same behavior as the loops we have been writing.

By on 3/18/2008 12:01 AM ()

Thanks. I am more interested in this example to understand the syntax of the match within sequence expressions. According to the manual, it should have a special auto-complete behavior, but I don't see it happening (maybe, this is another instance where the manual is out-of-date)?

For my purposes, in practice, I use the following idiom:
let nodes = seq { for i in [0..(Array2.length1 table)-1] do
for j in [i..(Array2.length2 table)-1] do
let Some p = table.[i,j]
yield p }
In this case, I am collecting all non-None entries of a 2-dimensional array into the variable nodes.
The key is to use the let construct which, in a sequence expression, silently discards patterns that don't match (this is what I thought match would do: i.e. silently discard!).

Anyways, I guess it would be nice if someone in the know could clarify whether match can have a special auto-complete behavior within sequence expressions or not.

By on 3/18/2008 12:11 AM ()

I use the following idiom:
let nodes = seq { for i in [0..(Array2.length1 table)-1] do
for j in [i..(Array2.length2 table)-1] do
let Some p = table.[i,j]
yield p }
In this case, I am collecting all non-None entries of a 2-dimensional array into the variable nodes.
The key is to use the let construct which, in a sequence expression, silently discards patterns that don't match

That is an interesting idiom!

How did you learn it? I would have thought the attempt to bind to Some p would give a runtime error if None was encountered, because it would be an impossible bind to perform. So instead it simply skips the remainder of the let .. in .. construct? (in this case, the yield).

If I try to use "let Some .." outside of a seq, it does what I expect: runtime error when fails to match. How strange that inside a seq it behaves differently!

By on 3/19/2008 6:35 PM ()

Per Julien's post to include all cases when using match, here is the most compact I've gotten. It works. It does give a compiler warning about "->> []" however.

{ for i in [0..3] do match x.[ i ] with | Some j -> yield j | _ -> ->> [] }

EDIT:
Found the yield equivalent of "->>". It is "yield!". So got rid of the compiler warning. It evaluates the expression that follows it, which can return multiple values. Including returning NO values in this case!

{ for i in [0..3] do match x.[ i ] with | Some j -> yield j | _ -> yield! [] }

NOTE: I found "yield!" via a Google search "F# yield", on this page:
[link:tomasp.net]

By on 3/17/2008 11:08 PM ()

To begin with, I think leave out the "do". That makes an imperative

loop, not a comprehension. Can anyone confirm this? I'm just learning

this comprehension stuff.

I was unable to find the correct syntax. I thought it should look like this:

let x = [| None; Some 1; Some 2; None |]

{ for i in [0..3] match x.[ i ] | Some j -> j }

But that yields a syntax error. While we await an expert answer, here is a do loop equivalent. This DOES work:

{for i in [0..3] do
match x.[ i ] with
| Some j -> ->> IEnumerable.singleton(j)
| _ -> ->> (IEnumerable.empty()) }

Output:
> val it : seq<int> = seq [1; 2]

~TMSteve

By on 3/17/2008 12:37 AM ()
1
2
3
4
5
6
 

{ for i in [0..3] when x.[ i ] <> None -> Option.get x.[ i ] } ;;

{ for i in [0..3] do if x.[ i ] <> None then yield Option.get x.[ i ] } ;;

If you use the match clause, then you have to provide a value for all cases (match x with | A -> ... | B -> ... | _ -> ...

Hope this helps

By on 3/17/2008 12:52 AM ()

Interesting idioms. Thanks.

The reason I am confused about the match in comprehensions is because the manual says:
Match/aggregation comprehensions. match expr with rule. Translated to an expression equivalent to match expr with rule' | _ -> IEnumerable.empty());. rule' is the translation of rule with any targets -> e_i replaced by targets ->> IEnumreable.singleton(e_i).

From this, I thought that it would complete the match with a catch-all rule for me. What's the syntax to get this auto-complete behavior?

Thanks, again.

By on 3/17/2008 1:01 AM ()

What's the syntax to get this auto-complete behavior?

I am wondering that also. It would be much more readable than what I wrote -- I had to add a level of complexity to represent "yield no value" [IEnumerable.empty()], because I couldn't figure out a syntax that matches the manual description.

NOTE: The syntax I used is useful if you want to be able to yield different number of values each iteration; hence the use of "->>", "IEnumerable.empty" -- no values, and "IEnumerable.singleton" -- one value.
But its overkill here!

By on 3/17/2008 10:39 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper