I need to convert Elixir function into Erlang function:
In Elixir I have:
Enum.map(0..n, fn i-> fun(i) end)
And I need to re-write to Erlang.
Any Idea? Thanks
Erlang doesn't have a single generic function that can handle mapping over any data structure like Enum.map in Elixir. The simplest way to do this would be to use lists:seq to generate the list and lists:map:
1> lists:map(fun(X) -> X * X end, lists:seq(0, 10)).
[0,1,4,9,16,25,36,49,64,81,100]
Using list comprehensions:
[ F(X) || X <- lists:seq(0, 10) ].
aka
[ X*X || X <- lists:seq(0, 10) ].
Related
I have checked the erlang websites operators etc but i cannot find what || and | Means.
I read somewhere that || means "such that" but what does just one " | " mean?
| is the "cons" operator: It puts an element in front of a list:
1> [1 | [2,3]].
[1,2,3]
2> [[1, 2] | [3,4,5]].
[[1,2],3,4,5]
|| is used in list-comprehensions. In its simplest form, it can be used as a short-hand for map:
3> [2 * X || X <- [1,2,3]].
[2,4,6]
But it becomes much more handy when you want to write multiple generators, creating the cartesian product:
4> [{X, Y} || X <- [1,2,3], Y <- [4, 5, 6]].
[{1,4},{1,5},{1,6},{2,4},{2,5},{2,6},{3,4},{3,5},{3,6}]
You can also do filter along the way. Compare:
5> [X+Y || X <- [1,2,3], Y <- [4,5,6]].
[5,6,7,6,7,8,7,8,9]
to:
6> [X+Y || X <- [1,2,3], Y <- [4,5,6], X+Y > 6].
[7,7,8,7,8,9]
The | operator is essential, in the sense that it is the canonical way how you construct a new list out of an existing head element and a tail of the list. The same notation also works in pattern matching, i.e., it is also how you deconstruct a list.
On the other hand, list comprehensions are mostly syntactic sugar: They can be written using regular function applications and hence is not fundamental to the language. But they can significantly improve readability by getting rid of syntactic noise, mimicking set-comprehension like mathematical notation directly within the language.
As part of learning Erlang, one of the problems I am trying to solve is
Write a higher-order function filter(F, L), which returns all the
elements X in L for which F(X) is true.
I am new to functional programming and very confused with higher-order functions as well.
My attempt looks like
filter(F, L) -> [T || T <- L, F(T) =:= true].
2> IsEven = fun(X) -> X rem 2 =:= 0 end.
#Fun<erl_eval.6.90072148>
3> IsEven(2).
true
4> IsEven(3).
false
5> math_functions:filter(IsEven, lists:seq(1, 10)).
[2,4,6,8,10]
6> math_functions:filter(IsEven, lists:seq(1, 20)).
[2,4,6,8,10,12,14,16,18,20]
Question
Is this is really higher-order function? Please guide
I want be able to input the following:
fun([{X,Y}, {A,B}, {M,N}]).
and only use the first tuple and save the others for later use. I tried defining it like this:
fun([{X|Y}, V]) ->
V.
But I just get a syntax error before the "|". "V" was just to try and output to see what was happening.
Is there any resources I can be pointed towards for some support with this? Or am I doing something really wrong?
func([{X,Y}| V]) -> %% fun is a keyword, you cannot use it as a function name
%% do some stuff with X, Y
V.
generally, if you want to apply the same function to all element of a list, it is good to use the lists module: (lists:foreach/2, lists:map/2, lists:foldl/2 ...) or a list comprehension
Res = [Fun(T) || T <- L]
wher Fun is the function to apply to each tuple T from the list L
you should write like this:
fun([{X, Y} | V]).
[{X, Y} | V] = [{X,Y}, {A,B}, {M,N}], then V = [{A,B}, {M,N}]
Day 2 of learning Erlang. I am trying to learn the basics of using Map in Erlang by creating a simple map function that takes in any predicate and list (passed in by the user) and checks if the the predicate returns true or false and stores the result in the list.
So if the user passes in (> 3) as the predicate and the list contains [3,4,5] the desired output would be [false, true, true].
This is what I tried:
applyMap (P, LST) -> lists:map(P LST).
I appreciate any suggestions on how to do this.
Many thanks in advance!
I think you're just missing a , between P and LST in your call to lists:map. Try this one:
applyMap (P, LST) -> lists:map(P, LST).
If you pass in the anonymous function fun(X) -> X > 3 end to your applyMap, you should get your desired output.
Example:
applyMap (fun(X) -> X > 3 end, LST).
There are two problems: first, you're missing the comma between P and LST, but second, you can't use Haskell-style curried functions like (> 3). lists:map((> 3), [1,2,3]) isn't correct in Erlang.
In Haskell, (> 3) is the curried form of \n -> n > 3. In Erlang, you have to write it explicitly:
lists:map(fun(N) -> N > 3 end, [2,4,6])
I'm trying to read in a file containing key/value pairs of the form:
#A comment
a=foo
b=bar
c=baz
Some other stuff
With various other lines, as suggested. This wants to go into a map that I can then look up keys from.
My initial approach would be to read in the lines and split on the '=' character to get a [[String]]. In Scala, I would then use collect, which takes a partial function (in this case something like \x -> case x of a :: b :: _ -> (a,b) and applies it where it's defined, throwing away the values where the function is undefined. Does Haskell have any equivalent of this?
Failing that, how would one do this in Haskell, either along my lines or using a better approach?
Typically this is done with the Maybe type and catMaybes:
catMaybes :: [Maybe a] -> [a]
So if your parsing function has type:
parse :: String -> Maybe (a,b)
then you can build the map by parsing the input string into lines, validating each line and returning just the defined values:
Map.fromList . catMaybes . map parse . lines $ s
where s is your input string.
The List Monad provides what you are looking for. This can probably be most easily leveraged via a list comprehension, although, it works with do notation as well.
First, here's the Scala implementation for reference -
// Using .toList for simpler demonstration
scala> val xs = scala.io.Source.fromFile("foo").getLines().toList
List[String] = List(a=1, b=2, sdkfjhsdf, c=3, sdfkjhsdf, d=4)
scala> xs.map(_.split('=')).collect { case Array(k, v) => (k, v) }
List[(String, String)] = List((a,1), (b,2), (c,3), (d,4))
Now the list comprehension version using Haskell -
λ :m + Data.List.Split
λ xs <- lines <$> readFile "foo"
λ xs
["a=1","b=2","sdkfjhsdf","c=3","sdfkjhsdf","d=4"]
-- List comprehension
λ [(k, v) | [k, v] <- map (splitOn "=") xs]
[("a","1"),("b","2"),("c","3"),("d","4")]
-- Do notation
λ do { [k, v] <- map (splitOn "=") xs; return (k, v) }
[("a","1"),("b","2"),("c","3"),("d","4")]
What's happening is that the pattern match condition is filtering out cases that don't match using the fail method from Monad.
λ fail "err" :: [a]
[]
So both the list comprehension and do notation are leveraging fail, which desugars to this -
map (splitOn "=") xs >>= (
\s -> case s of
[k, v] -> return (k, v)
_ -> fail ""
)