Erlang: elegant tuple_to_list/1 - functional-programming

I'm getting myself introduced to Erlang by Armstrongs "Programming Erlang". One Exercise is to write a reeimplementation of the tuple_to_list/1 BIF. My solution seems rather inelegant to me, especially because of the helper function I use. Is there a more Erlang-ish way of doing this?
tup2lis({}) -> [];
tup2lis(T) -> tup2list_help(T,1,tuple_size(T)).
tup2list_help(T,Size,Size) -> [element(Size,T)];
tup2list_help(T,Pos,Size) -> [element(Pos,T)|tup2list_help(T,Pos+1,Size)].
Thank you very much for your ideas. :)

I think your function is ok, and more if your goal is to learn the language.
As a matter of style, usually the base case when constructing lists is just the empty list [].
So I'd write
tup2list(Tuple) -> tup2list(Tuple, 1, tuple_size(Tuple)).
tup2list(Tuple, Pos, Size) when Pos =< Size ->
[element(Pos,Tuple) | tup2list(Tuple, Pos+1, Size)];
tup2list(_Tuple,_Pos,_Size) -> [].
you can write pretty much the same with list comprehension
[element(I,Tuple) || I <- lists:seq(1,tuple_size(Tuple))].
it will work as expected when the tuple has no elements, as lists:seq(1,0) gives an empty list.

Your code is good and also idiomatic way how to make this sort of stuff. You can also build this list backward which in this case will be a little bit faster because of tail call but not significant.
tup2list(T) -> tup2list(T, size(T), []).
tup2list(T, 0, Acc) -> Acc;
tup2list(T, N, Acc) -> tup2list(T, N-1, [element(N,T)|Acc]).

I am attempting exercises from Joe Armstrong book, Here is what I came up with
my_tuple_to_list(Tuple) -> [element(T, Tuple) || T <- lists:seq(1, tuple_size(Tuple))].

In Erlang R16B you can also use erlang:delete_element/2 function like this:
tuple2list({}) -> [];
tuple2list(T) when is_tuple(T) ->
[element(1, T) | tuple2list(erlang:delete_element(1, T))].

Strangely enough I'm learning this right now using the same book by Joe Armstrong the second edition and Chapter 4 is about modules and functions which covers List Comprehension, Guards, Accumulators etc. Anyways using this knowledge my solution is the code below :
-module(my_tuple_to_list).
-export([convert/1]).
convert(T) when is_tuple(T) -> [element(Pos,T) || Pos <- lists:seq(1,tuple_size(T))].
Most of the answers were already given in the same way mine just adds the Guard to ensure that a Tuple was given.

Erlang 17.0, you should build list in natural order, solutions above is incorrect from the point of efficiency. Always add elements to the head of an existing list:
%% ====================================================================
%% API functions
%% ====================================================================
my_tuple_to_list({}) ->
[];
my_tuple_to_list(Tuple) ->
tuple_to_list_iter(1, size(Tuple), Tuple, [])
.
%% ====================================================================
%% Internal functions
%% ====================================================================
tuple_to_list_iter(N, N, Tuple, List) ->
lists:reverse([element(N, Tuple)|List]);
tuple_to_list_iter(N, Tuplesize, Tuple, List) ->
L = [element(N, Tuple)|List],
tuple_to_list_iter(N + 1, Tuplesize, Tuple, L)
.

mytuple_to_list(T) when tuple_size(T) =:= 0 -> [];
mytuple_to_list(T) -> [element(1, T)|mytuple_to_list(erlang:delete_element(1, T))].

Related

Does this code have a mistake?

