Why does fold have the following type in Scala? - api

I was looking at the way fold is defined for immutable.Set:
def fold [A1 >: A] (z: A1)(op: (A1, A1) ⇒ A1): A1
yet foldLeft is defined as:
def foldLeft [B] (z: B)(op: (B, A) ⇒ B): B
This looks weird for me, at least at first glance, since I was expecting fold to be able to change the type of the collection it returned, much like foldLeft does.
I imagine this is because foldLeft and foldRight guarantee something about the order in which the elements are folded. What is the guarantee given by fold?

When you're applying foldLeft then your start value is combined with the first list element. The result is combined with the second list element. This result with the third and so on. Eventually, the list has collapsed to one element of the same type than your start value. Therefore you just need some type that can be combined by your function with a list element.
For foldRight the same applies but in reverse order.
fold does not guarantee the order in with the combinations are done. And it does not guarantee that it starts off at only one position. The folds might happen in parallel. Because you could have the parallelism it is required that any 2 list elements or return values can be combined – this adds a constraint to the types.
Regarding your comment that you have to see a case were order has an effect: Assume you're using folds to concatenate a list of characters and you want to have a text as result. If your input is A, B, C, you probably would like to preserve the order to receive ABC instead of ACB (for example).
On the other hand if you're, say, just adding up numbers, the order does not matter. Summing up 1, 2, 3 gives 6 independent of the additions' order. In such cases using fold instead of foldLeft or foldRight could lead to faster execution.

It seems that FoldLeft must return B. The method takes a B arg - this is an accumulator. Values of A are used to "add more to" a B. The final accumulated value is returned. I think FoldLeft and FoldRight are the same in this respect.

Related

List comprehension- Multiple inputs

I am a beginner , trying to understand how list comprehension for multiple input works.
Can someone explain how the below code works?
x,y = [int(x) for x in input("Enter the value ").split()]
print(x,y)
Thanks in advance!
This is actually is not directly related to list comprehensions but instead a concept called "sequence unpacking", which applies to any sequence type (list, tuple, range). What is happening here is that the user input is expected to be two whitespace-separated values. The split call will split the user input on the whitespace, returning a list of size 2. Then, the list comprehension is looping over each element of this split-produced list and converting each one to an int. Thus, the list comprehension will return a list of length 2, and each of its elements will be "unpacked" separately into the x and y variables on the left-hand side of the assignment operator. Here is an excerpt from the Data Structures section of the Python tutorial that explains sequence unpacking:
The statement t = 12345, 54321, 'hello!' is an example of tuple packing: the values 12345, 54321 and 'hello!' are packed together in a tuple. The reverse operation is also possible:
>>> x, y, z = t
This is called, appropriately enough, sequence unpacking and works for
any sequence on the right-hand side. Sequence unpacking requires that
there are as many variables on the left side of the equals sign as
there are elements in the sequence. Note that multiple assignment is
really just a combination of tuple packing and sequence unpacking.
Note that this only works if the user input is of length 2, else the
sequence unpacking will not work and will result in an error.

Why does this predicate leave behind a choicepoint?

I've written the following predicate:
list_withoutlast([_Last], []). % forget the last element
list_withoutlast([First, Second|List], [First|WithoutLast]) :-
list_withoutlast([Second|List], WithoutLast).
Queries like list_withoutlast(X, [1, 2]). succeed deterministically, but queries like list_withoutlast([1, 2, 3], X) leave behind a choicepoint, even though there's only one answer.
When I trace it seems to be that SWI attempts to match list_withoutlast([3], Var) against both clauses, even though definitely only the first one will ever match!
Is there something else I can do to tell SWI that I want a list with more than one element? Or, if I want to take advantage of first-argument indexing, are my only options "zero-length list" and "non-zero length list"?
Do other Prologs handle this situation any differently?
You can rewrite your predicate to avoid the spurious choice point:
list_withoutlast([Head| Tail], List) :-
list_withoutlast(Tail, Head, List).
list_withoutlast([], _, []).
list_withoutlast([Head| Tail], Previous, [Previous| List]) :-
list_withoutlast(Tail, Head, List).
This definition takes advantage of first-argument indexing, which will distinguish in the list_withoutlast /3 predicate the first clause, which have an atom (the empty list) in the first argument, from the second clause, which have a (non-empty) list in the first argument.
Passing the head and tail of an input list argument as separate arguments to an auxiliary predicate is a common Prolog programming idiom to take advantage of first-argument indexing and avoid spurious choice-points.
Note that most Prolog systems don't apply deep term indexing. In particular, for compound terms, indexing usually only takes into account the name and arity and doesn't take into account the compound term arguments (a list with one element and a list with two or more elements share the same functor).

