4 people like it.
Like the snippet!
Recursive active pattern for expanding list quotations
This is a recursive active pattern for extracting the elements of a list quotation as a list of Exprs, There doesn't seem to be a List pattern in the standard library. The compiler will complain about this recursive pattern unless you use #nowarn "40".
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
|
open FSharp.Quotations
open FSharp.Quotations.Patters
let rec (|List|_|) =
let isListType (u:UnionCaseInfo) = u.DeclaringType.IsGenericType && u.DeclaringType.GetGenericTypeDefinition() = typedefof<list<_>>
function
| NewUnionCase(uci, []) when isListType uci -> Some []
| NewUnionCase(uci, lhs::(NewUnionCase(_, []))::[]) when isListType uci -> Some (lhs::[])
| NewUnionCase(uci, lhs::List(rhs)::[]) when isListType uci -> Some (lhs::rhs)
| _ -> None
// Usage
match <@[5.;6.;7.;8.]@> with
| List e -> printf "%A" e
| _ -> ()
match <@[[5.;6.;7.];[8.]]@> with
| List e -> e |> List.map (function |List ee-> printf "%A" ee | _ ->())
| _ -> []
|
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Quotations
Multiple items
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IReadOnlyList<'T>
interface IReadOnlyCollection<'T>
interface IEnumerable
interface IEnumerable<'T>
member GetReverseIndex : rank:int * offset:int -> int
member GetSlice : startIndex:int option * endIndex:int option -> 'T list
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
...
val isListType : ('b -> bool)
val u : 'b
val typedefof<'T> : System.Type
type 'T list = List<'T>
val uci : obj
union case Option.Some: Value: 'T -> Option<'T>
val lhs : 'a
Multiple items
active recognizer List: 'a -> 'a list option
--------------------
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IReadOnlyList<'T>
interface IReadOnlyCollection<'T>
interface IEnumerable
interface IEnumerable<'T>
member GetReverseIndex : rank:int * offset:int -> int
member GetSlice : startIndex:int option * endIndex:int option -> 'T list
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
...
val rhs : 'a list
union case Option.None: Option<'T>
val e : Expr<float list> list
val printf : format:Printf.TextWriterFormat<'T> -> 'T
val e : Expr<float list list> list
val map : mapping:('T -> 'U) -> list:'T list -> 'U list
val ee : Expr<float list list> list
More information