I have been thinking about the accepted module params proposal lately. The proposal nicely describes the many benefits it unlocks with regards to platform-agnostic modules, by e.g. allowing us to parameterize the module with respect to functions that return Tasks.
But if I understand correctly, the module params can be used for other things. So I might pass in a defined value or function. Then this might unlock another approach to designing APIs that define functions with fewer parameters. I was thinking about this when I read the recent string reference Richard put together. E.g. capitalization is language dependent and hence we should also specify the language when we call capitalize. A basic typesignature of this function, after imported from the Unicode module, could then be
Unicode.capitalize: Str, Language -> Str
All in all this is a slight inconvenience compared to the experience from other languages (though there it is often error-prone, as Richard points out). But with module params we could make this module take a parameter that specifies the language, and then the typesignature would just be Unicode.capitalize: Str -> Str. So for example
import Unicode { language: EnGb } as English
str = "ijk"
expect str |> English.capitalize str == "IJK"
Which is pretty neat!
Also, if I understand the concept of "inline import" correctly, we could even have this language be specified at runtime! (e.g. for UIs where the end user specifies the language).
Did I understand module params correctly? If so, would this a good way to design APIs?
I hadn't thought about this! It's definitely interesting
it would give people a potential way to hardcode it at first and then later introduce locale-specific behavior, which is cool
Whoa that’s awesome!
That’s a nice use case!
I also thought it could work for that Elm pattern where you pass a Context/Session argument to your Page’s init/update/subscriptions/view functions
You’d have to inline import with the value from the root TEA functions, but it should work
Agus Zubiaga said:
I also thought it could work for that Elm pattern where you pass a
Context/Sessionargument to your Page’sinit/update/subscriptions/viewfunctions
Yes I guess generically it’s a nice way to pass configurations to modules
Agus Zubiaga said:
You’d have to inline import with the value from the root TEA functions, but it should work
What are root TEA functions?
I mean the import needs to be inside each of your app’s root init/update/subscriptions/view functions in order for the current context to be able available (presumably derived from Model)
Ah I see
Not as clean as the Unicode example :)
TEA being The Elm Architecture
This is very cool, seems very similar to ocaml's functors which is easily one of the coolest features of the language
Eli Dowling said:
This is very cool, seems very similar to ocaml's functors which is easily one of the coolest features of the language
Yes I had those in the back of my mind, though I never learned enough ocaml to understand their version of functors. Something like functions that map modules to modules? I guess that is similar to this
Another thought: could modules have optional parameters? So one might declare the module as
Unicode: {language ? EnGb} -> [capitalization]
And then when importing it one could either choose to not pass in a parameter and use the default configuration, or one could pass it in and make an explicit choice. Would enable easy use of default configs.
Yeah, I tried to learn about it a few times earlier in my learning of the language and i could read the words and look at the examples but it never really sunk in how to use it and why you want it.
I took building bigger stuff and actually needing it for it to start to make proper sense.
I realise I have some more thoughts about module params, will make separate threads for them to not jumble the discussions
Last updated: Jun 16 2026 at 16:19 UTC