I am just reading about syntax of Erlang, and read this implementation of while loop:
-module(helloworld).
-export([while/1,while/2, start/0]).
while(L) -> while(L,0).
while([], Acc) -> Acc;
while([_|T], Acc) ->
io:fwrite("~w~n",[Acc]),
while(T,Acc+1).
start() ->
X = [1,2,3,4],
while(X).
Is the semicolon a mistake? (4th line: while([], Acc) -> Acc;)
I would write the two functions like this:
while(L) -> while(L,0).
while([], Acc) -> Acc;
while([_|T], Acc) ->
io:fwrite("~w~n",[Acc]),
while(T,Acc+1).
start() ->
X = [1,2,3,4],
while(X).
Using whitespace to separate the function definitions makes it clear that two different functions are being defined: while/1 and while/2.
I had no idea about [_|T]. It just comes after this part in the
tutorial, so that's very confusing.
That's nearly equivalent to [H|T], which deconstructs a list into the Head and the Tail, where the Head is the first element of a list and the Tail is the rest of the list. The variable name _ means that you don't care about the variable, so you will not use it in the function body. In this case, it means that you don't care about the Head of the list, all you want is the Tail of the list. If a named variable is used in the head of a function clause, and you don't use the variable in the body of the function, then the compiler will give you a warning.
Here's an example of how deconstructing a list with pattern matching works:
-module(my).
-compile(export_all).
f([Head|Tail]) ->
io:format("The head of the list is: ~w~n", [Head]),
io:format("The tail of the list is: ~w~n", [Tail]).
In the shell:
8> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}
9> my:f([1, 2, 3]).
The head of the list is: 1
The tail of the list is: [2,3]
ok
10>
No. There are two functions defined here: while/1 (one argument) and while/2 (two arguments). The second one have two function bodies; which one to use is decided through pattern matching.

"Subsetting" a dictionary in F#

