I see that Swift offers convenient syntax for declaring curried functions. The manual gives partial function application as an example of where curried function will come in handy.
Can someone give me an example where partial function application can be useful? I know this is a general functional programming concept, but an example in Swift would be most appreciated.
Suppose you frequently want to check a number, i, is a multiple of another value. What it might be a multiple of can change, but the rule for how to determine it is always the same: i % n == 0.
You might write a function like this:
func isMultipleOf(#n: Int, #i: Int) -> Bool {
return i % n == 0
}
isMultipleOf(n: 2, i: 3) // false
isMultipleOf(n: 2, i: 4) // true
However, perhaps you find yourself frequently wanting to use this function with other "high-order" functions – that is, functions that take other functions as arguments, such as map and filter:
let r = 1...10
// use isMultipleOf to filter out the even numbers
let evens = filter(r) { isMultipleOf(n: 2, i: $0) }
// evens is now [2,4,6,8,10]
That use of isMultipleOf looks a little clunky and hard to read, so maybe you define a new function, isEven, in terms of isMultipleOf to make it a bit clearer:
let isEven = { isMultipleOf(n: 2, i: $0) }
isEven(2) // true
isEven(3) // false
let evens = filter(r, isEven)
Now, suppose you declare isMultipleOf a little differently, as a curried function:
func isMultipleOf(#n: Int)(#i: Int) -> Bool {
return i % n == 0
}
isMultipleOf is now a function that takes a number, n, and returns a new function that takes a number and checks if it's a multiple of n.
You can now use it to declare isEven like this:
let isEven = isMultipleOf(n: 2)
Or you could use it directly with filter like this:
let evens = filter(r, isMultipleOf(n: 2))
// just like before, evens is [2,4,6,8,10]
Related
I am trying to write a for loop, where I have to increment exponentially. I am using stride function but it won't work.
Here's c++ code, I am trying to write a swift version.
for (int m = 1; m <= high - low; m = 2*m){}
can you help me, to write this code in swift version?
A while-loop is probably the simplest solution, but here is an alternative:
for m in sequence(first: 1, next: { 2 * $0 }).prefix(while: { $0 <= high - low }) {
print(m)
}
sequence() (lazily) generates the sequence 1, 2, 4, ..., and prefix(while:) limits that sequence to the given range.
A slight advantage of this approach is that m is only declared inside the loop (so that it cannot be used later accidentally), and that is is a constant so that it cannot be inadvertently modified inside the loop.
There is no for loop in Swift, but you can achieve the same result with basic while loop
var m = 1 // initializer
while m <= high - low { // condition
...
m *= 2 // iterator
}
Based on #MartinR answer, only improvement is readability of the call:
// Helper function declaration
func forgen<T>(
_ initial: T, // What we start with
_ condition: #escaping (T) throws -> Bool, // What to check on each iteration
_ change: #escaping (T) -> T?, // Change after each iteration
_ iteration: (T) throws -> Void // Where actual work happens
) rethrows
{
return try sequence(first: initial, next: change).prefix(while: condition).forEach(iteration)
}
// Usage:
forgen(1, { $0 <= high - low }, { 2 * $0 }) { m in
print(m)
}
// Almost like in C/C++ code
Here is a solution using for:
let n = Int(log(Double(high - low))/log(2.0))
var m = 1
for p in 1...n {
print("m =", m)
...
m = m << 1
}
(Supposing that high - low is greater than 2)
I am using a for comprehension on a stream and I would like to know how many iterations took to get o the final results.
In code:
var count = 0
for {
xs <- xs_generator
x <- xs
count = count + 1 //doesn't work!!
if (x prop)
yield x
}
Is there a way to achieve this?
Edit: If you don't want to return only the first item, but the entire stream of solutions, take a look at the second part.
Edit-2: Shorter version with zipWithIndex appended.
It's not entirely clear what you are attempting to do. To me it seems as if you are trying to find something in a stream of lists, and additionaly save the number of checked elements.
If this is what you want, consider doing something like this:
/** Returns `x` that satisfies predicate `prop`
* as well the the total number of tested `x`s
*/
def findTheX(): (Int, Int) = {
val xs_generator = Stream.from(1).map(a => (1 to a).toList).take(1000)
var count = 0
def prop(x: Int): Boolean = x % 317 == 0
for (xs <- xs_generator; x <- xs) {
count += 1
if (prop(x)) {
return (x, count)
}
}
throw new Exception("No solution exists")
}
println(findTheX())
// prints:
// (317,50403)
Several important points:
Scala's for-comprehension have nothing to do with Python's "yield". Just in case you thought they did: re-read the documentation on for-comprehensions.
There is no built-in syntax for breaking out of for-comprehensions. It's better to wrap it into a function, and then call return. There is also breakable though, but it works with Exceptions.
The function returns the found item and the total count of checked items, therefore the return type is (Int, Int).
The error in the end after the for-comprehension is to ensure that the return type is Nothing <: (Int, Int) instead of Unit, which is not a subtype of (Int, Int).
Think twice when you want to use Stream for such purposes in this way: after generating the first few elements, the Stream holds them in memory. This might lead to "GC-overhead limit exceeded"-errors if the Stream isn't used properly.
Just to emphasize it again: the yield in Scala for-comprehensions is unrelated to Python's yield. Scala has no built-in support for coroutines and generators. You don't need them as often as you might think, but it requires some readjustment.
EDIT
I've re-read your question again. In case that you want an entire stream of solutions together with a counter of how many different xs have been checked, you might use something like that instead:
val xs_generator = Stream.from(1).map(a => (1 to a).toList)
var count = 0
def prop(x: Int): Boolean = x % 317 == 0
val xsWithCounter = for {
xs <- xs_generator;
x <- xs
_ = { count = count + 1 }
if (prop(x))
} yield (x, count)
println(xsWithCounter.take(10).toList)
// prints:
// List(
// (317,50403), (317,50721), (317,51040), (317,51360), (317,51681),
// (317,52003), (317,52326), (317,52650), (317,52975), (317,53301)
// )
Note the _ = { ... } part. There is a limited number of things that can occur in a for-comprehension:
generators (the x <- things)
filters/guards (if-s)
value definitions
Here, we sort-of abuse the value-definition syntax to update the counter. We use the block { counter += 1 } as the right hand side of the assignment. It returns Unit. Since we don't need the result of the block, we use _ as the left hand side of the assignment. In this way, this block is executed once for every x.
EDIT-2
If mutating the counter is not your main goal, you can of course use the zipWithIndex directly:
val xsWithCounter =
xs_generator.flatten.zipWithIndex.filter{x => prop(x._1)}
It gives almost the same result as the previous version, but the indices are shifted by -1 (it's the indices, not the number of tried x-s).
I'm pretty new to haskell and I think I'm falling into some OO traps. Here's a sketch of a structure (simplified) that I'm having trouble implementing:
A concept of an Observable that acts on a list of samples (Int) to produce a result (Int)
A concept SimpleObservable that achieves the result using a certain pattern (while there will be Observables that do it other ways), e.g. something like an average
A function instance, e.g. one that's just an average times a constant
My first thought was to use a subclass; something like (the below is kinda contrived but hopefully gets the idea across)
class Observable a where
estimate :: a -> [Int] -> Int
class (Observable a) => SimpleObservable a where
compute :: a -> Int -> Int
simpleEstimate :: a -> [Int] -> Int
simpleEstimate obs list = sum $ map compute list
data AveConst = AveConst Int
instance Observable AveConst where
estimate = simpleEstimate
instance SimpleObservable AveConst where
compute (AveConst c) x = c * x
However, even if something like the above compiles it's ugly. Googling tells me DefaultSignatures might help in that I don't have to do estimate = simpleEstimate for each instance but from discussions around it it seems doing it this way would be an antipattern.
Another option would be to have no subclass, but something like (with the same Observable class):
data AveConst = AveConst Int
instance Observable AveConst where
estimate (AveConst c) list = sum $ map (*c) list
But this way I'm not sure how to reuse the pattern; each Observable has to contain the complete estimate definition and there will be code repetition.
A third way is a type with a function field:
data SimpleObservable = SimpleObservable {
compute :: [Int] -> Int
}
instance Observable SimpleObservable where
estimate obs list =
sum $ map (compute obs) list
aveConst :: Int -> SimpleObservable
aveConst c = SimpleObservable {
compute = (*c)
}
But I'm not sure this is idiomatic either. Any advice?
I propose going even simpler:
type Observable = [Int] -> Int
Then, an averaging observable is:
average :: Observable
average ns = sum ns `div` length ns
If your Observable needs some data inside -- say, a constant to multiply by -- no problem; that's what closures are for. For example:
sumTimesConst :: Int -> Observable
sumTimesConst c = sum . map (c*)
You can abstract over the construction of Observables without trouble; e.g. if you want a SimpleObservable which only looks at elements, and then sums, you can:
type SimpleObservable = Int -> Int
timesConst :: Int -> SimpleObservable
timesConst = (*)
liftSimple :: SimpleObservable -> Observable
liftSimple f = sum . map f
Then liftSimple . timesConst is another perfectly fine way to spell sumTimesConst.
...but honestly, I'd feel dirty doing any of the above things. sum . map (c*) is a perfectly readable expression without introducing a questionable new name for its type.
I do not fully understand the question yet but I'll edit this answer as I learn more.
Something which acts on a list and produces a result can simply be a function. The interface (that is, the type) of this function can be [a] -> b. This says the function accepts a list of elements of some type and returns a result of a possibly different type.
Now, lets invent a small problem as an example. I want to take a list of lists, some function on lists which produces a number, apply this function to every list, and return the average of the numbers.
average :: (Fractional b) => ([a] -> b) -> [[a]] -> b
average f xs = sum (fmap f xs) / genericLength xs
For example, average genericLength will tell me the average length of the sub-lists. I do not need to define any type classes or new types. Simply, I use the function type [a] -> b for those functions which map a list to some result.
I was wondering if there is a method or function in Swift which can count the number of elements in the tuple.
Reason of question:
I have a tuple called "tople"
What I want to do is to load the elements into variables (by using for loop, where you actually need the number of elements)
And then use this in a function.
Additional questions, can you use tuples to load variables into the function and/or to return them from a function?
var tople = (1,2,3)
func funkce (a:Int, b:Int, c: Int){
println(a)
println(b)
println(c)
}
funkce(a,b,c)
Thanks and I do appreciate any helpful comment.
In Swift 3 you count the number of elements in a tuple like this:
let myTuple = (1,2,3,4)
let size = Mirror(reflecting: myTuple).children.count
Yes, you can load tuples into variables.
let (a, b, c) = (1, 2, 3)
To extract values from a tuple, you can use MirrorType. You can find more here.
let tuple = (1, 2, 3)
let count = Mirror(reflecting: tuple).children.count // 3
I'm looking for an expression to assign the smallest and largest of 2 numbers to variables.
There are several approaches that work
let a = 2
let b = 1
let (min, max) = (min(a, b), max(a, b))
But I wanted something a bit more flexible, for example
let sorted = [a, b].sorted{$0 < $1}
let (min, max) = (sorted.first, sorted.last)
But it's 2 lines... I was looking for something like:
let (min, max) = [a, b].sorted{$0 < $1}
But that doesn't compile, I think because it's not possible to deconstruct arrays, at least in this way, and there doesn't seem to be a clean/meaningful way to convert it to a tuple.
What am I missing? I know there's somewhere an elegant expression for this.
I’d just do a variant of your (pre-edit) first one:
let (min,max) = a < b ? (a,b) : (b,a)
If you do this a lot, you could wrap this in a generic function to make it a bit neater:
func minmax<T: Comparable>(a: T, b: T) -> (T,T) {
return a < b ? (a,b) : (b,a)
}
Which makes this quite nice and readable at the call site:
let (min,max) = minmax(a, b)