What does this F# code look like in Erlang – Part 4 of N

Yan Cui

I help clients go faster for less using serverless technologies.

This article is brought to you by

Hookdeck: The Serverless Event Gateway

Hookdeck is a reliable and scalable serverless event gateway for sending, receiving, authenticating, transforming, filtering, and routing events between services in your event-driven architecture.

Learn more

Related Posts

 

Here I will look at how some commonly used functions in F#’s List module might be translated to Erlang using Erlang’s equivalent – the lists module.

 

List.append

F#:         let newList = List.append [ 1..5 ] [ 6..10 ]

Erlang:   NewList = lists:append([ 1, 2, 3, 4, 5 ], [ 6, 7, 8, 9, 10 ]).

List.average

F#:         let avg = List.average [ 1.0..10.0 ]

Erlang:   List = lists: seq(1, 10).

             Avg = lists: sum(List) / length(List).

List.collect

F#:         let duped = [ ‘a’; ‘b’; ‘c’ ] |> List.collect (fun x -> [ x; x ])

Erlang:   Duped = lists:flatmap(fun(X) –> [ X, X ] end, [ a, b, c ]).

List.concat

F#:         let newList = List.concat [ [ 1; 2 ]; [ 3; 4; 5 ]; [ 6; 7; 8; 9 ] ]

Erlang:   NewList = lists:append([ [ 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8, 9 ] ]).

 

List.exists

F#:         let hasEven = [ 1..2..9 ] |> List.exists (fun x -> x % 2 = 0)

Erlang:   HasEven = lists:any(fun(X) -> X rem 2 =:= 0 end, lists: seq(1, 9, 2)).

 

List.filter

F#:         let evens = [ 1.. 6 ] |> List.filter (fun x -> x % 2 = 0)

Erlang:   Evens = lists:filter(fun(X) -> X rem 2 =:= 0 end, lists:seq(1, 6)).

 

List.find

F#:         let fstMatch = [ "cui"; "xue"; "yan" ] |> List.find ((=) "yan")

Erlang:   FstMatch = lists:keyfind(yan, 1, [ { cui }, { xue }, { yan } ]).

 

List.fold

F#:         let data = [ ("Cats", 4); ("Dogs", 5); ("Mice", 3); ("Elephants", 2) ]

              let count = data |> List.fold (fun acc (_, x) -> acc + x) 0

Erlang:   Data = [ { cats, 4 }, { dogs, 5 }, { mice, 3 }, { elephants, 2 } ].

             Count = lists:foldl(fun({ _, N }, Acc) -> Acc + N end, 0, Data).

 

List.foldBack

F#:         let copy = List.foldBack (fun elem acc -> elem::acc) [ 1..10 ] []

Erlang:   Copy = lists:foldr(fun(X, Acc) -> [X|Acc] end, [], lists:seq(1, 10)).

 

List.forall

F#:         let allEven = [2; 4; 6; 8] |> List.forall (fun n -> n % 2 = 0)

Erlang:   AllEven = lists:all(fun(X) -> X rem 2 =:= 0 end, [ 2, 4, 6, 8 ]).

 

List.iter

F#:         [1..10] |> List.iter (printfn "%d")

Erlang:   lists:foreach(fun(X) -> io:format("~p~n", [ X ]) end, lists:seq(1, 10)).

 

List.length

F#:         let lst = [ 1..10 ]

              // you can call the Length property on a list

              let len1 = lst.Length

              // or use List.length

              let len2 = List.length lst

Erlang:   Lst = lists: seq(1, 10).

             % you can use the length built-in function

             Len1 = length(Lst).

             % or you can use lists:flatlength

             Len2 = lists:flatlength(Lst).

 

List.map

F#:         let doubles = [ 1..10 ] |> List.map (fun x -> x * 2)

Erlang:   Doubles = lists:map(fun(X) -> X * 2 end, lists:seq(1, 10)).

 

List.max

F#:         let max = [ 1..10 ] |> List.max

Erlang:   Max = lists:max(lists: seq(1, 10)).

 

List.min

F#:         let min = [ 1..10 ] |> List.min

Erlang:   Min = lists:min(lists: seq(1, 10)).

 

List.nth

F#:         let fourth = List.nth [ 1..10 ] 3

Erlang:   Fourth = lists:nth(4, lists: seq(1, 10)). % node that n is not zero-indexed here!

 

List.partition

F#:         let evens, odds = [ 1..10 ] |> List.partition (fun n -> n % 2 = 0)

Erlang:   { Evens, Odds } = lists:partition(fun(X) -> X rem 2 =:= 0 end, lists:seq(1, 10)).

 

List.rev

F#:         let rev = [ 1..10 ] |> List.rev

Erlang:   Rev = lists:reverse(lists: seq(1, 10)).

 

List.sort

F#:         let sorted = List.sort [ 1; 4; 7; -1; 5 ]

Erlang:   Sorted = lists:sort([ 1, 4, 7, -1, 5 ]).

 

List.sum

F#:         let sum = List.sum [ 1..10 ]

Erlang:   Sum = lists:sum(lists:seq(1, 10)).

 

List.unzip

F#:         let lstA, lstB = List.unzip [ (1, 2); (3, 4) ]

Erlang:   { LstA, LstB } = lists:unzip([ {1, 2}, {3, 4} ]).

 

List.zip

F#:         let lst = List.zip [ 1; 2 ] [ 3; 4 ]

Erlang:   Lst = lists:zip([ 1, 2 ], [ 3, 4 ]).

Whenever you’re ready, here are 4 ways I can help you:

  1. Production-Ready Serverless: Join 20+ AWS Heroes & Community Builders and 1000+ other students in levelling up your serverless game. This is your one-stop shop for quickly levelling up your serverless skills.
  2. Do you want to know how to test serverless architectures with a fast dev & test loop? Check out my latest course, Testing Serverless Architectures and learn the smart way to test serverless.
  3. I help clients launch product ideas, improve their development processes and upskill their teams. If you’d like to work together, then let’s get in touch.
  4. Join my community on Discord, ask questions, and join the discussion on all things AWS and Serverless.

4 thoughts on “What does this F# code look like in Erlang – Part 4 of N”

  1. Pingback: What does this F# code look like in Erlang – Part 2 of N | theburningmonk.com

  2. Pingback: What does this F# code look like in Erlang – Part 1 of N | theburningmonk.com

  3. So… there is no easy alternative to F# sequences in Erlang… In F#, using a simple seq/yield syntax, I can generate zillions of records in O(1) memory. Is it possible to do in Erlang?

  4. Erlang lists are eagerly evaluated (same as F#) and it doesn’t have a built-in seq module. But it’s easy to write one yourself, for example – http://stackoverflow.com/a/193804 but of course you lose the syntactic sugar F#’s seq/yield gives you, and you’d have to reinvent the composability story yourself – map, filter, etc.

    Generally speaking the Erlang language designers have never been big on syntactic sugar for the better or worse..

    However, if you’re interested in Erlang’s runtime characteristics but want to code with a modern language, then you might be interested in Elixir http://elixir-lang.org/. It’s built on top of the Erlang VM so inherits its runtime characteristics and OTP abstractions (supervision, gen_server, etc.). It marries them with modern language features (it even borrowed F#’s pipe idiom ;-)), it’s homoiconic, and for what you’re looking for it has the Stream type – http://elixir-lang.org/docs/v1.0/elixir/Stream.html. Oh, it’s got a pretty great tooling story too, which is another pain point people always run into with Erlang.

Leave a Comment

Your email address will not be published. Required fields are marked *