<commit_before>﻿module Fancy
open System  
open System.ComponentModel   
open System.Dynamic
open System.Text.RegularExpressions
open Printf

open Microsoft.FSharp.Quotations   
open Microsoft.FSharp.Quotations.Patterns 
open Microsoft.FSharp.Quotations.DerivedPatterns

open Nancy            
open Nancy.Bootstrapper             
open Nancy.Hosting.Self

let getParameters (instance:'a->'b) =
    instance.GetType().GetMethods().[0].GetParameters()
    |> Seq.map (fun parameter-> parameter.Name, parameter.ParameterType)
    |> Seq.where (fun (_,parameterType) -> parameterType <> typeof<unit>)
        
let matchParameters parameters (dict:DynamicDictionary) =
    parameters
    |> Seq.map (fun (name:string,targetType) -> ((dict.[name] :?> DynamicDictionaryValue).Value,targetType))
    |> Seq.map (fun (value,targetType) ->
        match value with 
        | x when x.GetType() = targetType -> x
        | x ->
            let converter = TypeDescriptor.GetConverter(targetType)
            match converter.CanConvertFrom(x.GetType()) with
            | true -> converter.ConvertFrom(x)
            | false -> Convert.ChangeType(x, targetType))

let invokeFunction (instance:'a->'b) parameters =
    match Array.length parameters with
    | 0 -> instance.GetType().GetMethods().[0].Invoke(instance, [|()|])
    | _ -> instance.GetType().GetMethods().[0].Invoke(instance, parameters)

let rec printHelper<'a> (fmt:string) (list:string list) : 'a =
    match list with
    | [] -> sprintf <| Printf.StringFormat<_> fmt
    | s :: rest -> printHelper<string -> 'a> fmt rest s
    
let toNancy parameter =
    sprintf "%s" parameter

let formatNancyString inputString =
    Regex.Replace(inputString, "%i", "{%s:int}")

type State<'T, 'State> = 'State -> 'T * 'State
let getState = fun s -> (s,s)
let putState s = fun _ -> ((),s)
let eval m s = m s |> fst
let exec m s = m s |> snd
let empty = fun s -> ((), s)
let bind k m = fun s -> let (a, s') = m s in (k a) s'
                                                            
type NancyBuilder() =
    member this.Return(a) : State<'T,'State> = fun s -> (a,s)
    member this.Bind(m:State<'T,'State>, k:'T -> State<'U,'State>) : State<'U,'State> = bind k m
    member this.Combine(r1, r2) = this.Bind(r1, fun () -> r2)
    [<CustomOperation("get", MaintainsVariableSpaceUsingBind=true)>]
    member this.Get(m, url:StringFormat<'a->'b,'c>, processor:'a->'b) =
        let parameters = getParameters processor
        let url' = printHelper (formatNancyString url.Value) (Seq.map (fun (i,_) -> i) parameters |> Seq.map toNancy |> Seq.toList)
        this.Bind(m, fun _ ->
            this.Bind(getState, fun (nancyModule:NancyModule) ->
                do nancyModule.Get.[url'] <-
                    fun i ->
                        (i :?> DynamicDictionary)
                        |> matchParameters parameters
                        |> Seq.toArray
                        |> invokeFunction processor
                putState nancyModule))
let nancy = new NancyBuilder()

let pipeline =
    nancy {
        get "/" (fun () -> sprintf "Hello World!")
        get "/%s" (fun name -> sprintf "Hello %s!" name) 
        get "/square/%i" (fun number -> sprintf "%i" <| number * number) 
    }

type FSharpNancy() as this =
    inherit NancyModule()
    do exec pipeline this |> ignore
<commit_msg>Changes names to fancy<commit_after>﻿module Fancy
open System  
open System.ComponentModel   
open System.Dynamic
open System.Text.RegularExpressions
open Printf

open Microsoft.FSharp.Quotations   
open Microsoft.FSharp.Quotations.Patterns 
open Microsoft.FSharp.Quotations.DerivedPatterns

open Nancy            
open Nancy.Bootstrapper             
open Nancy.Hosting.Self

let getParameters (instance:'a->'b) =
    instance.GetType().GetMethods().[0].GetParameters()
    |> Seq.map (fun parameter-> parameter.Name, parameter.ParameterType)
    |> Seq.where (fun (_,parameterType) -> parameterType <> typeof<unit>)
        
let matchParameters parameters (dict:DynamicDictionary) =
    parameters
    |> Seq.map (fun (name:string,targetType) -> ((dict.[name] :?> DynamicDictionaryValue).Value,targetType))
    |> Seq.map (fun (value,targetType) ->
        match value with 
        | x when x.GetType() = targetType -> x
        | x ->
            let converter = TypeDescriptor.GetConverter(targetType)
            match converter.CanConvertFrom(x.GetType()) with
            | true -> converter.ConvertFrom(x)
            | false -> Convert.ChangeType(x, targetType))

let invokeFunction (instance:'a->'b) parameters =
    match Array.length parameters with
    | 0 -> instance.GetType().GetMethods().[0].Invoke(instance, [|()|])
    | _ -> instance.GetType().GetMethods().[0].Invoke(instance, parameters)

let rec printHelper<'a> (fmt:string) (list:string list) : 'a =
    match list with
    | [] -> sprintf <| Printf.StringFormat<_> fmt
    | s :: rest -> printHelper<string -> 'a> fmt rest s
    
let toNancy parameter =
    sprintf "%s" parameter

let formatNancyString inputString =
    Regex.Replace(inputString, "%i", "{%s:int}")

type State<'T, 'State> = 'State -> 'T * 'State
let getState = fun s -> (s,s)
let putState s = fun _ -> ((),s)
let eval m s = m s |> fst
let exec m s = m s |> snd
let empty = fun s -> ((), s)
let bind k m = fun s -> let (a, s') = m s in (k a) s'
                                                            
type FancyBuilder() =
    member this.Return(a) : State<'T,'State> = fun s -> (a,s)
    member this.Bind(m:State<'T,'State>, k:'T -> State<'U,'State>) : State<'U,'State> = bind k m
    member this.Combine(r1, r2) = this.Bind(r1, fun () -> r2)
    [<CustomOperation("get", MaintainsVariableSpaceUsingBind=true)>]
    member this.Get(m, url:StringFormat<'a->'b,'c>, processor:'a->'b) =
        let parameters = getParameters processor
        let url' = printHelper (formatNancyString url.Value) (Seq.map (fun (i,_) -> i) parameters |> Seq.map toNancy |> Seq.toList)
        this.Bind(m, fun _ ->
            this.Bind(getState, fun (nancyModule:NancyModule) ->
                do nancyModule.Get.[url'] <-
                    fun i ->
                        (i :?> DynamicDictionary)
                        |> matchParameters parameters
                        |> Seq.toArray
                        |> invokeFunction processor
                putState nancyModule))
let fancy = new FancyBuilder()

let pipeline =
    fancy {
        get "/" (fun () -> sprintf "Hello World!")
        get "/%s" (fun name -> sprintf "Hello %s!" name) 
        get "/square/%i" (fun number -> sprintf "%i" <| number * number) 
    }

type FSharpNancy() as this =
    inherit NancyModule()
    do exec pipeline this |> ignore

{'fraction_non_alphanumeric': 0.14283584314894887, 'fraction_numerical': 0.0023855673177277472, 'mean_word_length': 2.5194123819517316, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 119, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6846835', 'n_tokens_mistral': 2058, 'n_tokens_neox': 2018, 'n_words': 537}