Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do pattern matching in Rx. Where and Select in a single operator?

Suppose I have this type:

type T = int option

and an observable of that type:

let o : IObservable<T> = // create the observable

I'm looking for a better way to express this:

o.Where(function | None -> false | Some t -> true)
 .Select(function | Some t -> t)

An observable that only propagates the Some case.

There are several things that I don't like.

  • I'm using 2 operators
  • I'm pattern matching twice
  • The second pattern matching isn't exhaustive (makes visual studio show a warning and feels odd)
  • Too much code. The pattern repeats every time I need pattern matching.
like image 941
Lay González Avatar asked May 27 '15 17:05

Lay González


People also ask

Which operator is used with select command for pattern matching?

LIKE operator is used for pattern matching, and it can be used as -. % – It matches zero or more characters.

Which operator is used in query for pattern matching in SQL?

The LIKE operator is used in a WHERE clause to search for a specified pattern in a column.

Is a pattern matching operator?

The pattern is a general description of the format of the string. It can consist of text or the special characters X, A, and N preceded by an integer used as a repeating factor. X stands for any characters, A stands for any alphabetic characters, and N stands for any numeric characters.

Where is pattern matching used?

You can use pattern matching to test the shape and values of the data instead of transforming it into a set of objects. The preceding example takes a string array, where each element is one field in the row.


2 Answers

Can't you use Observable.choose ? something like this :

let o1 : IObservable<int option> = // ...
let o2 = Observable.choose id o1

If you have a type that is not an option, say:

type TwoSubcases<'a,'b> = | Case1 of 'a | Case2 of 'b

and a partial active pattern:

let (|SecondCase|_|) = function
    | Case1 _ -> None
    | Case2 b -> Some b

then you can do:

let o1 : IObservable<TwoSubcases<int, float>> = // ...
let o2 : IObservable<float> = Observable.choose (|SecondCase|_|) o1 
like image 139
Sehnsucht Avatar answered Sep 18 '22 11:09

Sehnsucht


Thanks to @Lee I came up with a nice solution.

o.SelectMany(function | None -> Observable.Empty() | Some t -> Observable.Return t)

This works for any union type, not only Option.

like image 34
Lay González Avatar answered Sep 19 '22 11:09

Lay González