Shmew / Feliz.MaterialUI

Feliz-style Fable bindings for Material-UI
https://shmew.github.io/Feliz.MaterialUI/
MIT License
70 stars 19 forks source link

Conflict between nested modules/types? #40

Closed cmeeren closed 4 years ago

cmeeren commented 4 years ago

(cc @Zaid-Ajaj)

In the new theme DSL, I have this:

module theme =

  type palette =
    static member inline primary (color: Color) : IThemeProp = unbox ("palette.primary", color)

  module palette =

    [<Erase>]
    type primary =
      static member inline main (color: string) : IThemeProp = unbox ("palette.primary.main", color)

Unfortunately, it seems that for some reason, this does not allow using theme.palette.primary.main:

image

Here's a minimal repro:

module test=

  type a =
    static member inline b x = x

  module a =

    type b =
      static member inline c x = x

// Doesn't compile
let x = test.a.b.c
//               ^ The field, constructor or member 'c' is not defined

// Compiles
open test
let x = a.b.c

Does anyone have any idea why, and if it can be circumvented? Currently things aren't looking good for the flattened theme DSL...

Zaid-Ajaj commented 4 years ago

Maybe try to define the module palette before the type palette?

Edit

Doesn't work, just tried it

Zaid-Ajaj commented 4 years ago

I can't test the following in the REPL but maybe it would help to add type palette as an extension type for module theme in a different file. i.e.

// File A
module test =
  module a =
    module b =
      let inline c x = x

// File B
module test = 
    type a = 
        static member inline b x = x
cmeeren commented 4 years ago

Nope, still fails. (VS gives no error, but Fable compilation fails with the same error.)

cmeeren commented 4 years ago

Reported as F# compiler issue here: https://github.com/dotnet/fsharp/issues/8432

Shmew commented 4 years ago

Yeah, this is because of the way the compiler resolves types. It picks out the first value that works, which means if you have three levels of nesting it stops working. It's why I had to change the dsl I used in Feliz.Plotly

cmeeren commented 4 years ago

Could you briefly describe how you solved it?

Shmew commented 4 years ago

I traversed the schema to find things that were unique and nested them inside the different properties, and everything else was top level. So before it would have been something like:

scatter.font [ 
    scatter.font.size 10 
]

where every level of nesting was getting longer, but now it is like this:

scatter.font [
    font.size 10
]

Once I had something that was deeper than three levels (so any more nesting than above) it would stop working and I had to use module aliasing to fix it. Luckily for me almost everything the different charts used were almost the same.

cmeeren commented 4 years ago

The only collisions are the stuff under palette, and I seem to be able to solve it by just renaming the modules. My preferred solution right now:

theme.palette.primary Colors.indigo  // as normal
theme.palette.primary'.main "#aabbcc"  // note the extra apostrophe

This allows the DSL to otherwise stay consistent.