Why is [1..n] not handled the same way as [n..1] in Haskell? - list

I was trying to solve a problem that required the maximum value of a list after being mapped over by a function. The list is a range from a to b where a>b or b>a. Because Haskell can also define decreasing lists i thought that i didn't need to check if a>b and there was no need to flip the bounds to b..a. The function looks somewhat like this:
f a b = maximum . map aFunction $ [a..b]
But if the list is decreasing i.e. a>b then Haskell gives me an exception:
Prelude.maximum: empty list
So for some reason a decreasing list hands over an empty list to the maximum function. Why is that?
I know that maximum is defined in terms of a foldl1 max and that foldl1 needs a non empty list but i don't know why a list like [10..1] is empty when handed to a foldl1.

[a..b] desugars to enumFromTo a b. For standard numeric types (modulo a couple of quirks for floating), this keeps adding one until you are >= b. So where b < a this is empty.
You can change the increment by using the following syntax [a,a'..b] which then takes steps in increments of a'-a. So [10,9..1] will be what you want.

This is because of the way the sequence is defined in Haskell Report Arithmetic Sequences
:
[ e1..e3 ] = enumFromTo e1 e3
and Haskell Report The Enum Class
The sequence enumFromTo e1 e3 is the list [e1,e1 + 1,e1 + 2, ... e3]. The list is empty if e1 > e3.
(emphasis added).

They are handled exactly the same way. You start from the first bound and count up.

Related

Counting how many elements in a list of lists satisfy a predicate

Given a list of lists of integers, e.g. [[3,10],[3,10,2],[5],[5,2],[5,3],[5,3,2],[5,3,10]], I want to go over each sublist and count how many of them sum to 15. In this case that would be 1, for the sublist [3,10,2].
I am aware of the predicate aggregate_all/3, but I'm having trouble writing a predicate to check each element of the list, what I have now is something like
fifteens([X|Xs]) :-
sum_list(X, 15),
fifteens(Xs).
and within another predicate I have:
aggregate_all(count, fifteens(Combinations), Value).
where Combinations is the list of lists of integers in question.
I know my fifteens predicate is flawed since it's saying that all elements of the nested list must sum to 15, but to fix this how do I take out each element of Combinations and check those individually? Do I even need to? Thanks.
First of all your fifteens/2 predicate has no because for empty list and thus it will always fails because due to the recursion eventually fifteens([]) will be called and fail.
Also you need to change completely the definition of fifteens, currently even if you add base case, it says check ALL elements-sublists to see if they sum to 15. That's Ok but I don't see how you could use it with aggregate.
To use aggregate/3 you need to express with fifteens/2, something like: for every part of my combinations list check separately each sublist i.e each member:
ifteens(L) :-
member(X,L),
sum_list(X, 15).
Now trying:
?- aggregate_all(count, ifteens([[3,10],[3,10,2],[5],[5,2],[5,3],[5,3,2],[5,3,10]]), Value).
Value = 1.
This is a job for ... foldl/4. Functional programming idioms in logic programming languages? Yes, we can!
First, summing the summable values of a list:
sum_them(List,Sum) :-
foldl(sum_goal,List,0,Sum).
sum_goal(Element,FromLeft,ToRight) :-
must_be(number,Element),
must_be(number,FromLeft),
ToRight is Element+FromLeft.
Then, counting the ones that sum to 15:
count_them(List,Count) :-
foldl(count_goal,List,0,Count).
count_goal(Element,FromLeft,ToRight) :-
must_be(list(number),Element),
must_be(number,FromLeft),
sum_them(Element,15) -> succ(FromLeft,ToRight) ; FromLeft = ToRight.
Does it work? Let's write some unit tests:
:- begin_tests(fifteen_with_foldl).
test("first test",true(R==1)) :-
count_them([[3,10],[3,10,2],[5],[5,2],[5,3],[5,3,2],[5,3,10]],R).
test("test on empty",true(R==0)) :-
count_them([],R).
test("test with 2 hist",true(R==2)) :-
count_them([[15],[],[1,1,1,1,1,10]],R).
:- end_tests(fifteen_with_foldl).
And so:
% PL-Unit: fifteen_with_foldl ... done
% All 3 tests passed
true.

How to implement recursive function to simplify polynomial terms with sorted tuple list?

I'm trying to implement a function to add like terms of a sorted list of tuples (first number represents polynomial's constant, the second represents the power). I'm an ocaml noob and don't really know what I'm doing wrong or how to do this correctly.
I tried to write it, but it doesn't work
https://gyazo.com/d37bb66d0e6813537c34225b6d4048d0
let rec simp list =
match list with
| (a,b)::(c,d)::remainder where b == d -> (a+c,b)::simp(remainder)
| (a,b)::(c,d)::remainder where b != d -> (a,b)::(c,d)::simp(remainder)
| _ -> list;;
This should combine all the terms with the same second value and just return one tuple with their first values added to the new list. ie: [(3,2);(4,2)] -> [(7,2)].
I am not familiar with the where keyword - there is ocaml-where which provides it, but it seems to be doing something different than what you are expecting. As such, the syntax is just wrong, and where is unexpected.
You probably meant when instead of where.

How to exclude a particular tuple from a list in haskell

