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.

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 3 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.
  2. Consulting: If you want to improve feature velocity, reduce costs, and make your systems more scalable, secure, and resilient, then let’s work together and make it happen.
  3. Join my FREE Community on Skool, where you can ask for help, share your success stories and hang out with me and other like-minded people without all the negativity from social media.

 

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 *