Open turboMaCk opened 3 years ago
up
@dtaskoff in meantime can you use one of the work-around mentioned above?
Sure, it's just that I changed a type from data to a newtype, and spent some time wondering why it didn't work. It's even written in the documentation already (to use deriving newtype (FromJSON, ToJSON)
, and deriving anyclass Elm
), so it's only a matter of convenience.
cool. There is another related but slightly different issue which is that elm-street likes to generate record aliases for new types on elm side. But semantically it would be better to better to generate regular type
since elm compiler can unbox these in compile time much like Haskell does for new types. It can't do it for records though because records are real records in elm, not just field accessors like in Haskell.
I'm not sure that it's a good idea to translate Haskell's newtype
s into Elm's type alias
es, since in Elm they are really just aliases, so type alias X = Int
, and type alias Y = Int
are indistinguishable.
it should not be alias. elm equivalent of newtype Foo a = Foo { unFoo :: a }
is type Foo a = Foo a
. There are 2 differences in type systems in play here:
newtype
for runtime unboxed values. Elm implicitly unboxes all values it can for type
.so generating types elm can unbox would not be less type safe on elm side. It would be more type safe because it would generate distinct type rather than alias so newtype Foo = Foo { fooVal :: Int }
and newtype Bar = Bar { barVal :: Int }
would not be the same alias on elm side as they are now.
My bad, I misread type
for type alias
in your previous comment.
no worries. this terminology is super confusing between Elm and Haskell..
that's a recipe for misunderstanding.
I will try to bring this issue up internally at Holmusk but expect this issue will take some time to resolve. There is a lot of code in the wild which need to keep supporting without introducing major breakages.
Deriving instances for
newtype
is broken in cases like:Json instances expect the value to be wrapped in tagged object while elm decoders are generated for json string values. Decoding therefore fails (at runtime).
Two other ways to derive the value work
This generates instances where both expect wrapping object to be present.
Derives the instance where json values are not boxed in json representation.
I think the later option is better in most cases but there is a disadvantage for types which might start as a newtype and later be changed to full
data
record. This often happens as hlint complains aboutdata
with single field. With 2nd approach the JSON representation in not compatible betweennewtype
anddata
so changing types fromnewtype
todata
is breaking change for the api.Related Issues