Pro elm tips to write code like a pro
designed using https://crello.com
The using elm in production involves teaching and learning. This article comprises of 10 killer pro elm tips that you may or may not know.
0001 — type alias as a function
The type
aliases can be used as functions to construct a new value.
> type alias User = { name: String, age: Int }
> user = User "john" 23
{ name = "john", age = 23 } : Repl.User
> user
{ name = "john", age = 23 } : Repl.User
You have to just pass the initial values in the order of the type alias definition.
0010 — calling infix functions
In elm
, almost everything is a function
or can act like a function
.
The addition operation in elm
is just a function call using +
. The definition of the +
is like
(+) : number -> number -> number
The type
specs clearly tell you that it takes two
number
parameters and returns a number
. The way of calling this function is different because it is Infix function.
Infix functions are the functions whose name is in between the parameters. The left side parameter is passed as the first parameter and the right parameter is passed as the second parameter.
example: 1+2
In the above example, +
is the function name and 1,2
are its parameters where 1
is the first parameter and 2
is the second parameter.
You can also call the infix function by wrapping function name inside the parenthesis ()
like (+)
.
> (+) 1 2
3 : number
-- which is the same as calling
> 1 + 2
3: number
0011 — function composition
As you know elm
is everywhere functions
. You can combine functions to form another function using >>
> wordCount = String.words >> List.length
<function> : String -> Int
> wordCount " Medium is full of knowledge resources"
6 : Int
The wordCount
function takes String as input and returns Int
. The passed String values passed to String.words
which in return gives the List String
is again passed to List.length
which gives Int
value.
This is pretty useful.
0100 — point free
This point-free style coding is where you omit one or more arguments in the body of the function.
To understand this concept, look at the following examples.
Here I am trying to write a function named double which doubles the given value.
> double num = num * 2
<function> : number -> number
> double 5
10 : number
Here, you can omit the argument num
You can do magic like
> double = (*) 2
<function> : number -> number
> double 5
10 : number
> plus = (+)
<function> : number -> number -> number
> plus 5 5
10 : number
0101 — special function for tuple creation
In elm , you can use the (,)
. This is a special function used to create tuples. The magic is, it allows you to use as many ,
inside the ()
.
E.g (,,)
constructs a 3-tuple and (,,,)
a 4-tuple.
Check the following examples to understand this more
> (,) "apple" "banana"
("apple","banana") : ( String, String )
> (,,) "apple" 12 "banana"
("apple",12,"banana") : ( String, number, String )
> (,,,) 1 2 3 4
(1,2,3,4) : ( number, number1, number2, number3 )
For N , you have to give N+1 args
You can use as many commas as you want. The ,
will act as an infix function where the function name is between the two args.
0110 — Special notation in the function definition to pattern match
Consider you have a record model with following content
> model = {name = { firstName = "john", lastName = "ankanna"}, age = 23}
{ name = { firstName = "john", lastName = "ankanna" }, age = 23 }
: { age : number, name : { firstName : String, lastName : String } }
If you observe the model, it has nested record name with firstName
, lastName
.
Suppose, you need to update the firstName field inside the model then you can do pattern match over parameters like following.
> updateFirstName ({name} as model)= {model | name = {name | firstName = "joe"}}
<function>
: { c | name : { b | firstName : a } }
-> { c | name : { b | firstName : String } }
The {name} as model
is a pattern matched here.
Now, you simple pass the defined model
to the function updateFirstName
to update firstName
field inside name
.
>updateFirstName model
{ name = { firstName = "joe", lastName = "ankanna" }, age = 23 }
: { age : number, name : { lastName : String, firstName : String } }
0111 — unit type ()
A unit type is a type that allows only one value and thus can hold no information. Sometimes it is also referred to as the type of 0-tuples.
It is denoted by ()
and its value is same ()
.
> void = ()
() : () -- value : type are same here
Read unit type
1000 — <| operator
This <|
has lower precedence than function expression.
The f(g(h(x))) can be written as f <| g <| h x
Check the following example
> add10 = (+) 10
<function> : number -> number
> mul10 = (*) 10
<function> : number -> number
> 10 |> mul10 |> add10
110 : number
> mul10 <| add10 <| 10
200 : number
Let us do some crazy stuff
>add = (+)
<function> : number -> number -> number
> 10 |> (add <| 10)
20 : number
> (10 |> add) <| 10
20 : number
> 10 |> add <| 10
-- SYNTAX PROBLEM -------------------------------------------- repl-temp-000.elm
Conflicting associativity for binary operators (|>, <|). Consider adding
parentheses to disambiguate.
1001 — pattern match a list with at least elements
If you want to match a list with at least two items inside the list you can take the advantage of ::
.
a :: b :: rest
Implementation
For an example, you have to return [] if the list has items less than 2 or else you have to return the rest of the list.
- input: [1,2,3,4,5] output: [3,4,5]
- input: [1] output:[]
import Html exposing (text)
rest list =
case list of
a :: b :: rest -> --this matches list with at least two items
rest
_ ->
[]
main =
text <| toString <| rest [1,2,3,4,5] -- returns [3,4,5]
import Html exposing (text)
rest list =
case list of
a :: b :: rest -> --this matches list with at least two items
rest
_ ->
[]
main =
text <| toString <| rest [1] -- returns []
1010 — Similar => function in elm
> add1 = \n -> n +1
<function> : number -> number
> add1 5
6 : number
Hope you have enjoyed the whole context.
Feel free to share and let others get benefited from you.
Happy Long Coding life :)
Top comments (0)