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:
20:
|
open FSharp.Reflection
open FSharp.Quotations
open FSharp.Quotations.Patterns
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.Reflection
namespace Microsoft.FSharp.Quotations
module Patterns
from 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 : (UnionCaseInfo -> bool)
val u : UnionCaseInfo
type UnionCaseInfo =
member GetCustomAttributes : unit -> obj []
member GetCustomAttributes : attributeType:Type -> obj []
member GetCustomAttributesData : unit -> IList<CustomAttributeData>
member GetFields : unit -> PropertyInfo []
member DeclaringType : Type
member Name : string
member Tag : int
property UnionCaseInfo.DeclaringType: System.Type with get
property System.Type.IsGenericType: bool with get
System.Type.GetGenericTypeDefinition() : System.Type
val typedefof<'T> : System.Type
type 'T list = List<'T>
active recognizer NewUnionCase: Expr -> (UnionCaseInfo * Expr list) option
val uci : UnionCaseInfo
union case Option.Some: Value: 'T -> Option<'T>
val lhs : Expr
Multiple items
active recognizer List: Expr -> Expr 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 : Expr list
union case Option.None: Option<'T>
val e : Expr list
val printf : format:Printf.TextWriterFormat<'T> -> 'T
val map : mapping:('T -> 'U) -> list:'T list -> 'U list
val ee : Expr list
More information