Holmusk / elm-street

:deciduous_tree: Crossing the road between Haskell and Elm
Mozilla Public License 2.0
88 stars 6 forks source link

Type aliases get generated with their rhs leading to duplicate definitions #124

Closed HugoPeters1024 closed 2 years ago

HugoPeters1024 commented 2 years ago

The following haskell snippet:

data CoreId = CoreId { name :: Text
                     , bindId :: Int 
                     }
                     deriving (Show, Generic)
                     deriving (Elm, ToJSON, FromJSON) via ElmStreet CoreId

type CoreBndr = CoreId

leads to the following generated Elm types:

type alias CoreId =
    { name : String
    , id : Int
    }

type alias CoreId =
    { name : String
    , id : Int
    }

I suspect that the type alias name is fetched from the rhs instead of the lhs. Perhaps more ideally it gets generated as an actual type alias.

P.S.

I'm loving the library thusfar and its proving very useful, thanks for your hard work

jhrcek commented 2 years ago

I assume that your goal was to generate elm code like this:

type alias CoreId =
    { name : String
    , id : Int
    }

type alias CoreBndr =
    CoreId

From haskell code like this:

-- your example definitions...

type Types = '[CoreId, CoreBndr]

main :: IO ()
main = generateElm @Types $ defaultSettings "frontend/src" ["Core", "Generated"]

I would say the behavior you're describing is as expected (although I'd agree it's undesirable).

According to section 4.2.2 in Haskell 98 report "Type synonyms are a convenient, but strictly syntactic, mechanism to make type signatures more readable."

So CoreBndr is really just another name for CoreId. Importantly it has identical instance of Elm type class => the same Elm code is generated for it. If you wanted different code to be generated, you would need CoreBndr to have different instance of Elm type class. But AFAIK there's no way to associate different type class with type alias.

HugoPeters1024 commented 2 years ago

Thanks for the explanation, for now I've settled to work without the extra clarity of the alias