4 people like it.

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
Next Version Raw view Test code New version

More information

Link:http://fssnip.net/82f
Posted:3 years ago
Author:allisterb
Tags: #active patterns , list , quotations