A type-safe string formatting library. It fulfils the need for
string-interpolation or a printf function, without sacrificing Elm's
runtime guarantees or requiring any language-level changes. It also
composes well, to make building up complex formatters easy.
Create a new formatter by applying a function to the output of this formatter.
For example:
import String exposing (toUpper)
format =
s "Name: " |> bs map toUpper string...produces a formatter that uppercases the name:
print format "Kris"
--> "Name: KRIS"Create a new formatter by applying a function to the input of this
formatter. The dual of map.
For example:
format =
s "Height: " |> bs premap .height float...produces a formatter that accesses a .height record field:
print format { height: 1.72 }
--> "Height: 1.72"Convert an ordinary 'stringifying' function into a Formatter.
Apply an argument to a Formatter. Useful when you want to supply
an argument, but don't yet want to convert your formatter to a plain
ol' function (with print).
Turn your formatter into a function that's just waiting for its arguments.
Given this format:
orderFormat =
s "FREE: " |> bs int |> bs s " x " |> bs string |> bs s "!"...we can either use it immediately:
order : String
order =
print orderFormat 2 "Ice Cream"
--> "FREE: 2 x Ice Cream!"...or turn it into an ordinary function to be used later:
orderFormatter : Int -> String -> String
orderFormatter =
print orderFormat
...elsewhere...
order : String
order = orderFormatter 2 "Ice Cream"
--> "FREE: 2 x Ice Cream!"Convenience function. Like print, but returns an Html.text
node as its final result, instead of a String.
Hint: If you're using any formatters where whitespace is sigificant, you might well need one or both of these CSS rules:
font-family: monospace;
white-space: pre;wrap one string with another. It's convenient for building strings
like `"Invalid key '<keyname>'." For example:
print (wrap "'" string) "tester"
--> "'tester'"String.pad lifted into the world of Formatters.
For example:
print (pad 10 '-' string) "KRIS"
--> "---KRIS---"String.padLeft lifted into the world of Formatters.
For example:
print (padLeft 10 '_' float) 1.72
--> "______1.72"String.padRight lifted into the world of Formatters.
For example:
print (padRight 10 '.' int) 789
--> "789......."Format a URI fragment.
For example:
print uriFragment "this string"
--> "this%20string"
A formatter. This type holds all the information we need to create a formatting function, wrapped up in a way that makes it easy to compose.
Build one of these up with primitives like
s,stringandint, join them together with|> bs, and when you're done, generate the final printing function withprint.Example
Creating Custom Formatters
Imagine you have an existing formatting rule you'd like to turn into a formatter:
First, wrap the type signature in brackets:
Then change the result type to a variable. (That's where the magic begins - the Formatting library gets control of the final result type.):
Now add
Format rto the start.All very mechanical. Now for the function body. Let's recall what it looked like at the start:
Change that into an anonymous function:
Now add in a
callbackfunction as the first argument:Pass your function's result to that callback (using
<|is the easy way):Finally, wrap that all up in a
Formatconstructor:And you're done. You have a composable formatting function. It's a mechanical process that's probably a bit weird at first, but easy to get used to.
Format (\callback -> g (\strG -> f (\strF -> callback (strG ++ strF))))