I am trying to learn Erlang and had gotten no further than operators when I ran into a problem:
5> TheList = [2,4,6,8].
[2,4,6,8]
6>
6> [N || N <- TheList, N rem 3 =:= 0].
[6]
7>
7> TheList.
[2,4,6,8]
8>
8> [2*N || N <- TheList, N rem 3 =:= 0].
"\f"
9>
Why do I get "\f" in the last operation? Shouldn't it be [12]? What does "\f" mean? Thanks.
It is explained here for example:
Erlang has no separate string type. Strings are usually represented by lists of integers (and the string module of the standard library manipulates such lists). Each integer represents the ASCII (or other character set encoding) value of the character in the string. For convenience, a string of characters enclosed in double quotes (") is equivalent to a list of the numerical values of those characters.
You can use io:format functions:
1> io:format("~w~n", [[2*N || N <- [2,4,6,8], N rem 3 =:= 0]]).
[12]
or disble this behaviour with shell:strings/1 function starting with Erlang R16B:
2> shell:strings(false).
true
3> [2*N || N <- [2,4,6,8], N rem 3 =:= 0].
[12]
As #Atomic_alarm has mentioned in the comment, it is due to erlang printing out the answer using string syntax rather than the list of integer. The default value is true, where as to see [12], you want the value set as false. The documentation for it is here.
Related
I'm currently trying to solve the following exercise:
Given a list of Ints, count the number of times, an element is greater than the element that comes after it. The exercise forces me not to use explicit recursions.
Here are some example outputs given function :: [Int] -> Int:
function [1, 2, 3, 4, 5] == 0 -- only increasing numbers
function [5, 4, 3, 2, 1] == 4 -- only decreasing numbers
function [2, 1, 3, 1, 0, 4] == 3
-- 2 > 1
-- 3 > 1
-- 1 > 0
function [1] == 0 -- no successor
function [ ] == 0 -- no numbers at all
I imagined to use in some way foldl but after many attempts and not working idea I had to give up.
How can I count the number of times an element is greater than its successor without using recursion?
First we need to pair up the consecutive elements,
foo :: [Int] -> Int
foo xs = result
where
pairs = zip xs (drop 1 xs)
then we can process each pair
biggers = [ () | (x,y) <- pairs, x > y]
and now we can count them,
result = .......
All the nested names belong to the same, shared, nested scope. result must make use of the value of biggers, and biggers refers to the value of pairs which refers to the value of foo's parameter, xs. Make sure to put these code lines into the same definition, all indented by the same amount as the first one, for pairs, one under the other.
Actually using a left fold is also possible:
foo (h:t) = snd ( foldl' (\ (a, !c) x -> (x, if (a > x) then (c+1) else c))
(h,0) t )
foo [] = 0
I think you'll agree though that this is much less self-apparent than the first definition. Also note that it uses a "bang pattern", !, together with foldl', not foldl, to do the counting as soon as possible as we go along the input list, not delaying it until all the input list is traversed in full as foldl would do, needlessly, harming the overall efficiency.
I have a tuple as {'Europe-Fiat-Italy-Warehouse'}.
Car = {'Europe-Fiat-Italy-Warehouse'}.
I want to search the string "Fiat" in the above tuple without converting them to string tokens in a list.
i.e.,
(madmax#erlang)46>string:tokens(atom_to_list(element(1, Car)), "-").
["Europe","Fiat","Italy","Warehouse"]
(madmax#erlang)46> ["Europe", "Fiat" | Other] =
string:tokens(atom_to_list(element(1, Car)), "-").
["Europe","Fiat","Italy","Warehouse"]
(madmax#erlang)47>
(madmax#erlang)47> Other.
["Italy","Warehouse"]
(madmax#erlang)48>
As in above, we convert tuple to atom, then atom to list and then list to string tokens. Is there any optimized way? or any Buit-in-Function available in erlang which make this task easier?
Use string:str
check documentation here: http://erlang.org/doc/man/string.html#str-2
it will return position of substring, zero if substring is not found.
string:str(atom_to_list(element(1, Car)), "Fiat")
the representation of atoms in memory is not using strings (or list), to search in an atom name there is no other choice than convert it into list first. It is possible to use library function such as string:str/2, but you may have bad results since string you search could be part of a longer one, so you should keep the call to string:token/2, then it depends of what you want to do:
1> Car = {'Europe-Fiat-Italy-Warehouse'}.
{'Europe-Fiat-Italy-Warehouse'}
2> Words = string:tokens(atom_to_list(element(1, Car)), "-").
["Europe","Fiat","Italy","Warehouse"]
3> lists:member("Fiat",Words). % only a test
true
4> lists:dropwhile(fun(X) -> "Fiat" =/= X end ,Words). % words after
["Fiat","Italy","Warehouse"]
5> lists:takewhile(fun(X) -> "Fiat" =/= X end ,Words). % words before
["Europe"]
6> lists:member("Fit",Words). % same thing with a bad match
false
7> lists:dropwhile(fun(X) -> "Fit" =/= X end ,Words).
[]
8> lists:takewhile(fun(X) -> "Fit" =/= X end ,Words).
["Europe","Fiat","Italy","Warehouse"]
9>
I have a list of lists (in erlang, strings are lists) which looks like this:
["abc","def"]
and I would like to get the following combinations in a list returned by a function:
["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]
Is it possible with list-comprehension? I don't know the dimension of the list beforehand
If you don't know the dimension of the input, then you need to use recursion as #legoscia said:
cartesian([H]) -> [[A] || A <- H];
cartesian([H|T]) -> [[A|B] || A <- H, B <- cartesian(T)].
A 1-dim input "abc" is turned into ["a", "b", "c"], everything else is recursion.
> cartesian:cartesian(["abc", "def", "ghi"]).
["adg","adh","adi","aeg","aeh","aei","afg","afh","afi",
"bdg","bdh","bdi","beg","beh","bei","bfg","bfh","bfi","cdg",
"cdh","cdi","ceg","ceh","cei","cfg","cfh","cfi"]
Edit: Or easier, yet: Let a 0-dim argument return the set that contains the empty set. I think that's what a mathematician would do, too.
cartesian([H|T]) -> [[A|B] || A <- H, B <- cartesian(T)];
cartesian([]) -> [[]].
If you have exactly two lists, then you can do it with a list comprehension like this:
1> [[X,Y] || X <- "abc", Y <- "def"].
["ad","ae","af","bd","be","bf","cd","ce","cf"]
If you have an arbitrary number of lists, you could do it with a list comprehension inside a recursive function.
Here is my problem: Declare type and define a function that takes two numbers m and n as input and returns a list containing the doubled values of all odd integers between m and n. For instance, fun 2 11 would return [6, 10, 14, 18, 22].
I don't know how I can take the two number 2 and 11 and make it into a list [2..11]. Does anyone know how to do this?
Use sequence generation (range syntax):
Prelude> [2 .. 11]
[2,3,4,5,6,7,8,9,10,11]
Works for symbolic values, too:
Prelude> let [m,n] = [2,11]
Prelude> [m .. n]
[2,3,4,5,6,7,8,9,10,11]
Didn't work with Haskell for almost two years, so correct me if I'm wrong and it doesn't work:
getDoubledOdd :: Int -> Int -> [Int]
getDoubledOdd m n = map (2*) $ filter odd [m..n]
A combination of list comprehension and range would be the most standard way to do it.
[ 2*x | x <- [2..11], odd x ]
The code basically says "let x loop from 2 to 11 (x <- [2..11]), and if x is odd (odd x), put 2*x into the list that will be returned".
Hope that explains.
This might be a strange question but if I want to define a list of integers from:
1, 2, 3, 4, 5, 6, 7, 8, 9
Do I need to do it using the ; character?
[ 1; 2; 3; 4; 5; 6; 7; 8; 9 ]
instead of?:
[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
It just seems to me , is more natural and easy on the eyes. Just wondering the idea behind using ;? (Not criticizing)
Yes you must. The reason why is that in F# the comma operator is used for tuple expressions. So the expression 1,2,...9 is interpreted as a single tuple with 9 values.
[1,2] // List with 1 element that is a tuple value - (int*int) list
[1;2] // List with 2 elements that are integer values - int list
Other answers have pointed out the main reason.
As an aside it is worth noting that, like most other places that semicolon is used in the language, an alternative is a newline. For example
[ "foo"; "bar"; "baz" ]
can also be written as
[ "foo"
"bar"
"baz" ]
or a variety of other layouts where semicolons are replaced by newlines.
[1,2,3,4,5] is a list of 1 element of type int * int * int * int * int
[1;2;3;4;5] is a list of 5 elements of type int
also, list comprehensions and ranges are your friends
let bar = [1..9], 1..9 is a range so it get's unfolded into 1;2;3;...9;
let blort = [for i in 1..9 -> i] is a comprehension that does the same thing -- a little more power for some performance issues.
Edit: for completeness sake, you can also do
let foo = [1
2
3]
and get a list of [1;2;3]
Just wondering the idea behind using ;?
Tuples are more common in ML and using ; lets you write lists of tuples as:
[1, 2; 3, 4]
Historically, F# inherited this syntax from OCaml which created its syntax by trying to remove more superfluous parentheses from Standard ML syntax.