How would you structure a spreadsheet app in elm?

I've been looking at elm and I really enjoy learning the language. I've been thinking about doing a spreadsheet application, but i can't wrap my head how it would be structured.
Let's say we have three cells; A, B and C.
If I enter 4 in cell A and =A in cell B how would i get cell B to always equal cell A? If i then enter =A+B in cell C, can that be evaluated to 8, and also be updated when A or B changes?
Not sure how to lever Signals for such dynamic behavior..
Regards Oskar
First you need to decide how to represent your spreadsheet grid. If you come from a C background, you may want to use a 2D array, but I've found that a dictionary actually works better in Elm. So you can define type alias Grid a = Dict (Int, Int) a.
As for the a, what each cell holds... this is an opportunity to define a domain-specific language. So something like
type Expr = Lit Float | Ref (Int, Int) | Op2 (Float -> Float -> Float) Expr Expr
This means an expression is either a literal float, a reference to another cell location, or an operator. An operator can be any function on two floats, and two other expressions which get recursively evaluated. Depending on what you're going for, you can instead define specific tags for each operation, like Plus Expr Expr | Times Expr Expr, or you can add extra opN tags for operations of different arity (like negate).
So then you might define type alias Spreadsheet = Grid Expr, and if you want to alias (Int, Int) to something, that might help too. I'm also assuming you only want floats in your spreadsheet.
Now you need functions to convert strings to expressions and back. The traditional names for these functions are parse and eval.
parse : String -> Maybe Expr -- Result can also work
eval : Spreadsheet -> Grid Float
evalOne : Expr -> Spreadsheet -> Maybe Float
Parse will be a little tricky; the String module is your friend. Eval will involve chasing references through the spreadsheet and filling in the results, recursively. At first you'll want to ignore the possibility of catching infinite loops. Also, this is just a sketch, if you find that different type signatures work better, use them.
As for the view, I'd start with read-only, so you can verify hard-coded spreadsheets are evaluated properly. Then you can worry about editing, with the idea being that you just rerun the parser and evaluator and get a new spreadsheet to render. It should work because a spreadsheet has no state other than the contents of each cell. (Minimizing the recomputed work is one of many different ways you can extend this.) If you're using elm-html, table elements ought to be fine.
Hope this sets you off in the right direction. This is an ambitious project and I'd love to see it when you're done (post it to the mailing list). Good luck!

Sort a list of custom objects multiple times by different object properties in vb.net

I want to sort a list of custom objects by multiple object properties.
For example, I have:
MyObject.A
MyObject.B
MyObject.C
I want to sort the list first by the values of property "A", then by B and then by C. All those properties are strings(that may or may not be equal to each other and may or may not consist of/contain number characters).
After digging through web I found something that worked for the case where I only needed to sort the list by one property (by "A" in this example):
MyList.Sort(Function(x, y) x.A.CompareTo(y.A))
That worked fine.
So after that, I figured I just need to do more sorts in correct order and I tried doing something like this:
MyList.Sort(Function(x, y) x.C.CompareTo(y.C))
MyList.Sort(Function(x, y) x.B.CompareTo(y.B))
MyList.Sort(Function(x, y) x.A.CompareTo(y.A))
Which kinda sometimes works and sometimes doesn't. If there are few list entries (<10), it works fine and, for example, if "A" values are equal, the list is sorted by "B" values and if those are equal, then by "C".
But, when I add more entries, it breaks down and only the last sort is correct.
Seems that each next sort doesn't retain the original order of entries it doesn't need to sort.
How would I sort something like this?
MyList = (MyList.OrderBy(Function(i) i.A).
ThenBy(Function(i) i.B).
ThenBy(Function(i) i.C)).ToList()
As to why your existing method did not work: that's the difference between a stable and an unstable sort. According to MSDN, the Sort() method unstable.

