nickcowle / HCollections

Type-safe heterogeneous collections for F#
MIT License
6 stars 4 forks source link

My HList of 1586 items #4

Open Thorium opened 4 years ago

Thorium commented 4 years ago

It seems that a list of 1586 items kills Visual Studio. It just dies without any warnings.

I haven't debugged why. I expect what could happen is a stack-overflow in FSharp compiler (i.e. generating the tooltips for function signatures).

HList of 1585 items seems to work ok.

Edit: Visual Studio Professional 2017, version 15.9.13

Thorium commented 4 years ago

BTW, it could be helpful to have more unit-tests in this project as examples how to work with HLists. I was testing to create a foldr but there was no examples how to use current HListTFolder in this project.

Smaug123 commented 4 years ago

@Thorium This is a tooling problem; I suspect there's not much we can do about it. The following demonstrates for me in VS2019 16.3.0 that HLists can cope with being quite large (although this is extremely slow). This was done off master, which contains a performance optimisation to HList.length relative to the current Nuget version.


    type 'ret HListEvaluator = abstract Eval<'u> : 'u HList -> 'ret
    type HListCrate = abstract Apply<'ret> : 'ret HListEvaluator -> 'ret

    [<RequireQualifiedAccess>]
    module HListCrate =
        let make<'a> (i : 'a HList) =
            { new HListCrate with
                member __.Apply e = e.Eval i
            }

        let length (i : HListCrate) : int =
            i.Apply { new HListEvaluator<_> with
                member __.Eval h = HList.length h
            }

    let toHList<'a> (l : 'a list) : HListCrate =
        l
        |> List.fold (fun cr elt ->
            cr.Apply { new HListEvaluator<_> with
                member __.Eval<'b> (l : 'b HList) =
                    HList.cons elt l
                    |> HListCrate.make
            }) (HListCrate.make HList.empty)

    [<Fact>]
    let largeHlist () =
        let i = 7000
        let l = List.init i id
        let hl = l |> toHList

        Assert.Equal (i, HListCrate.length hl)