Zaid-Ajaj / LiteDB.FSharp

Advanced F# Support for LiteDB, an embedded NoSql database for .NET with type-safe query expression through F# quotations
MIT License
181 stars 20 forks source link

Single private case union support #55

Closed humhei closed 3 years ago

humhei commented 3 years ago

Single private case union is widely used in Domain Driven Design , I would like to implement it to LiteDB.FSharp, how do you think? @Zaid-Ajaj

humhei commented 3 years ago

It's more than a experiment, It has some limition For example

type SpeficPerson = private SpeficPerson of name: string * age: int * specficInfo: SpecficInfo
with 
    member x.Name =
        let (MySinglePrivateCaseUnion (name, age, specficInfo)) = x
        name

    static member Create(name, age, specficInfo) = 
        // check the input dataInfo here, and then create it

It's hard to querable for further quotations(Not means fullsearch, May be implemented in future) as the private (name: string * age: int * specficInfo: SpecficInfo) is mising

While if it's public , You can reslove it in quotation expression and do more typed query

<@
///other codes 
let (SpecificPerson (name, age, sepcificInfo)) = specificPerson 
///other codes 
@>

An workaround is to implement ICaseInfo<'T> to add the addtional caseInfo

type SpeficPerson = private SpeficPerson of name: string * age: int * specficInfo: SpecficInfo
with 
    member x.Name =
        let (MySinglePrivateCaseUnion (name, age, specficInfo)) = x
        name

    static member Create(name, age, specficInfo) = 
        // check the input dataInfo here, and then create it

    interface ICaseInfo<string * int * SpecficInfo> with 
            member x.CaseInfo() = 
                  let (MySinglePrivateCaseUnion (name, age, specficInfo)) = x
                  (name, age, speficInfo)

Then we can use this type in quatation expression

<@
///other codes 
/// Here `ICaseInfo` is an active pattern to resolve `ICaseInfo<'T>`
let (ICaseInfo (name, age, sepcificInfo)) = specificPerson 
///other codes 
@>