<commit_before>﻿// Copyright (C) by <NAME>

[<AutoOpen>]
module internal Infers.TypeManip

open System.Collections.Generic
open System.Reflection
open System.Threading
open System

////////////////////////////////////////////////////////////////////////////////

module Fresh =
  type t = int
  let mutable private counter: t = 0

  let newMapper () =
    let v2w = Dictionary<_, _> ()
    fun v ->
      Dictionary.getOr v2w v <| fun () ->
        Interlocked.Increment &counter

////////////////////////////////////////////////////////////////////////////////

type TyCon =
  | Arr of rank: int
  | Def of def: Type

type Ty =
  | Var of Fresh.t
  | App of TyCon * array<Ty>
  | Mono of Type
  override t.ToString () =
    match t with
     | Mono t ->
       sprintf "%A" t
     | Var v -> sprintf "%A" v
     | App (Def tc, [||]) ->
       sprintf "%A" tc
     | App (tc, tys) ->
       match tc with
        | Arr _ ->
          sprintf "array<%A>" tys.[0]
        | Def t ->
          if t = typedefof<_ -> _> then
            sprintf "(%A -> %A)" tys.[0] tys.[1]
          elif t = typedefof<list<_>> then
            sprintf "list<%A>" tys.[0]
          else
            sprintf "%A%A" t tys

let (|App'|Var'|) ty =
  match ty with
   | Var v -> Var' v
   | App (tc, tys) -> App' (tc, tys)
   | Mono t ->
     if t.IsArray then
       App' (Arr (t.GetArrayRank ()), [|t.GetElementType () |> Mono|])
     elif t.IsGenericType then
       App' (Def (t.GetGenericTypeDefinition ()),
             t.GetGenericArguments () |> Array.map Mono)
     else
       App' (Def t, [||])

let (|TyCon'|_|) ty =
  match ty with
   | Var _ -> None
   | App (tc, _) -> Some tc
   | Mono t ->
     if t.IsArray then
       Arr (t.GetArrayRank ()) |> Some
     elif t.IsGenericType then
       Def (t.GetGenericTypeDefinition ()) |> Some
     else
       Def t |> Some

let (|TyArgs'|) ty =
  match ty with
   | Var _ -> [||]
   | App (_, tys) -> tys
   | Mono t ->
     if t.IsArray then
       [|t.GetElementType () |> Mono|]
     elif t.IsGenericType then
       t.GetGenericArguments () |> Array.map Mono
     else
       [||]

[<CompilationRepresentation (CompilationRepresentationFlags.ModuleSuffix)>]
module TyCon =
  let apply tc ts =
    match (tc, ts) with
     | (Def t, ts) ->
       t.MakeGenericType ts
     | (Arr r, [|t|]) ->
       if r = 1
       then t.MakeArrayType ()
       else t.MakeArrayType r
     | _ ->
       failwith "Bug: apply %A %A" tc ts

[<CompilationRepresentation (CompilationRepresentationFlags.ModuleSuffix)>]
module Ty =
  let inline containsVars ty =
    match ty with
     | Mono _ -> false
     | Var _ | App _ -> true

  let ofTypeIn env (t: Type) =
    let rec ofType (t: Type) =
      if t.IsArray then
        match t.GetElementType () |> ofType with
         | Mono _ ->
           Mono t
         | ty ->
           App (Arr (t.GetArrayRank ()), [|ty|])
      elif t.IsGenericParameter then
        Var (env t)
      elif t.IsGenericType then
        let tys = t.GetGenericArguments () |> Array.map ofType
        if Array.exists containsVars tys
        then App (Def (t.GetGenericTypeDefinition ()), tys)
        else Mono t
      else<commit_msg>Fix to use failwithf as intended.<commit_after>﻿// Copyright (C) by <NAME>

[<AutoOpen>]
module internal Infers.TypeManip

open System.Collections.Generic
open System.Reflection
open System.Threading
open System

////////////////////////////////////////////////////////////////////////////////

module Fresh =
  type t = int
  let mutable private counter: t = 0

  let newMapper () =
    let v2w = Dictionary<_, _> ()
    fun v ->
      Dictionary.getOr v2w v <| fun () ->
        Interlocked.Increment &counter

////////////////////////////////////////////////////////////////////////////////

type TyCon =
  | Arr of rank: int
  | Def of def: Type

type Ty =
  | Var of Fresh.t
  | App of TyCon * array<Ty>
  | Mono of Type
  override t.ToString () =
    match t with
     | Mono t ->
       sprintf "%A" t
     | Var v -> sprintf "%A" v
     | App (Def tc, [||]) ->
       sprintf "%A" tc
     | App (tc, tys) ->
       match tc with
        | Arr _ ->
          sprintf "array<%A>" tys.[0]
        | Def t ->
          if t = typedefof<_ -> _> then
            sprintf "(%A -> %A)" tys.[0] tys.[1]
          elif t = typedefof<list<_>> then
            sprintf "list<%A>" tys.[0]
          else
            sprintf "%A%A" t tys

let (|App'|Var'|) ty =
  match ty with
   | Var v -> Var' v
   | App (tc, tys) -> App' (tc, tys)
   | Mono t ->
     if t.IsArray then
       App' (Arr (t.GetArrayRank ()), [|t.GetElementType () |> Mono|])
     elif t.IsGenericType then
       App' (Def (t.GetGenericTypeDefinition ()),
             t.GetGenericArguments () |> Array.map Mono)
     else
       App' (Def t, [||])

let (|TyCon'|_|) ty =
  match ty with
   | Var _ -> None
   | App (tc, _) -> Some tc
   | Mono t ->
     if t.IsArray then
       Arr (t.GetArrayRank ()) |> Some
     elif t.IsGenericType then
       Def (t.GetGenericTypeDefinition ()) |> Some
     else
       Def t |> Some

let (|TyArgs'|) ty =
  match ty with
   | Var _ -> [||]
   | App (_, tys) -> tys
   | Mono t ->
     if t.IsArray then
       [|t.GetElementType () |> Mono|]
     elif t.IsGenericType then
       t.GetGenericArguments () |> Array.map Mono
     else
       [||]

[<CompilationRepresentation (CompilationRepresentationFlags.ModuleSuffix)>]
module TyCon =
  let apply tc ts =
    match (tc, ts) with
     | (Def t, ts) ->
       t.MakeGenericType ts
     | (Arr r, [|t|]) ->
       if r = 1
       then t.MakeArrayType ()
       else t.MakeArrayType r
     | _ ->
       failwithf "Bug: apply %A %A" tc ts

[<CompilationRepresentation (CompilationRepresentationFlags.ModuleSuffix)>]
module Ty =
  let inline containsVars ty =
    match ty with
     | Mono _ -> false
     | Var _ | App _ -> true

  let ofTypeIn env (t: Type) =
    let rec ofType (t: Type) =
      if t.IsArray then
        match t.GetElementType () |> ofType with
         | Mono _ ->
           Mono t
         | ty ->
           App (Arr (t.GetArrayRank ()), [|ty|])
      elif t.IsGenericParameter then
        Var (env t)
      elif t.IsGenericType then
        let tys = t.GetGenericArguments () |> Array.map ofType
        if Array.exists containsVars tys
        then App (Def (t.GetGenericTypeDefinition ()), tys)
        else Mono t
      else
{'fraction_non_alphanumeric': 0.17503519474425153, 'fraction_numerical': 0.002502737368997341, 'mean_word_length': 1.6586278586278587, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 95, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1273179', 'n_tokens_mistral': 2067, 'n_tokens_neox': 2088, 'n_words': 630}