module Species exposing(Mammal)
type Mammal
= Cat
| Dog
I’ve got a newbie(stupid) question: I found the first line module Species exposing(Mammal) is valid. But what is it good for, instead of module Species exposing(Mammal(..))?
Exposing Mammal in the former way still cannot allow you access the contructor(Cat or Dog) from other modules. Then when it can be used?
In another thread I gave an example of a Length that assured it was never negative. It’s not a great example though since I was really answering a different question and just explaining opaque types as an aside.
Another example might be if you want to be able to change the implementation of something, but keep its API the same. So the package elm/core exposed Dict as:
type Dict k v
Inside that package is an implementation of Dict. Maybe later someone decides a different data structure + algorithm is better (faster or uses less memory etc). With the opaque type, all of that can be changed behind the scenes without the users of Dict even being aware - they just plug in the new one and get the benefits.
So the idea comes from modular design principles, which state that you should give the smallest interface onto something that is needed to use it. This allows the complexity behind something to be hidden, which means that the user of it needs to understand less about it in order to use it. It also removes the possibility of a user accidentally making their code depend on some implementation detail, which would then cause their code to break if that is changed. So its about simplicity, and allowing developers to work in parallel by only having a shared API contract between them.
Of course if the API changes, Elm’s enforced semantic versioning will help to handle that too…
It’s one of my favorite features in Elm
It’s a feature that when used well can make your project a lot more maintainable, so it’s one worth learning more about it.
Dillon and I talked extensively on this topic on the Elm Radio podcast, if that’s a medium you like.
Thank you guys so much. I need more time to get a grasp on type(and opaque type) in a rush on learning elm. It’s a little like class in Java or even javascript, but the difference is huge.
There is some similarity - like a class with private fields, and private methods, that exposes how it works through its public methods only. I tend to think that a module in Elm is roughly equivalent to a class in Java.
I think both ideas have their roots in modular design principles.
A major difference is that OO languages have sub-classing, where you can always extend things. An Elm module supports only 1 implementation. You can make an even more class-like thing in Elm using records or extensible records, but its not a good idea to get into that without a compelling reason.