anchor.diff:                          Call (None, routeItemParsersT, makeLinkM, [Var shapeId])
                       ])
               )
  +        | MetaTuple items ->
  +            let shapes =
  +                items |> List.map (fun item ->
  +                    let shape = getRouteShape item |> convertRouteShape
  +                    let shapeId = Id.New()
  +                    Let(shapeId, shape,
  +                        NewArray [
  +                            Call (None, routeItemParsersT, parseShapeM, [Var shapeId])
  +                            Call (None, routeItemParsersT, makeLinkM, [Var shapeId])
  +                        ]))
  +            NewUnionCase (routeShapeT, "Tuple", [NewArray shapes])
   
       override __.TranslateCall(_, _, m, args, _) =
           match m.Generics.[0] with
  
positive.code:     | Base of ParseFunc // assuming string as LinkFunc
      | Object of ctor: (unit -> obj) * name: option<string> * args: RouteObjectArgs
      | Sequence of fromArray: (array<obj> -> obj) * parseItem: ParseFunc * linkItem: LinkFunc
  //    | Tuple of items: array<ParseFunc * LinkFunc>
  
  and private MetaRootShape =
      | MetaBase of parse: Method
      | MetaObject of ctor: Expression * name: option<string> * args: list<string * System.Type>
      | MetaSequence of fromArray: Expression * item: Type
  //    | MetaTuple of items: list<System.Type>
  
  and private RouteMapBuilderMacro(comp: Metadata.Compilation) =
      inherit Macro()
  
negative.code:                 | _ -> MetaBase parseMeth
          | ArrayType (t, 1) ->
              MetaSequence((let x = Id.New() in Lambda([x], Var x)), t)
          | TupleType ts ->
              MetaTuple ts
          | t -> failwithf "Type not supported by RouteMap: %s" t.AssemblyQualifiedName
  
      let routeShapeT = concrete(Reflection.getTypeDefinition typeof<RouteShape>, [])
  