While working through a problem found in 'Functional Programming in Scala':
Implement isSorted, which checks whether an Array[A] is sorted according to a given comparison function:
def isSorted[A](as: Array[A], ordered: (A,A) => Boolean): Boolean
While comparing my answer to the below solution provided by the author(s):
// Exercise 2: Implement a polymorphic function to check whether
// an `Array[A]` is sorted
def isSorted[A](as: Array[A], gt: (A,A) => Boolean): Boolean = {
#annotation.tailrec
def go(n: Int): Boolean =
if (n >= as.length-1) true
else if (gt(as(n), as(n+1))) false
else go(n+1)
go(0)
}
I am getting confused by the following line of code: else if (gt(as(n), as(n+1))) false
I thought when using a function as a parameter in Scala, one would need to actually define a separate function outside the scope of the current function (i.e. have another function defined that does what gt would need to do)? I don't see gt defined anywhere else, so how is it able to provide a Boolean value to use in isSorted?
Are my assumptions correct, or am I completely something missing here with using functions as parameters? A detailed explanation is much appreciated.
In this case, gt is a function passed to isSorted as an argument;
Let's compare it to any other argument, say a: Int. Let's look at the following function:
def increaseByOne(a: Int): Int = a + 1
Your question about gt is equivalent to asking: "How can increaseByOne use a if a is never assigned a value?". Obviously, the caller of the increaseByOne method would have to pass some value as the value of a, but the very concept of arguments is naming some value that is provided into the method.
The same goes for gt: it's an argument of isSorted. In the code you presented, we don't see the caller of isSorted, so we don't see any example of what gt might be - but obviously the implementation of isSorted need not assume anything about how and where gt is created, it is passed as an argument and therefore can be used in isSorted.
We can imagine a usage such as:
isSorted(Array(1,3,6), (a: Int, b: Int) => a > b)
Here, (a: Int, b: Int) => a > b would be the value of gt.
Related
I have read all the posts I can find here about arrays of functions - great you can do it. I figured. But none of the posts show practically how to use them (at least not what I'm trying to do). Here's what I want - they can all take the same args, but that's not a requirement.
This article is close, and will allow me to loop through to execute each function (which meets the first goal).
https://stackoverflow.com/a/24447484/11114752
But... what if I want to execute a single function by reference?
In other words, how to call just the referenced Arity2 function - for example:
// None of these work (with or without the parameter labels)
funcs.Arity2(n: 2, S: "Fred) // value of type [MyFuncs] has no member .Arity2
funcs[Arity2](n: 2, S: "Fred") // no exact matches to call in subscript
funcs[.Arity2](n: 2, S: "Fred") // Cannot call value of non-function type...
let fn = funcs.first(where: { a whole ton of permutations here to try to match Arity2 }) -- a whole lotta frustrating nope...
Help, please! Nothing I've tried works. The pre-compiler just goes in circles making suggestions that don't pan out and it will not compile.
EDIT:
The reason for the array in the first place is that I'm going to have a quite a few functions, and I don't know what they all are in advance. Essentially, I want a plugin type of architecture. Where I can add to the list of functions (ideally within an extension of the class, but that's another problem..) and not change the processing loop that executes each function in order.
I assume you need something like
_ = funcs.first {
if case let MyFuncs.Arity2(f) = $0 {
f(2, "Fred")
return true
}
return false
}
It can be achieved in a much simpler way if you know the position of the function in the array.
Assuming you have:
func someFunc(n: Int, s: String) {
print("call \(n) \(s)")
}
var funcs = [MyFuncs.Arity2(someFunc)]
you can do:
if case .Arity2(let f) = funcs.first {
f(2, "Fred")
}
By replacing funcs.first with funcs[i] you can access the i-th index (first make sure it does exist).
Consider the given two arrays A and B without repetitions (that
is, no double occurrences of the same element). The task is to check whether
each element of B is also an element of A without regard to the order.
For instance if A = [1, 2, 3, 4] and B = [2, 3, 1] then the answer is YES. If
however B = [1, 2, 5] then the answer is NO because 5 is not in A.
Design a recursive algorithm (no use of loops) for the above problem.
I am trying to solve the above problem, and there is no way I can find to solve it without using the loop. Would anyone know a way to solve this with recursion without using a loop?
I can not use any builtin functions, this is a recursion exercise for algorithms and data structures.
You can convert a loop to recursion by designing a recursive function/method that operates on a part of your original array (technically on a sub-array) (initially the sub-array will be your complete array) and reducing the size of the array (each time you are passing to your recursive method) by 1.
The following method (I've the implementation in Java) simply checks if the given number is present in the array/list. But notice that it also takes startIndex and endIndex which specifically denotes our boundaries of sub-array/sub-list.
In simple words the following method checks whether the given number is present in list or not but the check is done only between startIndex and endIndex both inclusive. Consider that you pass each element of your array B (listB in my case) to this method, and list argument is actually a reference to your array A (listA in my case).
/**
* This method recursively checks whether given
* number is contained in the given list or not.
*
* For this method startIndex and endIndex
* correspond to the indices of listA
*/
private static boolean contains(List<Integer> list, int startIndex, int endIndex, int number) {
if (startIndex == endIndex) {
return list.get(startIndex) == number;
} else if (startIndex < endIndex) {
return list.get(startIndex) == number || contains(list, startIndex + 1, endIndex, number);
}
// should never be the case
return true;
}
Now, once you have the above method, you can now device a recursive method that pics up all the elements of listB one at a time, and "plugs it in" inside the above method. This can be preciously done as follows:
/**
* This method recurse over each element of listB and checks
* whether the current element is contained in listA or not
*
* for this method startIndex and endIndex correspond to the
* indices of listB
*/
private static boolean contains(List<Integer> listA, List<Integer> listB, int startIndex, int endIndex) {
if (startIndex > endIndex) {
return true;
}
boolean c = contains(listA, 0, listA.size() - 1, listB.get(startIndex));
if (!c) {
return false;
}
return contains(listA, listB, startIndex + 1, endIndex);
}
And a call to above method will look like contains(listA, listB, 0, listB.size() - 1)
Bingo!! You are done.
I'd like you to think of recursive functions in a specific manner. Think of them as like what arguments it take, and what it does. So when you have a recursive call inside the recursive method, you don't need to think how that recursive call will work, rather have an abstraction there and believe that the recursive call will give you the result. Now focus on how you can use this returned result to make this recursive method correctly work.
One way is to turn a simple iterative algorithm -- with a nested loop -- into a recursive one.
An iterative solution, which is not optimised to use a map, but has a O(n²) time complexity, would look like this:
function includesValue(A, v):
for i = 0 to length(A) - 1:
if A[i] == v:
return true
return false
function includesArray(A, B):
for j = 0 to length(B) - 1:
if not includesValue(A, B[j]):
return false
return true
If you translate this into a recursive pattern, you could pass the current index as an extra argument:
function recIncludesValueAfter(A, v, i):
if i >= length(A):
return false
if A[i] == v:
return true
return recIncludesValuesAfter(A, v, i + 1)
function recIncludesSubArray(A, B, j):
if j >= length(B):
return true
if not recIncludesValueAfter(A, B[j], 0):
return false
return recIncludesSubArray(A, B, j + 1)
You would call it with the third argument as 0:
recIncludesSubArray(A, B, 0)
Each of the two recursive functions uses this pattern:
The first if block corresponds to the end of the loop in the iterative version
The second if block corresponds to the body of the for loop in the iterative version (including its potential break-out)
The final recursive call corresponds to the launch of a next iteration in the iterative version.
Optimised by using a Map/Set
If you would need an optimised version, using a set (a map where only the key is important, not the value associated with it), then the iterative version would look like this:
function includesArray(A, B):
setA = new Set
for i = 0 to length(A):
setA.add(A[i])
for j = 0 to length(B) - 1:
if setA.has(B[j]):
return false
return true
Again, we can convert this to a recursive version:
function recAddSubArrayToSet(setA, B, j):
if j >= length(B):
return setA
setA.add(B[j])
return recAddSubArrayToSet(setA, B, j + 1)
function recSetIncludesSubArray(setA, B, j):
if j >= length(B):
return true
if not setA.has(B[j]):
return false
return recSetIncludesSubArray(A, B, j + 1)
function recIncludesSubArray(A, B):
setA = new empty Set
recAddSubArrayToSet(setA, B, 0)
return recSetIncludesSubArray(setA, B, 0)
About built-in functions
You wrote that built-in functions are not allowed. This is a constraint that only makes sense when you have a specific target programming language in mind. In pseudo code there is no concept of built-in functions.
Some languages will provide maps/sets/dictionaries in a way where you can only do something useful with them by calling methods on them (built-in), while other languages will allow you to apply operators (like +) on them, and use an in operator to test membership.
But even getting the size of an array may need a function call in some languages. So this constraint really only makes sense in the context of a specific programming language.
Pseudocode for a function that recursively tests whether the array A contains a given element, x might look something like this:
function isMember(x, A):
if A = [] then return false
if x = A[0] then return true
return isMember(x, A[1..-1])
end
This function is built on the premise that to test if x is a member of A, we can test to see if the first element of A, denoted A[0], is the same as x. If so, we can terminate the function and return true. If not, then call the function again, passing it all the elements of array A except the first one that we already tested. I've denoted the remaining elements of A with A[1..-1], i.e. element numbers 1 through to -1, which in some languages is another way to refer to the last element.
Now during the second call to this function, x is being compared to the first element of A[1..-1], which is, of course, the second element of A. This recurses over and over, each time shrinking the size of array A the element at the top of the list is tested and discarded.
Then we eventually reach the final case, where there are no more elements left in A to test, which results in the final recursive call to the function being passed an empty array. In this situation, we can infer that every element in A failed to match with x, and so we can safely return false, stating the x is not a member of A.
Now, in order to determine whether a given array B is contained by array A, each element in B needs to undergo the test described above. If isMember() returns true for every element in B, then B must be contained by A. If any one element causes isMember() to return false, then we can stop further testing because B contains elements that are not in A, so it cannot be a subarray.
Here's some pseudocode that illustrates this recursive process:
function containedBy(B, A):
if B = [] then return true
let x := B[0]
if not isMember(x, A) then return false
return containedBy(B[1..-1], A)
end
It's very similar in many ways to the first function, which isn't surprising. This time, however, array B is reduced in size with each recursion, as its lead element is passed through to the isMember() function, then discarded upon isMember() returning true. As before, the final case after the last recursive call to containedBy() passes through an empty list in place of B. This can only mean that every element of B successfully passed the membership test with A, so we return true to confirm that B is, indeed, contained by A.
Accessing collection elements in Scala is done by apply method. Having said that I tried to read numbers from standard input and get the second one as int in just one line.
def main(args: Array[String]): Unit = {
val number = StdIn.readLine().split(" ").map(_.toInt)(1)
}
IntelliJ marks this 1 and show the error (the same is shown after the compilation attempt):
Error:(11, 60) type mismatch; found : Int(1) required:
scala.collection.generic.CanBuildFrom[Array[String],Int,?]
val number = StdIn.readLine().split(" ").map(_.toInt)(1)
Folding the expression in the parentheses dosn't help as well. However, when I split mapping input to int array and getting the element to other lines, everything works fine.
def main(args: Array[String]): Unit = {
val numbers = StdIn.readLine().split(" ").map(_.toInt)
numbers(1)
}
The explicit invocation of apply also does the job:
val number = StdIn.readLine().split(" ").map(_.toInt).apply(1)
Why does this weird behaviour happens? Obtaining element via array(5) is just a shortcut for array.apply(5), isn't it?
As compiler already pointed out, map is defined with two arg lists. second one containing a single implicit param: implicit bf: CanBuildFrom[Repr, B, That]
For a vast majority of scenarios, the users don't worry about specifying the second arg. Specifically, in your case this is what the compiler "figures out":
StdIn.readLine().split(" ").map(_.toInt)(Array.canBuildFrom[Int])
So, if writing out apply is not desired then the following is the only choice:
StdIn.readLine().split(" ").map(_.toInt)(Array.canBuildFrom[Int])(1)
It's a bit counter-intuitive that adding a set of parentheses still doesn't quite do the trick:
( StdIn.readLine().split(" ").map(_.toInt) )(1) //does not compile, same error
Perhaps it's best to demonstrate what's going with a simpler example. Consider the following function:
def add(x:Int)(y:Int) = x + y
The type of add(2) is Int => Int (since we haven't specified y). Note that adding a set of parentheses around it doesn't change the return type, i.e. (add(2)) still has a type Int => Int. Similarly, (Array("1").map(_.toInt))(1) still requires an instance of CanBuildFrom before using shorthand for apply.
Suggested reading about Scala collections:
The Architecture of Scala Collections
Getting to know CanBuildFrom (without a PhD)
and implicit scope:
Scala Specification <- as comprehensive as it gets
Where does Scala look for implicits?
You're getting a collision with an implicit argument to map. This is one of the cases apply needs to be invoked explicitly.
Here's some REPL that replicates the error:
scala> class Foo {
def apply() { println("bar") }
}
scala> def makeFoo(): Foo = new Foo
scala> makeFoo()()
bar // got the println from the apply here
scala> def makeFooImplicit()(implicit x: Int): Foo = new Foo
scala> implicit val x = 5
scala> makeFooImplicit()()
<console>:11: error: not enough arguments for method makeFooImplicit:(implicit x: Int)Foo.
Unspecified value parameter x.
makeFooImplicit()()
I'm trying to add functionality to an Array class.
So I attempted to add a sort() similar to Ruby's lexicon.
For this purpose I chose the name 'ricSort()' if deference to Swift's sort().
But the compiler says it can't find an overload for '<', albeit the 'sort({$0, $1}' by
itself works okay.
Why?
var myArray:Array = [5,4,3,2,1]
myArray.sort({$0 < $1}) <-- [1, 2, 3, 4, 5]
myArray.ricSort() <-- this doesn't work.
Here's a solution that is close to what you are looking for, followed by a discussion.
var a:Int[] = [5,4,3,2,1]
extension Array {
func ricSort(fn: (lhs: T, rhs: T) -> Bool) -> T[] {
let tempCopy = self.copy()
tempCopy.sort(fn)
return tempCopy
}
}
var b = a.ricSort(<) // [1, 2, 3, 4, 5]
There are two problems with the original code. The first, a fairly simple mistake, is that Array.sort returns no value whatsoever (represented as () which is called void or Unit in some other languages). So your function, which ends with return self.sort({$0 < $1}) doesn't actually return anything, which I believe is contrary to your intention. So that's why it needs to return tempCopy instead of return self.sort(...).
This version, unlike yours, makes a copy of the array to mutate, and returns that instead. You could easily change it to make it mutate itself (the first version of the post did this if you check the edit history). Some people argue that sort's behavior (mutating the array, instead of returning a new one) is undesirable. This behavior has been debated on some of the Apple developer lists. See http://blog.human-friendly.com/swift-arrays-the-bugs-the-bad-and-the-ugly-incomplete
The other problem is that the compiler does not have enough information to generate the code that would implement ricSort, which is why you are getting the type error. It sounds like you are wondering why it is able to work when you use myArray.sort but not when you try to execute the same code inside a function on the Array.
The reason is because you told the compiler why myArray consists of:
var myArray:Array = [5,4,3,2,1]
This is shorthand for
var myArray: Array<Int> = [5,4,3,2,1]
In other words, the compiler inferred that the myArray consists of Int, and it so happens that Int conforms to the Comparable Protocol that supplies the < operator (see: https://developer.apple.com/library/prerelease/ios/documentation/General/Reference/SwiftStandardLibraryReference/Comparable.html#//apple_ref/swift/intf/Comparable)[1]. From the docs, you can see that < has the following signature:
#infix func < (lhs: Self, rhs: Self) -> Bool
Depending on what languages you have a background in, it may surprise you that < is defined in terms of the language, rather than just being a built in operator. But if you think about it, < is just a function that takes two arguments and returns true or false. The #infix means that it can appear between its two functions, so you don't have to write < 1 2.
(The type "Self" here means, "whatever the type is that this protocol implements," see Protocol Associated Type Declaration in https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/Declarations.html#//apple_ref/doc/uid/TP40014097-CH34-XID_597)
Compare this to the signature of Array.sort: isOrderedBefore: (T, T) -> Bool
That is the generic signature. By the time the compiler is working on this line of code, it knows that the real signature is isOrderedBefore: (Int, Int) -> Bool
The compiler's job is now simple, it just has to figure out, is there a function named < that matches the expected signature, namely, one that takes two values of type Int and returns a Bool. Obviously < does match the signature here, so the compiler allows the function to be used here. It has enough information to guarantee that < will work for all values in the array. This is in contrast to a dynamic language, which cannot anticipate this. You have to actually attempt to perform the sort in order to learn if the types can actually be sorted. Some dynamic languages, like JavaScript, will make every possible attempt to continue without failing, so that expressions such as 0 < "1" evaluate correctly, while others, such as Python and Ruby, will throw an exception. Swift does neither: it prevents you from running the program, until you fixed the bug in your code.
So, why doesn't ricSort work? Because there is no type information for it to work with until you have created an instance of a particular type. It cannot infer whether the ricSort will be correct or not.
For example, suppose instead of myArray, I had this:
enum Color {
case Red, Orange, Yellow, Green, Blue, Indigo, Violet
}
var myColors = [Color.Red, Color.Blue, Color.Green]
var sortedColors = myColors.ricSort() // Kaboom!
In that case, myColors.ricSort would fail based on a type error, because < hasn't been defined for the Color enumeration. This can happen in dynamic languages, but is never supposed to happen in languages with sophisticated type systems.
Can I still use myColors.sort? Sure. I just need to define a function that takes two colors and returns then in some order that makes sense for my domain (EM wavelength? Alphabetical order? Favorite color?):
func colorComesBefore(lhs: Color, rhs: Color) -> Bool { ... }
Then, I can pass that in: myColors.sort(colorComesBefore)
This shows, hopefully, that in order to make ricSort work, we need to construct it in such a way that its definition guarantees that when it is compiled, it can be shown to be correct, without having to run it or write unit tests.
Hopefully that explains the solution. Some proposed modifications to the Swift language may make this less painful in the future. In particular creating parameterized extensions should help.
The reason you are getting an error is that the compiler cannot guarantee that the type stored in the Array can be compared with the < operator.
You can see the same sort closure on an array whose type can be compared using < like an Int:
var list = [3,1,2]
list.sort {$0 < $1}
But you will get an error if you try to use a type that cannot be compared with <:
var URL1 = NSURL()
var URL2 = NSURL()
var list = [URL1, URL2]
list.sort {$0 < $1} // error
Especially with all the syntax you can leave out in Swift, I don't see a reason to define a method for this. The following is valid and works as expected:
list.sort(<)
You can do this because < actually defines a function that takes two Ints and returns a Bool just like the sort method is expecting.
What's the best Python idiom for this C construct?
while ((x = next()) != END) {
....
}
I don't have the ability to recode next().
update: and the answer from seems to be:
for x in iter(next, END):
....
#Mark Harrison's answer:
for x in iter(next_, END):
....
Here's an excerpt from Python's documentation:
iter(o[, sentinel])
Return an iterator object.
...(snip)... If the second argument, sentinel, is given, then o must be
a callable object. The iterator
created in this case will call o
with no arguments for each call to its
next() method; if the value returned
is equal to sentinel,
StopIteration will be raised,
otherwise the value will be returned.
It depends a bit what you want to do. To match your example as far as possible, I would make next a generator and iterate over it:
def next():
for num in range(10):
yield num
for x in next():
print x
Short answer: there's no way to do inline variable assignment in a while loop in Python. Meaning that I cannot say:
while x=next():
// do something here!
Since that's not possible, there are a number of "idiomatically correct" ways of doing this:
while 1:
x = next()
if x != END:
// Blah
else:
break
Obviously, this is kind of ugly. You can also use one of the "iterator" approaches listed above, but, again, that may not be ideal. Finally, you can use the "pita pocket" approach that I actually just found while googling:
class Pita( object ):
__slots__ = ('pocket',)
marker = object()
def __init__(self, v=marker):
if v is not self.marker:
self.pocket = v
def __call__(self, v=marker):
if v is not self.marker:
self.pocket = v
return self.pocket
Now you can do:
p = Pita()
while p( next() ) != END:
// do stuff with p.pocket!
Thanks for this question; learning about the __call__ idiom was really cool! :)
EDIT: I'd like to give credit where credit is due. The 'pita pocket' idiom was found here
Maybe it's not terribly idiomatic, but I'd be inclined to go with
x = next()
while x != END:
do_something_with_x
x = next()
... but that's because I find that sort of thing easy to read
What are you trying to do here?
If you're iterating over a list, you can use for e in L where e is the element and L is the list. If you're filtering a list, you can use list comprehensions (i.e. [ e for e in L if e % 2 == 0 ] to get all the even numbers in a list).
Can you provide more information about what you're trying to accomplish? It's not clear to me why you can't just say
for x in everything():
...
and have the everything function return everything, instead of writing a next function to just return one thing at a time. Generators can even do this quite efficiently.
If you need to do this more than once, the pythonic way would use an iterator
for x in iternext():
do_something_with_x
where iternext would be defined using something like
(explicit is better than implicit!):
def iternext():
x = next()
while x != END:
yield x
x = next()