Build a file!
Elm.file [ "My", "Module" ]
[ Elm.declaration "placeholder"
(Elm.string "a fancy string!")
]See what code this expression would generate!
Note - Check out the Elm.ToString module if this doesn't quite meet your needs!
Sometimes you may need to add a manual type annotation.
import Elm.Annotation as Type
Elm.value "myString"
|> Elm.withType Type.stringThough be sure elm-codegen isn't already doing this automatically for you!
Elm.record
[ ( "name", Elm.string "Elm" )
, ( "designation", Elm.string "Pretty fabulous" )
]record
|> Elm.get "field"results in
record.fieldmyRecord
|> updateRecord
[ ( "designation", Elm.string "Pretty fabulous" )
]Results in
{ myRecord | designation = "Pretty fabulous" }ifThen (Elm.bool True)
(Elm.string "yes")
(Elm.string "no")Will generate
if True then
"yes"
else
"no"If you need more than one branch, then chain them together!
Elm.ifThen (Elm.bool True)
(Elm.string "yes")
(Elm.ifThen (Elm.bool True)
(Elm.string "maybe")
(Elm.string "no")
)Will generate
if True then
"yes"
else if True then
"maybe"
else
"no"Renders a multiline comment.
Elm.comment """Here is my comment!"""Will generate
{- Here is my comment! -}Add a documentation comment to a declaration!
By default, everything is exposed for your module.
However, you can tag specific declarations you want exposed, and then only those things will be exposed.
You can also add a group tag to an exposed value. This will automatically group the docs statements in the module docs.
For precise control over what is rendered for the module comment, use fileWith.
Same as file, but you have more control over how the module comment is generated!
Pass in a function that determines how to render a @docs comment.
Each exposed item is grouped based on the string used in exposeWith.
aliases allow you to specify a module alias to be used.
Elm.fileWith [ "MyModule" ]
{ docs = List.map Elm.docs
, aliases =
[ ( [ "Json", "Encode" ], "Encode" )
]
}
[-- whatever declarations you desire.
]would make an import statement like
import Json.Encode as EncodeAll values rendered in this file that are from this module would also automatically respect this alias as well.
Render a standard docstring.
@docs one, two, threeIf a group has been given, it will be rendered as a second level header.
## Group name
@docs one, two, threeCreate a function with a single argument.
This may seem a little weird the first time you encounter it, so let's break it down.
Here's what's happening for the fn* functions —
String arguments are the names of the arguments for the generated function.Maybe Annotation is the type annotation. If you provide Nothing, then elm-codegen will infer the type for you!(Expression -> Expression) function is where we're providing you an Expression that represents an argument coming in to the generated function.So, this
Elm.fn ( "firstInt", Nothing )
(\firstArgument ->
Elm.plus
(Elm.int 42)
firstArgument
)Generates
\firstInt -> 42 + firstIntIf you want to generate a top level function instead of an anonymous function, use Elm.declaration.
Elm.declaration "add42" <|
Elm.fn ( "firstInt", Nothing )
(\firstArgument ->
Elm.plus
(Elm.int 42)
firstArgument
)Results in
add42 : Int -> Int
add42 firstInt =
42 + firstIntNote — Elm CodeGen will protect variable names if they're used in a nested fn* by adding a string of numbers to the end of the name. So, you may see a variable name be something like myVariable_0_1.
If you absolutely don't want this behavior, you'll need to use functionAdvanced.
You may run into situations where you don't know the number of arguments for a function at compile-time.
In that case you can use function. It follows the same pattern as the fn* functions.
Provide it with —
Expressions.This is a special case of function declaration which will reduce itself if possible.
Meaning, if this would generate the following code
\myArg -> someOtherFunction myArgThen it will replace itself with just
someOtherFunctionNote you likely won't need this! It's generally used by the package-helper generator, but that might be a relatively special case.
A custom type declaration.
Elm.customType "MyType"
[ Elm.variant "One"
, Elm.variantWith "Two"
[ Elm.Annotation.list Elm.Annotation.string ]
]Will result in
type MyType
= One
| Two (List String)A type alias declaration.
import Elm.Annotation as Type
Elm.alias "MyAlias"
(Type.record
[ ( "one", Type.string )
, ( "two", Type.int )
, ( "three", Type.var "content" )
]
)Should result in
type alias MyAlias content =
{ one : String
, two : Int
, three : content
}import Elm.Annotation as Type
Elm.portIncoming "receiveMessageFromTheWorld"
[ Type.string
, Type.int
]Results in
port receiveMessageFromTheWorld :
(String -> Int -> msg)
-> Sub msgNote You generally only need one incoming and one outgoing port!
If you want to vary the messages going in and out of your app, don't use a huge number of ports, instead write Json encoders and decoders.
This will give you more flexibility in the future and save you having to wire up a bunch of stuff.
Another note - You may need to expose your port explicitly using Elm.expose.
Create a port that can send messages to the outside world!
import Elm.Annotation as Type
Elm.portOutgoing "tellTheWorld" Type.stringwill generate
port tellTheWorld : String -> Cmd msgThis will insert the given string into your generated file.
Check out the using packages/helpers guide. If you're reaching for this, it's likely you'd be better off using a local helper file!
Unwraps a single-variant type
Elm.declaration "myFunction" <|
Elm.fn "val"
(\val ->
Elm.unwrap "MyType" val
)Results in the following lambda
myFunction val =
(\(MyType val) -> val) valGenerate a lambda which unwraps a single-variant type.
Elm.unwrapper [ "MyModule" ] "MyType"Results in the following lambda
\(MyModule.MyType val) -> val