anchor.diff:          |> Seq.map snd
           |> Seq.fold (fun acc namedDef -> acc @ validateType namedDef) Success
   
  +type SchemaInfo =
  +    { SchemaTypes : Map<string, IntrospectionType>
  +      QueryType : IntrospectionType option
  +      SubscriptionType : IntrospectionType option
  +      MutationType : IntrospectionType option }
  +    static member FromIntrospectionSchema(schema : IntrospectionSchema) =
  +        let schemaTypes = schema.Types |> Seq.map (fun x -> x.Name, x) |> Map.ofSeq
  +        let rec getSchemaType (tref : IntrospectionTypeRef) =
  +            match tref.Kind with
  +            | TypeKind.NON_NULL | TypeKind.LIST when tref.OfType.IsSome -> getSchemaType tref.OfType.Value
  +            | _ -> tref.Name |> Option.bind schemaTypes.TryFind
  +        { SchemaTypes = schema.Types |> Seq.map (fun x -> x.Name, x) |> Map.ofSeq
  +          QueryType = getSchemaType schema.QueryType
  +          MutationType = schema.MutationType |> Option.bind getSchemaType
  +          SubscriptionType = schema.SubscriptionType |> Option.bind getSchemaType }
  +    member x.TryGetOperationType(ot : OperationType) =
  +        match ot with
  +        | Query -> x.QueryType
  +        | Mutation -> x.MutationType
  +        | Subscription -> x.SubscriptionType
  +    member x.TryGetTypeByName(name : string) =
  +        x.SchemaTypes.TryFind(name)
  +
   module Ast =
       let private getOperationDefinitions (ast : Document) =
           ast.Definitions |> List.choose (function | OperationDefinition x -> Some x | _ -> None)
  
positive.code:                 | None -> acc @ Error [ sprintf "Subscription operations should have only one root field. Operation has %i fields (%s)." fieldNames.Length fieldNamesAsString ]
          getOperationDefinitions ast
          |> List.choose (fun def -> if def.OperationType = Subscription then Some (def.Name, getFieldNames [] def.SelectionSet) else None)
          |> List.fold (fun acc (name, fieldNames) -> validate acc name fieldNames) Success
negative.code:             | selection :: tail ->
                  let acc =
                      match selection with
                      | Field field -> field.AliasOrName :: acc
                      | InlineFragment frag -> getFieldNames acc frag.SelectionSet
                      | FragmentSpread spread ->
                          let frag = fragmentDefinitions |> List.tryFind (fun x -> x.Name.IsSome && x.Name.Value = spread.Name)
  