I want to know if f(X) is true for all X in some very large list L.
Right now I have:
lists:foldl(fun(X, Last) -> f(X) andalso Last end, true, L)
The problem is I don't think this short circuits. Even if it is false for the first element in L it continues on always andalsoing with false.
Is there a flag to foldl such that this will short circuit or another function I can use?
I now see there is a function called all but it doesn't say whether it short circuits either.
lists:foldl/3 does not have any way to stop the fold and return a value immediately. You can use lists:all/2 for this, which will stop processing the rest of the list if the function passed returns false for any item of the list:
lists:all(fun(X) -> f(X) end, L)
% or
lists:all(fun f/1, L)
Related
I’m trying to learn to program with the book Clojure for the Brave and True (CFTBAT). At the end of the crash course, the author makes us write a small programm to illustrate looping in Clojure. To explain the looping and recursing part of the program, here, the author writes a smaller example using loop and then shows it’s possible to replace loop with a normal function definition.
It’s this normal function definition example I can’t understand. Here is the code:
(defn recursive-printer
([]
(recursive-printer 0))
([iteration]
(println iteration)
(if (> iteration 3)
(println "Bye!")
(recursive-printer (inc iteration)))))
(recursive-printer)
I don’t understand the code because I can’t see where are the arguments of the function recursive-printer. In Clojure, the arguments of a function are supposed to be in brackets and the body in parenthesis. So, in this example, the arguments would be an empty argument [] and iteration. But then why are they put between parenthesis too?
And what is (recursive-printer 0) Is it a function call, where the function calls itself?
If someone could explain me how this piece of code works, that would be much appreciated.
In clojure you can define a function such that it can take different numbers of
arguments e.g.
(defn foo []
....)
is a function which takes no arguments. It is called like this ..
(foo)
(defn foo [x]
...)
is a function which takes 1 argument. It can be called like
(foo :a)
but sometimes, you may want to define a function which takes zero or 1
argument. To do this, you use a slightly different format
(defn foo
([] ;no argument form
...)
([x] ;single argument form
...))
A common idiom is to use a zero argument form in a recursive function definition
and include a single 'accumulator' argument form as the main part of the
function. So, looking at your example, you have
(defn recursive-printer
([] ; zero argument form
(recursive-printer 0))
([iteration] ; 1 argument form
(println iteration)
(if (> iteration 3)
(println "Bye!")
(recursive-printer (inc iteration)))))
(recursive-printer)
When you call (recursive-printer) it calls the first form (zero argument
form). That form in turn calls the function with a single argument of 0. This
calls the second form.
The second form first prints out the argument, then tests to see if it is
greater than 3, which in the first call it is not as it is 0, so it executes the
'else' statement, which does a recursive call with a new argument which is the
current argument increased by 1. Now your argument is 1 and it is printed
out. the test is still false as 1 is not > 3, so the function is called again
with the argument increased by 1 i.e. 2. In this call, 2 is printed, the test is
still not grater than three, so the function is called again with the argument
increased to 3. In this call, 3 is printed and the test is still not > 3, so the
argument is incremented to 4 and the function called again with 4 as the
argument. The value 4 is printed, but this time 4 is > 3, so the string "Bye" is
printed and as this is the terminating condition, no further recursive call is
made and the stack unwinds and the function terminates.
We can drop the zero arity:
(defn recursive-printer [iteration]
(println iteration)
(if (> iteration 3)
(println "Bye!")
(recursive-printer (inc iteration))))
... and call the function with an explicit 0 argument:
(recursive-printer 0)
0
1
2
3
4
Bye!
=> nil
This lets us concentrate on the recursion. Since the recursive call is the last thing done (in tail position), we can use recur instead:
(defn recursive-printer [iteration]
(println iteration)
(if (> iteration 3)
(println "Bye!")
(recur (inc iteration))))
... with exactly the same effect.
The extra arity just confuses things, I think.
I know how to calculate the sum of the digits of a number:
(define (sum-of-digits x)
(if (= x 0) 0
(+ (modulo x 10)
(sum-of-digits (/ (- x (modulo x 10))
10)))))`
But I just don't have a clue to make a count of the digits. And also don't know how to do that by a linear iterative progress.
Thanks!!
You are very close to the answer.
In order to figure out how to change sum-of-digits into count-of-digits, try writing some test cases. A test case must include an example of calling the function, and also the expected result.
As a side note, this is an example of generative recursion, and you shouldn't be tackling it until you've done a bunch of problems like "add the numbers in a list", "count the elements in a list", etc.
Some hints regarding each of your questions:
For counting digits, you don't need to add the current digit (as is the case in your code). Just add 1
There are several strategies for transforming a recursive solution (like yours) to a tail recursion (one that generates a linear iterative progress). Here's a short list:
Add an extra parameter to the function to hold the result accumulated so far
Pass the initial value for the accumulator the first time you call the procedure, typically this is the same value that you'd have returned at the base case in a "normal" (non-tail-recursive) recursion.
Return the accumulator at the base case of the recursion
At the recursive step, update the accumulated result with a new value and pass it to the recursive call
And the most important: when the time comes to call the recursion, make sure to call it as the last expression with no "additional work" to be performed.
I'm trying to learn smlnj at the moment and am having trouble with a fold function.
What I'm trying to do is write a function, select, that uses the folding pattern and takes in a function and a list. It will take the head of the list into the function to determine whether it will add that element to the list. Here is an example of what I mean.
select (fn x => x mod 2 = 0) [1,2,3,4,5,6,7,8,9,10];
val it = [2,4,6,8,10] : int list
So, here is what I have so far...
fun select f l = foldl (fn (x,y) => if (f(x)) then x else 0) 0 l;
This obviously doesn't work correctly. It simply returns 10. I'm sure I need to use op:: somehow to get this to work, but I can't figure it out. My thought is that it should look something like this...
fun select f l = foldl (fn (x,y) => if (f(x)) then op:: else []) [] l;
But this does not work. Any help would be appreciated. Thanks!
You're close. The only problems are the if/else cases in the function you're passing to fold.
Remember, in your fn (x,y), x is the list element you're considering, and y is the result of folding the rest of the list. If f(x) fails, then you want to exclude x from the result, so you just pass y along. If f(x) succeeds, you want to include x in your result, so you return y#[x].
Note that it's best to avoid using the append operator (y#[x]) where you can, as it's a linear-time operation, while prepending (x::y) is constant. Of course, substituting one for the other in this case will construct your list backwards. You can get around this by folding backwards as well, i.e. using foldr instead of foldl.
What you're implementing already exists. It's called filter.
- List.filter (fn x => x mod 2 = 0) [1,2,3,4,5,6,7,8,9,10];
val it = [2,4,6,8,10] : int list
Your attempt in your second code sample is pretty close. There are several issues I might point out:
op:: is an operator, which is a function. You probably don't want to return a function. Instead, you probably want to use the operator to create a list from a head element and the rest of the list, like this: x :: y
In the else case, you are currently returning an empty list, and throwing away whatever was accumulated in y. You probably don't want to do that.
Think about whether left-fold or right-fold would be most suitable for your output
Sorry for the vague title, I guess I just don't understand my problem well enough to ask it yet but here goes. I want to write a recursive function which takes a sequence of functions to evaluate and then calls itself with their results & so on. The recursion stops at some function which returns a number.
However, I would like the function being evaluated at any point in the recursion, f, to be wrapped in a function, s, which returns an initial value (say 0, or the result of another function i) the first time it is evaluated, followed by the result of evaluating f (so that the next time it is evaluated it returns the previously evaluated result, and computes the next value). The aim is to decouple the recursion so that it can proceed without causing this.
I think I'm asking for a lazy-seq. It's a pipe that's filling-up with evaluations of a function at one end, and historical results are coming out of the other.
Your description reminds me some of reductions? Reductions will perform a reduce and return all the intermediate results.
user> (reductions + (range 10))
(0 1 3 6 10 15 21 28 36 45)
Here (range 10) creates a seq of 0 to 9. Reductions applies + repeatedly, passing the previous result of + and the next item in the sequence. All of the intermediate results are returned. You might find it instructive to look at the source of reductions.
If you need to build a test (check for value) into this, that's easy to do with an if in your function (although it won't stop traversing the seq). If you want early exit on a condition being true, then you'll need to write your own loop/recur which amalloy has already done well.
I hate to say it, but I suspect this might also be a case for the State Monad but IANAMG (I Am Not A Monad Guy).
I don't understand your entire goal: a lot of the terms you use are vague. Like, what do you mean you want to evaluate a sequence of functions and then recur on their results? These functions must be no-arg functions (thunks), then, I suppose? But having a thunk which first returns x, and then returns y the next time you call it, is pretty vile and stateful. Perhaps trampoline will solve part of your problem?
You also linked to something you want to avoid, but seem to have pasted the wrong link - it's just a link back to this page. If what you want to avoid is stack overflow, then trampoline is likely to be an okay way to go about it, although it should be possible with just loop/recur. This notion of thunks returning x unless they return y is madness, if avoiding stack overflow is your primary goal. Do not do that.
I've gone ahead and taken a guess at the most plausible end goal you might have, and here's my implementation:
(defn call-until-number [& fs]
(let [numeric (fn [x] (when (number? x) x))]
(loop [fs fs]
(let [result (map #(%) fs)]
(or (some numeric result)
(recur result))))))
(call-until-number (fn [] (fn [] 1))) ; yields 1
(call-until-number (fn [] (fn [] 1)) ; yields 2
(fn [] 2))
(call-until-number (fn f [] f)) ; never returns, no overflow
Firstly, Real World Haskell, which I am reading, says to never use foldl and instead use foldl'. So I trust it.
But I'm hazy on when to use foldr vs. foldl'. Though I can see the structure of how they work differently laid out in front of me, I'm too stupid to understand when "which is better." I guess it seems to me like it shouldn't really matter which is used, as they both produce the same answer (don't they?). In fact, my previous experience with this construct is from Ruby's inject and Clojure's reduce, which don't seem to have "left" and "right" versions. (Side question: which version do they use?)
Any insight that can help a smarts-challenged sort like me would be much appreciated!
The recursion for foldr f x ys where ys = [y1,y2,...,yk] looks like
f y1 (f y2 (... (f yk x) ...))
whereas the recursion for foldl f x ys looks like
f (... (f (f x y1) y2) ...) yk
An important difference here is that if the result of f x y can be computed using only the value of x, then foldr doesn't' need to examine the entire list. For example
foldr (&&) False (repeat False)
returns False whereas
foldl (&&) False (repeat False)
never terminates. (Note: repeat False creates an infinite list where every element is False.)
On the other hand, foldl' is tail recursive and strict. If you know that you'll have to traverse the whole list no matter what (e.g., summing the numbers in a list), then foldl' is more space- (and probably time-) efficient than foldr.
foldr looks like this:
foldl looks like this:
Context: Fold on the Haskell wiki
Their semantics differ so you can't just interchange foldl and foldr. The one folds the elements up from the left, the other from the right. That way, the operator gets applied in a different order. This matters for all non-associative operations, such as subtraction.
Haskell.org has an interesting article on the subject.
Shortly, foldr is better when the accumulator function is lazy on its second argument. Read more at Haskell wiki's Stack Overflow (pun intended).
The reason foldl' is preferred to foldl for 99% of all uses is that it can run in constant space for most uses.
Take the function sum = foldl['] (+) 0. When foldl' is used, the sum is immediately calculated, so applying sum to an infinite list will just run forever, and most likely in constant space (if you’re using things like Ints, Doubles, Floats. Integers will use more than constant space if the number becomes larger than maxBound :: Int).
With foldl, a thunk is built up (like a recipe of how to get the answer, which can be evaluated later, rather than storing the answer). These thunks can take up a lot of space, and in this case, it’s much better to evaluate the expression than to store the thunk (leading to a stack overflow… and leading you to… oh never mind)
Hope that helps.
By the way, Ruby's inject and Clojure's reduce are foldl (or foldl1, depending on which version you use). Usually, when there is only one form in a language, it is a left fold, including Python's reduce, Perl's List::Util::reduce, C++'s accumulate, C#'s Aggregate, Smalltalk's inject:into:, PHP's array_reduce, Mathematica's Fold, etc. Common Lisp's reduce defaults to left fold but there's an option for right fold.
As Konrad points out, their semantics are different. They don't even have the same type:
ghci> :t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
ghci> :t foldl
foldl :: (a -> b -> a) -> a -> [b] -> a
ghci>
For example, the list append operator (++) can be implemented with foldr as
(++) = flip (foldr (:))
while
(++) = flip (foldl (:))
will give you a type error.