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

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 ]).

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

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

  • jacek

    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?

  • Yan Cui

    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.