Im very confused on how to filter out the element (1,1) from this list in the code below.
take 10 [ (i,j) | i <- [1,2],
j <- [1..] ]
yields
[(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8),(1,9),(1,10)]
My thoughts were to use something like filter but Im not too sure where to implement it.
My go was Filter ((i,j) /=0) "the list"
Thanks
Your attempt
Filter ((i,j) /=0) "the list"
has a few problems, which can be fixed.
First, the function is called filter. Second, its first argument must be a function: so you can use \(i,j) -> ... to take a list as input. Third, you want (i,j) /= (1,1) -- you can't compare a pair (i,j) to a single number 0.
You should now be able to correct your code.
As an alternative to using filter, you can also specify that you don't want (1,1) as an element within your list comprehension by adding a guard expression (i,j) /= (1,1):
take 10 [ (i,j) | i &lt- [1,2], j &lt- [1..], (i,j) /= (1,1) ]
This is similar to how you might write a set comprehension (which list comprehensions mimic):
This answer gives a nice example ([x | i <- [0..10], let x = i*i, x > 20]) of the three types of expression you can have in the tail end of a list comprehension:
Generators, eg. i <- [0..10] provide the sources of values.
Guards, eg. x > 20 are arbitrary predicates - for any given values from the generators, the value will only be included in the result if all the predicates hold.
Local declarations, eg. let x = i*i perform the same task as normal let/where statements.
Names for the different expressions taken from the syntax reference, expression qual.

Building sucessive union of lists/arrays using comprehension and iteration

Afternoon-I'm currently trying to read up on/implement more clever ways to form the union of sub lists after imposing varying conditions on the original list (or, more generally, any list)-specifically the successive union over what may be a large number of sublists. the data within may be strings, or numerical data.
For example, I could form sub lists of the following list based on the condition if 'a' appears in the ith position of the list.
mylist = [a b c d
d a b c
c b a d
b d c a]
mysublist1 = [item for item in mylist if item[0] == a]
mysublist = [ a b c d]
In this example, I could repeat this process and change the condition to be the ith position of the list and generate 4 sublists. I could then-for demonstrations sake, reform the original list using the handy set functions
set(thisset).union(thatset)
However, without being clever this will take n-1 instances of these guys (forming the first union, then taking successive unions)-which can get dicey.
Is anyone aware of any methods that would make this a bit more elegant? I have tried appending sets to a list and then defining the successive union over the size of this list be fruitful (but I'm getting some type errors!)
Thanks!

Prolog return value comparation

I'm traying to learn the basics of logic programming.
I solved some exercises, and now I'm having trouble on creating a function that take two arguments, a list of non empty lists whose elements concatenated together form the second argument.
By the time I created a function that concat the elements of a list of lists:
concat([[]|L],L3):- concat(L,L3).
concat([[Head|L1]|L2],[Head|L3]):- concat([L1|L2],L3),!.
Now, what I need to know is how to take the return value of that function and compare it with a list (the second argument of the function).
This is one approach that will allow down to single elements in a sublist, but not an empty sublist:
concat([[L]], [L]).
concat([[H],L|T], [H|R]) :- concat([L|T], R).
concat([[H1,H2|T]|LT], [H1|RT]) :- concat([[H2|T]|LT], RT).
The method here to avoid an empty list is to call out two head elements in the recursive clause, and a solitary element list in the base case. This prevents empty sublists from succeeding, as requested in the comments of the original post.
If you have a variable, Y that is already instantiated, and you want to know if it is the result of concatenating the list of lists, LL, you simply query:
concat(LL, Y).
This will be true if Y is the concatenation of list LL and false if it is not. You don't have to "return and compare" (as, for example, in C, you might say, concat(LL) == Y, or concat(LL, X); if (X == Y)...). This is because concat is a relation defined between the two arguments and it determine if the query can be made true by following the stated rules (clauses of the predicate).
If you already obtained a result and want to determine if it's unifiable to another variable, Z, then you can say:
concat(X, Y), Y = Z.
Note that, in Prolog, concat(X, Y) == Z is not correct to determine if the result of the predicate is equal to Z because it is not a function that returns a value.
Prolog doesn't have functions or return values in the sense of a procedural programming language. It has predicates, which assert a relationship. It has terms, which include variables which comes with some strictures:
All variables are local, and
A variable, once assigned a value, ceases to be variable. That's why it's called unification.
So....
If you want a predicate that will take two lists and produce their concatenation, you'll need to pass it a 3rd variable. You might invoke it like this:
concat([a,b],[c,d],X).
which asserts that X is the concatenation of [a,b] and [c,d]. Prolog's inference engine will then evaluate the truth or falseness of the assertion.
Most recursive problems has a few special cases and a more general case. The implementation of such a concat/3 predicate might look something like this (annotated to explain what it's doing).
First, we have one special (and terminating) case: If the left-hand list is empty, the concatenation is simply the right-hand list.
concat( [] , Bs , Bs ).
Next, we have the one general case: if the left-hand list is non-empty, we need to prepend it to the concatentation that we're building (and then recurse down.)
concat( [A|As] , Bs , [A|Cs] ) :-
concat(As,Bs,Cs).
That's all there is two it. You'll also notice that it's bi-directional: it's perfectly happy to split lists apart as well. Invoking it like this:
concat( Prefix , Suffix, [a,b,c,d] ).
will, on backtracking, produce all the possible ways that [a,b,c,d] could be split into a prefix and suffix:
Prefix Suffix
--------- ---------
[] [a,b,c,d]
[a] [b,c,d]
[a,b] [c,d]
[a,b,c] [d]
[a,b,c,d] []
You just need the base case
concat([],[]).
concat([[]|L],L3):- concat(L,L3).
concat([[Head|L1]|L2],[Head|L3]):- concat([L1|L2],L3).
It also works for empty (sub)lists.
I've removed the useless cut.