I have been messing around with Haskell for two weeks now and have some functions written in Haskell. I heard that Erlang was quite similar(since they are both predominately functional) so I thought I would translate some of these functions to see if I could get them working in Erlang. However I have been having trouble with the syntax for this function I wrote. The purpose of this function is to simply take a character or int and go through a list. After it goes through the list I am just trying to count the amount of times that item occurs. Here is an example run it should return the following.
count (3, [3, 3, 2, 3, 2, 5]) ----> 3
count (c, [ a, b, c, d]) ----> 1
Whenever I run my code it just keeps spitting out syntax issues and it is really a pain debugging in Erlang. Here is the code I have written:
count(X,L) ->
X (L:ls) ->
X == L = 1+(count X ls);
count X ls.
Any ideas I can do to fix this?
It's not clear what you're going for, as your syntax is pretty far off. However, you could accomplish your call with something like this:
count(Needle, Haystack) -> count(Needle, Haystack, 0).
count(_, [], Count) -> Count;
count(X, [X|Rest], Count) -> count(X, Rest, Count+1);
count(X, [_|Rest], Count) -> count(X, Rest, Count).
To elaborate, you're creating a recursive function called count to find instances of Needle in Haystack. With each call, there are 3 cases to consider: the base case, where you have searched the entire list; the case in which the value you're searching for matches the first item in the list; and the case in which the value you're searching for does not match the first item in the list. Each case is a separate function definition:
count(_, [], Count) -> Count;
Matches the case in which the Haystack (i.e., the list you are scanning) is empty. This means you do not have to search anymore, and can return the number of times you found the value you're searching for in the list.
count(X, [X|Rest], Count) -> count(X, Rest, Count+1);
Matches the case in which the value you're searching for, X, matches the first item in the list. You want to keep searching the list for more matches, but you increment the counter before calling count again.
count(X, [_|Rest], Count) -> count(X, Rest, Count).
Matches the case in which the value you're searching for does not match the head of the list. In this case, you keep scanning the rest of the list, but you don't increment the counter.
Finally,
count(Needle, Haystack) -> count(Needle, Haystack, 0).
Is a helper that calls the three-argument version of the function with an initial count of 0.
Use list comprehension in Erlang:
Elem = 3,
L = [3, 3, 2, 3, 2, 5],
length([X || X <- L, X =:= Elem]) %% returns 3
Related
I'm new to Clojure, after trying multiple methods I'm completely stuck. I know how to achieve this in any other imperative languages, but not in Clojure.
I have a JSON file https://data.nasa.gov/resource/y77d-th95.json containing meteor fall data, each fall includes a mass and year.
I'm trying to find which year had the greatest collective total mass of falls.
Here's what I have so far:
(def jsondata
(json/read-str (slurp "https://data.nasa.gov/resource/y77d-th95.json") :key-fn keyword))
;Get the unique years
(def years (distinct (map :year jsondata)))
;Create map of unique years with a number to hold the total mass
(def yearcount (zipmap years (repeat (count years) 0)))
My idea was to use a for function to iterate through the jsondata, and update the yearcount map with the corresponding key (year in the fall object) with the mass of the object (increment it by, as in += in C)
I tried this although I knew it probably wouldn't work:
(for [x jsondata]
(update yearcount (get x :year) (+ (get yearcount (get x :year)) (Integer/parseInt (get x :mass)))))
The idea of course being that the yearcount map would hold the totals for each year, on which I could then use frequencies, sort-by, and last to get the year with the highest mass.
Also defined this function to update values in a map with a function, although Im not sure if I could actually use this:
(defn map-kv [m f]
(reduce-kv #(assoc %1 %2 (f %3)) {} m))
I've tried a few different methods, had lots of issues and just can't get anywhere.
Here's an alternate version just to show an approach with a slightly different style. Especially if you're new to clojure it may be easier to see the stepwise thinking that led to the solution.
The tricky part might be the for statement, which is another nice way to build up a new collection by (in this case) applying functions to each key and value in an existing map.
(defn max-meteor-year [f]
(let [rdr (io/reader f)
all-data (json/read rdr :key-fn keyword)
clean-data (filter #(and (:year %) (:mass %)) all-data)
grouped-data (group-by #(:year %) clean-data)
reduced-data
(for [[k v] grouped-data]
[(subs k 0 4) (reduce + (map #(Double/parseDouble (:mass %)) v))])]
(apply max-key second reduced-data)))
clj.meteor> (max-meteor-year "meteor.json")
["1947" 2.303023E7]
Here is my solution. I think you'll like it because its parts are decoupled and are not joined into a single treading macro. So you may change and test any part of it when something goes wrong.
Fetch the data:
(def jsondata
(json/parse-string
(slurp "https://data.nasa.gov/resource/y77d-th95.json")
true))
Pay attention, you may just pass true flag that indicates the keys should be keywords rather than strings.
Declare a helper function that takes into account a case when the first argument is missing (is nil):
(defn add [a b]
(+ (or a 0) b))
Declare a reduce function that takes a result and an item from a collection of meteor data. It updates the result map with our add function we created before. Please note, some items do not have either mass or year keys; we should check them for existence before operate on them:
(defn process [acc {:keys [year mass]}]
(if (and year mass)
(update acc year add (Double/parseDouble mass))
acc))
The final step is to run reducing algorithm:
(reduce process {} jsondata)
The result is:
{"1963-01-01T00:00:00.000" 58946.1,
"1871-01-01T00:00:00.000" 21133.0,
"1877-01-01T00:00:00.000" 89810.0,
"1926-01-01T00:00:00.000" 16437.0,
"1866-01-01T00:00:00.000" 559772.0,
"1863-01-01T00:00:00.000" 33710.0,
"1882-01-01T00:00:00.000" 314462.0,
"1949-01-01T00:00:00.000" 215078.0,
I think that such a step-by-step solution is much more clearer and maintainable than a single huge ->> thread.
Update: sorry, I misunderstood the question. I think this will work for you:
(->> (group-by :year jsondata)
(reduce-kv (fn [acc year recs]
(let [sum-mass (->> (keep :mass recs)
(map #(Double/parseDouble %))
(reduce +))]
(assoc acc year sum-mass)))
{})
(sort-by second)
(last))
=> ["1947-01-01T00:00:00.000" 2.303023E7]
The reduce function here is starting out with an initial empty map, and its input will be the output of group-by which is a map from years to their corresponding records.
For each step of reduce, the reducing function is receiving the acc map we're building up, the current year key, and the corresponding collection of recs for that year. Then we get all the :mass values from recs (using keep instead of map because not all recs have a mass value apparently). Then we map over that with Double/parseDouble to parse the mass strings into numbers. Then we reduce over that to sum all the masses for all the recs. Finally we assoc the year key to acc with the sum-mass. This outputs a map from years to their mass sums.
Then we can sort those map key/value pairs by their value (second returns the value), then we take the last item with the highest value.
fun({0, M}) -> {M+1, M-2};
fun({N, M}) ->
{A, B} = fun({N-1, M+1}),
{B, A+1}.
so I am kinda unsure of what the A and B would be and how the next recursive call would be. let say 2,2
so it would be
f(2,2) -> {A,B} = fun({1,3}), {B,A+1}
f(1,3) -> {A,B} = fun({0,4}), {B,A+1}
f(0,4) -> {5,2}
but where does A and B go and do they change in each recursive call?
As a very basic explanation of "where is my variable", consider the countdown function in this example module:
-module(example).
-export([countdown/1]).
-spec countdown(non_neg_integer()) -> ok.
countdown(0) ->
io:format("Blastoff!~n");
countdown(N) when N > 0 ->
ok = io:format("Counting down in: ~w~n", [N]),
Next = N - 1,
countdown(Next).
If we hit the base case, which is 0, then we stop. The return value of the function overall is the atom ok (because that is the return value of a successful call to io:format/2).
If the input is greater than 0 then we match on the second clause, which means we assign N the sole input argument for this particular iteration. The next thing we do is make our output call. Then we assign Next to the value N - 1. Then we call the same function again (do a loop) using the value of Next in body of the the current call as the input argument.
The next iteration all the variables are totally new because this is a fresh execution context. The old N and Next no longer exist. In fact, they don't event exist on a stack anywhere because Erlang uses "tail call optimization" to maintain recursive tail calls in constant space, the same way most other languages would do an explicit for or while or do while or [insert form].
As Alexy points out, be careful about the token fun -- it is a keyword in Erlang, not a legal function name. It is the non-name of an anonymous function (also known as a lambda). In other words, unless you provide a label, the name of every anonymous function is just fun.
fun is also the keyword that is used to reference a function by label (to use as a value itself) instead of calling it. For example, countdown(10) calls the function above with an argument of 10. Referencing the function as fun countdown/1 returns the function itself as a value. That is, incidentally, why the function export declaration at the top of the module is written as -module([countdown/1]), because that is the explicit name of this function. Consider this:
1> c(example).
{ok,example}
2> example:countdown(2).
Counting down in: 2
Counting down in: 1
Blastoff!
ok
3> Countdown = fun example:countdown/1.
#Fun<example.countdown.1>
4> Countdown(2).
Counting down in: 2
Counting down in: 1
Blastoff!
ok
While I'm on the subject...
Erlang has very few keywords compared to most languages (and very little syntax, actually). Here is the list of reserved words:
after and andalso band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse receive rem try when xor
You just need to go back up:
f({1, 3}) -> {A, B} = {5, 2}, {B, A+1} -> {2, 6}
f({2, 2}) -> {A, B} = {2, 6}, {B, A+1} -> {6, 3}
(note that fun is a keyword in Erlang and that f(N,M) is not the same as f({N,M}))
and do they change in each recursive call
Yes, as you can see.
How many functions are present in this expression? :
'a -> 'a -> ('a*'a)
Also, how would you implement a function to return this type? I've created functions that have for example:
'a -> 'b -> ('a * b)
I created this by doing:
fun function x y = (x,y);
But I've tried using two x inputs and I get an error trying to output the first type expression.
Thanks for the help!
To be able to have two inputs of the same alpha type, I have to specify the type of both inputs to alpha.
E.g
fun function (x:'a) (y:'a) = (x, y);
==>
a' -> 'a -> (a' * 'a)
Assuming this is homework, I don't want to say too much. -> in a type expression represents a function. 'a -> 'a -> ('a * 'a) has two arrows, so 2 might be the answer for your first question, though I find that particular question obscure. An argument could be made that each fun defines exactly one function, which might happen to return a function for its output. Also, you ask "how many functions are present in the expression ... " but then give a string which literally has 0 functions in it (type descriptions describe functions but don't contain functions), so maybe the answer is 0.
If you want a natural example of int -> int -> int * int, you could implement the functiondivmod where divmod x y returns a tuple consisting of the quotient and remainder upon dividing x by y. For example, you would want divmod 17 5 to return (3,2). This is a built-in function in Python but not in SML, but is easily defined in SML using the built-in operators div and mod. The resulting function would have a type of the form 'a -> 'a -> 'a*'a -- but for a specific type (namely int). You would have to do something which is a bit less natural (such as what you did in your answer to your question) to come up with a polymorphic example.
OK, it's been a long day and my brain may not function at Haskell level, but I just cannot understand one example from 'Learn You a Haskell'.
The section is called Function Application with $, and there is example of how $ may be defined:
($) :: (a -> b) -> a -> b
f $ x = f x
So far everything is clear. I understand all examples in the section, except for the last one:
ghci> map ($ 3) [(4+), (10*), (^2), sqrt]
[7.0,30.0,9.0,1.7320508075688772]
Here we map ($ 3) across list of functions and get result of application of those functions to 3. But how is this possible?
From the first code snippet it's clear that first argument is a function, we can even write:
*Main> ($) sqrt 4
2.0
Now ($ 3) is a partial application of function $, but 3 goes on function's position! So 3 is supposed to be a function or what?
There is another mystery: what the heck is (4+)? I know that (+4) is a partial application of function +, so (4+) should be partial application of function 4? Nonsense. What sort of trick works here?
($ 3) and (+ 4) aren't partial applications - they're operator sections. A partial application would look like (($) 3) or ((+) 4).
An operator section of the form (? x) (where ? stands for an arbitrary infix operator) binds the right operand of the operator, i.e. it is equivalent to \y -> y ? x. Likewise the operator section (x ?) binds the left operand and is thus equivalent to partial application.
I think what's tripping you up is operator sections. These let you partially apply an operator with either one of its arguments, so you can have the operators (+4) and (4+), where 4 is the the second then the first argument to + respectively. A more clear example might be ("Hello" ++) versus (++ "world"), the former prepends "Hello" onto the front of a string, while the latter appends "world" onto the end of a string.
This is contrasted with using operators in prefix form with just parens around it. In this form, the following are equivalent:
> let join = (++)
> join "Hello, " "world"
"Hello, world"
> (++) "Hello, " "world"
"Hello, world"
In prefix form, you treat the operator as a normal function and it accepts its first then second argument in order. In operator sections, it matters which side of the operator the argument is on.
So in your example, you have the partial application of ($ 3), you can reduce it as
map ($ 3) [(4+), (10*), (^2), sqrt]
[($ 3) (4+), ($ 3) (10 *), ($ 3) (^ 2), ($ 3) sqrt]
[4 + 3, 10 * 3, 3 ^ 2, sqrt 3]
[7.0, 30.0, 9.0, 1.7320508075688772]
You are getting confused with sections. A good way to grasp the concept of sections is playing with an example:
(<^>) :: Int -> Float -> Int
a <^> b = a
The above function is an useless function which returns the first parameter no matter what the second parameter is. But it accepts Int and then Float as input.
Now, because of sections you can apply with any one of their arguments:
λ> let a = (3 <^>)
λ> :t a
a :: Float -> Int
λ> let b = (<^> 3.0)
λ> :t b
b :: Int -> Int
See how the type of a and b are different because of sections.
I've another issue with my Haskell. I'm given the following data constructor from a problem,
type Point = (Int, Int)
data Points = Lines Int Int
| Columns Int Int
| Union Points Points
| Intersection Points Points
It's about points on a grid starting (0,0) and (x,y) has x as the horizontal distance from the origin and y as the vertical distance from the origin.
I tried to define a function "Lines" from this, which, given Lines x y would evaluate all points with vertical distance x ~ y on the grid.
e.g.
> Lines 2 4
(0,2)(1,2)(2,2)(3,2)....
(0,3)(1,3)(2,3)(3,3)....
(0,4)(1,4)(2,4)(3,4)....
and so on. Well what I did, was,
Lines :: Int -> Int -> Points
Lines lo hi = [ (_, y) | lo <= y && y <= hi ]
But Haskell complains that;
Invalid type signature Lines :: Int -> Int -> Points.
Should be of the form ::
what's this mean? "Points" is defined above already...surely "Int" "Points" are regarded as "types"? I don't see the problem, why is Haskell confused?
Functions must not start with a capital letter. So you need to use lines, not Lines. This is probably the source of the error message you're seeing.
The syntax [ ... ] is for creating a list of results, but your type signature claims that the function returns Points, which isn't any kind of list. If you meant to return a list of Point values, that's the [Point] type.
I have literally no idea what your implementation of Lines is even trying to do. The syntax makes no sense to me.
OK, so taking your comments into account...
You can generate a list of numbers between lo and hi by writing [lo .. hi].
You say an "arbitrary" value can go in X, but you need to pin down exactly what that means. Your example seems to suggest you want the numbers from 0 upwards, forever. The way to generate that list is [0 .. ]. (Not giving an upper limit makes the list endless.)
Your example suggests you want a list of lists, with the inner list containing all points with the same Y-coordinate paired with all possible X-coordinates.
So here is one possible way to do that:
type Point = (Int, Int)
lines :: Int -> Int -> [[Point]]
lines lo hi = [ [(x,y) | x <- [0..]] | y <- [lo .. hi] ]
That's perhaps a teeny bit hard to read, with all those opening and closing brackets, so perhaps I can make it slightly cleaner:
lines lo hi =
let
xs = [0..]
ys = [lo .. hi]
in [ [(x,y) | x <- xs] | y <- ys]
If you run this, you get
> lines 2 4
[[(0,2), (1,2), (2,2), ...],
[(0,3), (1,3), (2,3), ...],
[(0,4), (1,4), (2,4), ...]]
In other words, the outer list has 3 elements (Y=2, Y=3 and Y=4), and each of the three inner lists is infinitely long (every possible positive X value).