Correct use of findall/3, especially the last result argument

I'm a beginner in Prolog and I am dealing with a problem that might seem stupid to you, but I really can't understand what I'm doing wrong! Ok, I have this file fruits.pl and inside that I have something like this:
fruit(apple,small,sweet).
fruit(lemon,small,nosweet).
fruit(melon,big,sweet).
I have already (inside that file made a coexist(X,Y) atom that checks if two fruits can be put together in a plate. It works fine! But now I can't create a suggest(X) that takes as a parameter a fruit and returns a list of fruits that can be put together in the same plate.
The thing is I was trying to make something like that
suggest(X) :- findall(Y,fruit(Y,_,_), List), coexist(X,Y).
What do you think? Every time I try to run this in swi prolog there is a warning 'singleton variable' and when I press
suggest(apple).
then it says false..
sorry for my english :/
Predicates in Prolog do not return anything. You have goals that are satisfied or not and you can interpret that as returning true or false.
Your predicate suggest(X) should contain another parameter that will be bound to the list of fruits that go together with X. An option would be: suggest(X, List) which describes the following relation: List represents all the fruits that go together with X. Then, you could ask:
?- suggest(apple, List).
List = [pear, cherry].
The goal findall(Y, ... , ...) uses the Y variable internally and Y is still unbound after the goal is satisfied. So, you should move coexist(X,Y) inside the second argument of findall/3 which is the goal that is satisfied in all possible ways. Th rule below works only if X is instantiated (suggest(+X, -List)).
suggest(X, List) :- findall(Y, (fruit(Y,_,_), coexist(X, Y)), List).
You can read this as follows: "List represents all fruits Y that coexist with X".
When you try to define a predicate in Prolog, first of all pretend that you have written that predicate already and start with imagining how you would use it. That is, what queries you would like to pose.
To me, it looks as if coexist/2 already describes what you want. BTW, may_coexist/2 might be a more descriptive name. Why do you want this in a separate list? And why using fruit/3 at all? But for the sake of the question let's assume that this makes sense. So essentially you would have now a relation fruit_compatible/2:
fruit_compatible(F, G) :-
fruit(F, _, _),
may_coexist(F, G),
fruit(G, _, _). % maybe you want to add this?
And now, let's assume you want this list too. So you would have a relation fruit_suggestions/2. How to use it?
?- fruit_suggestions(apple, L).
L = [cherry,pear].
or ... should it be rather L = [pear,cherry]? Or both?
?- fruit_suggestions(lemon, L).
L = [orange].
So every time I want a suggestion I have to think of a fruit. Always thinking: what fruit should it be? Fortunately there is a less demanding way in Prolog: Simply use a variable instead of the fruit! Now we should get all suggestions at once!
?- fruit_suggestions(F, L).
F = apple, L = [cherry, pear]
; F = lemon, L = [orange]
; F = cromulon, L = [embiggy, mushfruit].
So we need to implement it such that it will behave that way. findall/3 alone does not solve this. And implementing it manually is far from trivial. But there is setof/3 which handles variables in exactly that manner. Many of the tiny nitty-gritty design decisions have already been made, like that the list will be sorted ascendingly.
fruit_suggestions(F, L) :-
setof(G, fruit_compatible(F, G), L).
Edit: Due to the discussion below, here would be a solution that also permits empty lists. Note that this sounds trivial but it is not. To see this, consider the query:
?- fruit_suggestions(F, []).
What does it mean? What should F be? Also things that are no fruits at all? In that case we would have to produce solutions for everything. Like F = badger ; F = 42 ; .... Most probably this does not make much sense. What might be intended is those fruits that are incompatible with everything. To this end, we need to add a new rule:
fruit_suggestions(F, []) :-
setof(t,X^Y^fruit(F,X,Y),_),
\+ fruit_compatible(F, _).
fruit_suggestions(F, L) :-
setof(G, fruit_compatible(F, G), L).