F# - Merge modules?
I'm at the moment working on a Entity Framework Code First Wrapper for F#, and I've been wondering whether I should merge all my modules into just one.
Take a look at this:
module ManyNavProperty =
let withMany (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithMany()
let withSeq expr (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithSeq expr
let withList expr (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithList expr
let withArray expr (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithArray expr
let withOptional (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithOptional()
let withOptionalProperty expr (cfg开发者_开发百科:ManyNavPropertyInfo<'a,'b>) = cfg.WithOptional expr
let withRequired (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithRequired()
let withRequiredProperty expr (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithRequiredProperty expr
module DependentNavProperty =
let hasForeignKey expr (cfg:DependentNavPropertyInfo<'a>) = cfg.HasForeignKey expr
module CascadableNavProperty =
let willCascadeOnDelete b (cfg:CascadableNavPropertyInfo) = cfg.WillCascadeOnDelete b
module EF =
let entity<'a when 'a : not struct> (cfg:DbModelBuilder) = EntityInfo<'a>(cfg.Entity<'a>())
let hasKey expr (cfg:EntityInfo<'a>) = cfg.HasKey expr
let hasSeq expr (cfg:EntityInfo<'a>) = cfg.HasSeq expr
let hasList expr (cfg:EntityInfo<'a>) = cfg.HasList expr
let hasArray expr (cfg:EntityInfo<'a>) = cfg.HasArray expr
let hasOptional expr (cfg:EntityInfo<'a>) = cfg.HasOptional expr
let hasRequired expr (cfg:EntityInfo<'a>) = cfg.HasRequried expr
let toTable s (cfg:EntityInfo<'a>) = cfg.ToTable s
that would require me to call the code like:
override x.OnModelCreating (mb:DbModelBuilder) =
let finished = ignore
let entity = EF.entity<Author> mb
entity
|> EF.hasSeq <@ fun z -> z.Books @>
|> ManyNavProperty.withRequiredProperty <@ fun z -> z.Author @>
|> DependentNavProperty.hasForeignKey <@ fun z -> z.AuthorId @>
|> CascadableNavProperty.willCascadeOnDelete true
|> finished
Is the use of so many modules confusing for the user? - Should I place them all into one module, or will that destroy the overview for the user?
An example where all functions are placed in same Module:
override x.OnModelCreating (mb:DbModelBuilder) =
let finished = ignore
let entity = EF.entity<Author> mb
entity
|> EF.hasSeq <@ fun z -> z.Books @>
|> EF.withRequiredProperty <@ fun z -> z.Author @>
|> EF.hasForeignKey <@ fun z -> z.AuthorId @>
|> EF.willCascadeOnDelete true
|> finished
This is a tricky design question.
Generally, F# libraries tend to group functions that work with a type (e.g. list<T>
or seq<T>
) in a separate module with the name same as the type (e.g. List.xyz
and Seq.xyz
). This works well for common types, because the users learn how to find the functions.
However, for less common types (e.g. your own library), it may be a bit difficult to discover these modules (especially if the type is not created explicitly (but is obtained as a result of some call). Having one module name and then use .
to explore it is quite powerful.
I would probably suggest using nested modules. Something like:
module EF =
// common functions
module Cascadable =
// CascadableNavProperty functions
module Many =
// etc.
The users could then find everything by starting with EF
. They'd write something like:
entity
|> EF.hasSeq <@ fun z -> z.Books @>
|> EF.Many.withRequiredProperty <@ fun z -> z.Author @>
|> EF.Dependent.hasForeignKey <@ fun z -> z.AuthorId @>
|> EF.Cascadable.willCascadeOnDelete true
|> finished
精彩评论