I'm a beginner in F# and I'm trying to write a function to subset a dictionary given list, and return the result.
I tried this, but it doesn't work.
let Subset (dict:Dictionary<'T,'U>) (sub_list:list<'T>) =
let z = dict.Clear
sub_list |> List.filter (fun k -> dict.ContainsKey k)
|> List.map (fun k -> (k, dict.TryGetValue k) )
|> List.iter (fun s -> z.Add s)
|> List.iter (fun s -> z.Add s);;
--------------------------------------^^^
stdin(597,39): error FS0039: The field, constructor or member 'Add' is not defined
Perhaps there is a native function in F# to do that ?
thanks
EDIT
thanks to #TheInnerLight for his answer below
can you just educate me a bit more, and tell me how i should adapt that function if i want to return the original variable being modified ?
(of course it would be possible to go from where we call that function, call it with a temp variable, and reassign)
You have written:
let z = dict.Clear
z is of type unit->unit yet you are calling z.Add.
I suspect you want to write
let subset (dict:Dictionary<'T,'U>) (sub_list:list<'T>) =
let z = Dictionary<'T,'U>() // create new empty dictionary
sub_list |> List.filter (fun k -> dict.ContainsKey k)
|> List.map (fun k -> (k, dict.[k]) )
|> List.iter (fun s -> z.Add s)
z
TryGetValue is going to return something of type bool*'U in F#, which I suspect you don't want if already filtering by ContainsKey so you probably want to look up directly with dict.[k].
Note that Dictionary is a mutable collection so if you were to actually call dict.Clear(), it wouldn't return a new empty dictionary, it would mutate the existing one by clearing all elements. The immutable F# data structure usually used for key-value relationships is Map, see https://msdn.microsoft.com/en-us/library/ee353880.aspx for things you can do with Map.
Here is a map version (this is the solution I recommend):
let subset map subList =
subList
|> List.choose (fun k -> Option.map (fun v -> k,v) (Map.tryFind k map))
|> Map.ofList
Edit (in response to the question edit about modifying the input variable):
It's possible to update an existing dictionary using the destructive update operator <- on a mutable variable.
Option 1:
let mutable dict = Dictionary<Key,Value>() // replace this with initial dictionary
let lst = [] // list to check against
dict <- sublist dict lst
Likewise, my first function could be changed to perform only a side effect (removing unwanted elements).
Option 2:
let subset (d : System.Collections.Generic.Dictionary<'T,'U>) (sub_list : list<'T>) =
sub_list
|> List.filter (d.ContainsKey >> not)
|> List.iter (d.Remove >> ignore)
For an F# beginner I don't really recommend Option 1 and I really don't recommend Option 2.
The functional approach is to favour immutable values, pure functions, etc. This means you will be better off thinking of your functions as defining data transformations rather than as defining a list of instructions to be performed.
Because F# is a multi-paradigm language, it's easy to fall back on the imperative in the early stages but you will probably gain the most from learning your new language if you force yourself to adopt the standard paradigm and idioms of that language even if those idioms feel strange and uncomfortable to begin with.
The immutable data structures like Map and list are pretty efficient at sharing data as well as providing good time complexity so these are really the go-to collections when working in F#.

The API design philosophy in OCaml

After learning OCaml for like half year, I am still struggling at the functional programming and imperative programming bits.
It is not about using list or array, but about API design.
For example, if I am about to write stack for a user, should I present it in functional or imperative way?
stack should have a function called pop, which means return the last element to user and remove it from the stack. So if I design my stack in functional way, then for pop, I should return a tuple (last_element, new_stack), right? But I think it is ugly.
At the same time, I feel functional way is more natural in Functional Programming.
So, how should I handle this kind of design problem?
Edit
I saw stack's source code and they define the type like this:
type 'a t = { mutable c : 'a list }
Ok, internally the standard lib uses list which is immutable, but the encapsulate it in a mutable record.
I understand this as in this way, for the user, it is always one stack and so no need for a tuple to return to the client.
But still, it is not a functional way, right?
Mutable structures are sometimes more efficient, but they're not persistent, which is useful in various situations (mostly for backtracking a failed computation). If the immutable interface has no or little performance overhead over the mutable interface, you should absolutely prefer the immutable one.
Functionally (i.e. without mutability), you can either define it exactly like List by using head/tail rather than pop, or you can, as you suggest, let the API handle state change by returning a tuple. This is comparable to how state monads are built.
So either it is the responsibility of the parent scope to handle the stack's state (e.g. through recursion), in which case stacks are exactly like lists, or some of this responsibility is loaded to the API through tuples.
Here is a quick attempt (pretending to know O'Caml syntax):
module Stack =
struct
type 'a stack = 'a list
let empty _ = ((), [])
let push x stack = ((), x::stack)
let pop (x::stack) = (x, stack)
| pop _ = raise EmptyStack
end
One use case would then be:
let (_, st) = Stack.empty ()
let (_, st) = Stack.push 1 Stack.empty
let (_, st) = Stack.push 2 st
let (_, st) = Stack.push 3 st
let (x, st) = Stack.pop st
Instead of handling the tuples explicitly, you may want to hide passing on st all the time and invent an operator that makes the following syntax possible:
let (x, st) = (Stack.empty >>= Stack.push 1 >>=
Stack.push 2 >>= Stack.push 3 >>= Stack.pop) []
If you can make this operator, you have re-invented the state monad. :)
(Because all of the functions above take a state as its curried last argument, they can be partially applied. To expand on this, so it is more apparent what is going on, but less readable, see the rewrite below.)
let (x, st) = (fun st -> Stack.empty st >>= fun st -> Stack.push 1 st
>>= fun st -> Stack.push 2 st
>>= fun st -> Stack.push 3 st
>>= fun st -> Stack.pop) []
This is one idiomatic way to deal with state and immutable data structures, at least.

Counting nodes in a Tree

fighting with f# - the fight is in the realm of Trees - specifically to count the number of nodes. This is of real interest as the program I would like to eventually code in F# concerns multi-way trees, unfortunately it has got off to a bit of a troublesome start - I hope you maybe able to help!
Problem 61 of the 99 f# series, asks to count the leaves of a binary Tree. The solution (given below) counts the nodes, but my problem is not understanding
how the double recursion works loop left (fun lacc -> loop right..)
what cont (branchF x lacc racc) is, my impression was that cont was the "abc" function, but this takes only two parameters...
loop t id the id is of type unit - i don't see how this is implied
basically not understanding this, or the order in which it flows through the tree (debug & step through not proving helpful) If there are simpler examples, pre-reading recommendations etc. then please direct me to them.
Many thanks for any help, the solution code in question is below:
Cheers
td
type 'a Tree = Empty | Branch of 'a * 'a Tree * 'a Tree
let foldTree branchF emptyV t =
let rec loop t cont =
match t with
| Empty ->
cont emptyV
| Branch (x, left, right) ->
loop left (fun lacc ->
loop right (fun racc ->
cont (branchF x lacc racc)))
loop t id
let counLeaves tree =
foldTree (fun abc lc rc ->
if lc + rc = 0 then 1
else 1 + lc + rc) 0 tree
let Tree1 = Branch ('x', Branch ('x', Empty, Empty),Branch ('x', Empty, Branch ('x', Empty, Branch ('x', Empty, Empty))))
let result = counLeaves Tree1
As the name implies, foldTree defines the fold function over the custom Tree type.
A naive way of defining a foldTree could be:
let rec foldTreeNaive accFun init = function
| Empty -> init
| Branch (x, left, right) ->
let lacc = foldTreeNaive accFun init left
let racc = foldTreeNaive accFun init right
accFun x lacc racc
The problem with this function is that it could potential make very deep recursive calls if the tree being folded over is deep, since the recursive calls must complete for a node before the accumulator function can be called. For example the following causes a stack overflow exception:
let unbalanced = [1..100000] |> List.fold (fun t i -> Branch(i, t, Empty)) Empty
let nodeCount = foldTreeNaive (fun _ lc rc -> lc + rc + 1) 0 unbalanced
The usual way to avoid such stack overflows is to make the function tail recursive, however this seems impossible in this case since there are two recursive calls to make, instead of the one required when folding over lists.
foldTree is defined using the local loop function. This function is interesting in that it is defined using continuation passing style. In CPS, each function takes an additional 'continuation' function which is passed the result of the computation and is responsible for deciding what happens next. Note that loop is tail recursive and so avoids the overflow problem of foldTreeNaive.
The type of the loop function is:
Tree<'a> -> ('b -> 'c) -> 'c
where 'a is the type of nodes in the tree, 'b is the accumulator type, and 'c is the result of the continuation function.
In the case of a leaf node, the continuation is passed the empty accumulator value passed to the foldTree function.
When folding over a non-empty tree in the Branch case, the result of the fold depends on the results for the left and right subtrees. This is done recursively, first by folding over the left subtree, then the right. For the recursive call over the left subtree, loop must build a new continuation to receive the result, this is the
(fun lacc ->
loop right (fun racc ->
cont (branchF x lacc racc))
function. What this continuation does is to make a recursive call over the right subtree, passing yet another continuation to receive the result of that fold. When that continuation is called, the results for the left and right subtrees are available in lacc and racc. At this point the accumulation function for the node can be called with the value for the current node and the results for the left and right subtrees. The result of this function is then passed to the original continuation passed to loop.
The loop function is then invoked by the foldTree function in the line:
loop t id
Here, id is the continuation which will receive the result of the fold for the root node of the tree. Since this is the value required, id just returns its argument without modification.
You might also find this description of fold for binary trees useful.

Erlang syntax for nested function with if

I've been looking around and can't find examples of this and all of my syntax wrestling skills are failing me. Can someone please tell me how to make this compile?? My ,s ;s or .s are just wrong I guess for defining a nested function...
I'm aware there is a function for doing string replaces already so I don't need to implement this, but I'm playing with Erlang trying to pick it up so I'm hand spinning some of the basics I need to use..
replace(Whole,Old,New) ->
OldLen = length(Old),
ReplaceInit = fun(Next, NewWhole) ->
if
lists:prefix(Old, [Next|NewWhole]) -> {_,Rest} = lists:split(OldLen-1, NewWhole), New ++ Rest;
true -> [Next|NewWhole]
end,
lists:foldr(ReplaceInit, [], Whole).
Basically I'm trying to write this haskell (also probably bad but beyond the point):
repl xs ys zs =
foldr replaceInit [] xs
where
ylen = length ys
replaceInit y newxs
| take ylen (y:newxs) == ys = zs ++ drop (ylen-1) newxs
| otherwise = y:newxs
The main problem is that in an if you are only allowed to use guards as tests. Guards are very restricted and, amongst other things, calls to general Erlang functions are not allowed. Irrespective of whether they are part of the OTP release or written by you. The best solution for your function is to use case instead of if. For example:
replace(Whole,Old,New) ->
OldLen = length(Old),
ReplaceInit = fun (Next, NewWhole) ->
case lists:prefix(Old, [Next|NewWhole]) of
true ->
{_,Rest} = lists:split(OldLen-1, NewWhole),
New ++ Rest;
false -> [Next|NewWhole]
end
end,
lists:foldr(ReplaceInit, [], Whole).
Because of this if is not used that often in Erlang. See about if and about guards in the Erlang documentation.

Resources