overload operator as generic function - swift

i saw an example on "Pro swift" book.
it overloaded the operator, the first parameter "lhs" is a function that takes T -> U.
but "generateRandomNumber" function is Int -> Int
How can it work on >>> operator?
how does it work?
thanks.
import Foundation
infix operator >>> { associativity left }
func >>> <T, U, V>(lhs: T -> U, rhs: U -> V) -> T -> V {
return { rhs(lhs($0)) }
}
func generateRandomNumber(max: Int) -> Int {
let number = Int(arc4random_uniform(UInt32(max)))
print("Using number: \(number)")
return number
}
func calculateFactors(number: Int) -> [Int] {
return (1...number).filter { number % $0 == 0 }
}
func reduceToString(numbers: [Int]) -> String {
return numbers.reduce("Factors: ") { $0 + String($1) + " " }
}
let combined = generateRandomNumber >>> calculateFactors >>>
reduceToString
print(combined(100))

see the documentation about generics.
let combined = generateRandomNumber >>> calculateFactors >>> reduceToString
print(generateRandomNumber.dynamicType)
print(calculateFactors.dynamicType)
print(reduceToString.dynamicType)
print(combined.dynamicType)
/*
Int -> Int
Int -> Array<Int>
Array<Int> -> String
Int -> String
*/

Related

Swift 4.0 Difference between implementing custom operator inside a type as a type method and in global scope as a global function

Given a Parser type as following:
public struct Parser<Result> {
internal let parse: (String) -> (Result, String)?
public func run(_ string: String) -> (Result, String)? {
guard let (result, remainder) = parse(string) else { return nil }
return (result, remainder)
}
public func map<T>(_ transform: #escaping (Result) -> T )
-> Parser<T> {
return Parser<T> { input in
guard let (result, remainder) = self.run(input) else { return nil }
return (transform(result), remainder)
}
}
public func followed<A>(by other: Parser<A>) -> Parser<(Result, A)> {
return Parser<(Result, A)> { input in
guard let (result, remainder) = self.run(input) else { return nil }
guard let (resultA, remainderA) = other.run(remainder) else { return nil }
return ((result, resultA), remainderA)
}
}
}
First implementation as following:
infix operator >>> : FunctionCompositionPrecedence
public func >>> <A, B> (lhs: Parser<A>, rhs: Parser<B>)
-> Parser<(A,B)> {
return lhs.followed(by: rhs)
}
Second implementation as following:
infix operator >>> : FunctionCompositionPrecedence
extension Parser {
public static func >>> <A, B> (lhs: Parser<A>, rhs: Parser<B>)
-> Parser<(A,B)> {
return lhs.followed(by: rhs)
}
}
Reclaim the question as what is the difference between the first implementation and the second one.
Moreover, when I use the first implementation, and compile the following code, the compiler reported an error as
"'map' produces 'Parser', not the expected contextual result type 'Parser'"
extension Parser {
public static func apply <A, B> (_ lhs: Parser<(A)->B>, _ rhs: Parser<A>) -> Parser<B> {
return (lhs >>> rhs).map{(arg) -> B in let (f, x) = arg; return f(x)}
}
}
However, after I use the second implementation, everything goes fine.
I am so confused about the essential nuances between them.
With
infix operator >>> : FunctionCompositionPrecedence
extension Parser {
public static func >>> <A, B> (lhs: Parser<A>, rhs: Parser<B>)
-> Parser<(A,B)> {
return lhs.followed(by: rhs)
}
}
You've provided no way for the compiler to infer the generic placeholder Result on calling the operator (really I think the compiler should error here rather than on usage). Remember that static methods on generic types are called on specialisations of those types; the placeholders must be satisfied (as they're accessible at static scope).
So to directly answer
what is the difference between the first implementation and the second one.
The main difference is that as a static member, you have the additional generic placeholder Result that needs to be satisfied; as a top-level function, you don't have that.
So, if you want to keep >>> as a static method, you'll want to use the Result placeholder in the signature of your operator implementation such that the compiler can infer its type on usage, for example:
infix operator >>> : FunctionCompositionPrecedence
extension Parser {
public static func >>> <B> (
lhs: Parser, rhs: Parser<B>
) -> Parser<(Result, B)> {
return lhs.followed(by: rhs)
}
}
Now Result can be inferred from the type of the argument passed as the lhs of the operator (Parser is syntactic sugar for Parser<Result> in this context).
Note you'll face a similar problem with
extension Parser {
public static func apply <A, B> (_ lhs: Parser<(A)->B>, _ rhs: Parser<A>) -> Parser<B> {
return (lhs >>> rhs).map{(arg) -> B in let (f, x) = arg; return f(x)}
}
}
in that you'll need to explicitly satisfy the Result placeholder when calling; although the type used to satisfy it won't actually be used by the method.
Better would be to use the Result placeholder in the signature to allow the compiler to infer it at the call-site:
extension Parser {
public static func apply<Arg>(
_ lhs: Parser<(Arg) -> Result>, _ rhs: Parser<Arg>
) -> Parser<Result> {
return (lhs >>> rhs).map { arg -> Result in
let (f, x) = arg
return f(x)
}
}
}
// ...
let p = Parser<(String) -> String> { input in ({ $0 + input }, "hello") }
let p1 = Parser { ($0, "") }
let p2 = Parser.apply(p, p1)
print(p2.run(" world") as Any) // Optional(("hello world", ""))
Or, better still, as an instance method:
extension Parser {
public func apply<A, B>(with rhs: Parser<A>) -> Parser<B>
where Result == (A) -> B {
return (self >>> rhs).map { arg -> B in
let (f, x) = arg
return f(x)
}
}
}
// ...
let p = Parser<(String) -> String> { input in ({ $0 + input }, "hello") }
let p1 = Parser { ($0, "") }
let p2 = p.apply(with: p1)
print(p2.run(" world") as Any) // Optional(("hello world", ""))

About Swift functions, named parameters, and type management

Suppose I have a function overloaded as such:
func doMath(mathOption: String) -> (Int...) -> Double {
...
return average
}
func doMath(mathOption: String) -> ([Int]) -> Double {
...
return average
}
Side note: Function average itself is overloaded to accept both an array as an input or a list of parameters.
Two questions:
1 - How do I reference which function I am referring to?
For example:
let doAverage = doMath(mathOption: "average")
How do I specify which doMath function I'm calling? Swift is confused and can't infer from the next line:
If I later write:
doAverage(1,2,3,4)
2 - How do I name parameters? The original average function is called thus:
average(nums: 1,2,3,4)
I have to name the parameters. Yet with doAverage, I can't name parameters because of how the return type is defined.
3 - How could I create a type (perhaps using struct?) to simplify this hypothetical code.
Thanks for any help, explanation, or answers you offer!
Edit, to clarify 3, here is the expanded version of the situation:
func sumAll(nums: [Int]) -> Double {
return Double(nums.reduce(0, { (a,b) in a+b}))
}
func sumAll(nums: Int...) -> Double {
return sumAll(nums: nums)
}
func average(nums: [Int]) -> Double {
return sumAll(nums: nums) / Double(nums.count)
}
func average(nums: Int...) -> Double {
return average(nums: nums)
}
func doMath(mathOption: String, nums: Int...) -> Double {
if mathOption == "average" {
return average(nums: nums)
} else {
return sumAll(nums: nums)
}
}
typealias mathReturnType1 = (Int...) -> Double
typealias mathReturnType2 = ([Int]) -> Double
func doMath(mathOption: String) -> mathReturnType1 {
return average
}
func doMath(mathOption: String) -> mathReturnType2 {
return average
}
I've used typealias to create two example types. Could a type be overloaded somehow to handle both situations? To me, this makes sense in that if the same function is being overloaded to handle different inputs, why not the type? Perhaps this is a naive perspective or perhaps there is a way to express what I'm thinking in Swift?
How to reference the function? Just specify the type!
func doMath(mathOption: String) -> (Int...) -> Double {
return { (values: Int...) -> Double in
return Double(values.reduce(0, +)) / Double(values.count)
}
}
func doMath(mathOption: String) -> ([Int]) -> Double {
return { (values: [Int]) -> Double in
return Double(values.reduce(0, +)) / Double(values.count)
}
}
let average1 = doMath(mathOption: "x") as (Int...) -> Double
print(average1(1, 2, 3))
or
let average1: (Int...) -> Double = doMath(mathOption: "x")
print(average1(1, 2, 3))
I would also advise to to name that type using a typealias.
Your second question - you cannot name parameters in function types.
You can pass the function you want done to doMath as a parameter. And use generics so you have some extensibility.
func doMath<T>(using op: (T) -> Double, with value: T) -> Double {
return op(value)
}
doMath(using: sumAll, with: [1,2,3])
// returns 6
Edit: It's having trouble with the variadic parameter.
Another edit: Found a workaround.
func doMath<T>(using op: ([T]) -> Double, with value: T...) -> Double {
return op(value)
}
func doMath<T>(using op: (T) -> Double, with value: T) -> Double {
return op(value)
}
doMath(using: sumAll, with: 1,2,3,4,5) //15
doMath(using: sumAll, with: [1,2,3,4,5]) // 15
Also, here's a prettier way to write that reduce:
Double(nums.reduce(0, +))

How to use Anonymous Closure in Swift?

A closure function :
func makeIncrementer(externNumber:Int) -> (Int -> Int) {
func addOne(number: Int) -> Int {
return externNumber + number
}
return addOne
}
I want to use Anonymous Closure to achieve it, so I write this :
func my_makeIncrementer(externNumber:Int) -> (Int -> Int) {
return {
(number:Int)-> Int { // Error : cannot create a single-element tuple with an element label ;
return externNumber + number ;
} ;
}
}
You can see, Xcode throw a error
Error : cannot create a single-element tuple with an element label
You should re-look up the syntax here:
func my_makeIncrementer(externNumber:Int) -> (Int -> Int) {
return {
(number:Int)-> Int in
return externNumber + number
}
}

YCombinator not working in Swift

I am trying to create a lambda function as such to get a factorial function but this throws a segmentation fault and errors out. How do I get this working in Swift. Please look at this video for reference on what I am trying to do http://www.confreaks.com/videos/1287-rubyconf2012-y-not-adventures-in-functional-programming
typealias f = () -> ()
typealias g = (Int) -> (Int)
typealias F = Any -> g
let y = { (gen: Any) -> g in
(gen as F)(gen)
}
let fact = y({ (gen: Any) -> g in
{ (n: Int) -> Int in
if n == 0 {
return 1
} else {
return n * (gen as F)(gen)(n - 1)
}
}
})
fact(10)
There's a great post by xiliangchen that walks through creating a Y-combinator in Swift. (Technically, this isn't a Y-combinator, since it is explicitly recursive, but it largely does what you want.) Here's an example of that Y function (stripped of its generic specification for clarity):
typealias G = Int -> Int
func Y (f: G -> G) -> G {
return {
(i: Int) -> Int in
f(Y(f))(i)
}
}
let factorial = Y { (f: G) -> G in
{ (n: Int) -> Int in
if n == 0 {
return 1
} else {
return n * f(n - 1)
}
}
}
factorial(5) // 120
For more on Y-combinators, you can look at this terrific (long) piece by Mike Vanier.
(Note: Using Any is kind of a mess -- I'd recommend steering clear of it whenever you can, especially since you don't need it in this case.)
You can implement a real (without explicit recursion) Y combinator using a recursive type, without any unsafe tricks (credits to Rosetta Code):
struct RecursiveFunc<F> {
let o : RecursiveFunc<F> -> F
}
func Y<A, B>(f: (A -> B) -> A -> B) -> A -> B {
let r = RecursiveFunc<A -> B> { w in f { w.o(w)($0) } }
return r.o(r)
}
let factorial = Y { (f: Int -> Int) -> Int -> Int in
{ $0 <= 1 ? 1 : $0 * f($0-1) }
}
println(factorial(10))
Any doesn't really help because Any cannot represent function types.
Update: Starting in Xcode 6.1 beta 3, Any can represent function types, and your code compiles and works correctly.
This is an implementation in modern Swift that actually compiles under Swift 5.7. It has the proper modern closure syntax and declares as escaping the escaping closures.
import Foundation
struct RecursiveFunc<T> {
let o : (RecursiveFunc<T>) -> T
}
func Y<A, B>(f: #escaping (#escaping (A) -> B) -> (A) -> B) -> (A) -> B {
let r = RecursiveFunc<(A) -> B> { w in f { w.o(w)($0) } }
return r.o(r)
}
let fac = Y { (f: #escaping (Int) -> Int) in
{ $0 <= 1 ? 1 : $0 * f($0-1) }
}
func fact (_ n: Int) -> Int {
if n == 0 { return 1 }
else { return n * fact (n-1) }
}
print (fact(19))
print (fac (19))
NB: code pasted from a PlayGround

Generate an integer binary representation using Swift?

How to create a function accepting any type of Int or Uint in swift
(and calculating number of bits needs regarding param type)
String has constructors
init<T : _SignedIntegerType>(_ v: T, radix: Int, uppercase: Bool = default)
init<T : _UnsignedIntegerType>(_ v: T, radix: Int, uppercase: Bool = default)
which can be used here:
let num = 100
let str = String(num, radix: 2)
print(str)
// Output: 1100100
Here's a little shorter version. It doesn't add extra leading zeroes though:
func bitRep<T: IntegerArithmeticType>(value: T) -> String {
var n: IntMax = value.toIntMax()
var rep = ""
while(n > 0){
rep += "\(n % 2)"
n = n / 2;
}
return rep
}
let binStr:Int->String = {a in return String(a, radix: 2)}
binStr(7) // "111"
Here's a function using Generics in order to accept any type of Int or Uint without param conversion needs.
1- The function needs to constraint a value type conforming to "ToInt" protocol
in order to offer an unique method to convert self type to Int
2- The function calculates length bit needs regarding param type
3- The function insert space every 8 digits to offer legibility
protocol ToInt { func toInt() -> Int }
extension UInt: ToInt { func toInt() -> Int { return Int(self) } }
extension Int8: ToInt { func toInt() -> Int { return Int(self) } }
extension UInt8: ToInt { func toInt() -> Int { return Int(self) } }
extension Int16: ToInt { func toInt() -> Int { return Int(self) } }
extension UInt16: ToInt { func toInt() -> Int { return Int(self) } }
extension Int32: ToInt { func toInt() -> Int { return Int(self) } }
extension UInt32: ToInt { func toInt() -> Int { return Int(self) } }
extension Int64: ToInt { func toInt() -> Int { return Int(self) } }
extension UInt64: ToInt { func toInt() -> Int { return Int(self) } }
func bitRep<T:ToInt>(value: T) -> String {
var size: Int
switch value {
case is Int8, is UInt8: size = 7
case is Int16, is UInt16: size = 15
case is Int32, is UInt32: size = 31
case is Int64, is UInt64: size = 63
default : size = 63
}
var n = value.toInt()
var rep = ""
for (var c = size; c >= 0; c--) {
var k = n >> c
if (k & 1) == 1 { rep += "1" } else { rep += "0" }
if c%8 == 0 && c != 0 { rep += " " }
}
return rep
}
Some examples:
let b1: UInt8 = 0b00000000
bitRep(b1)
// > "00000000"
let c1: UInt16 = 0b00000000_10000101
bitRep(c1)
// > "00000000 10000101"
let e1: UInt64 = 0b00000000_00000000_00000000_00000001
bitRep(e1)
// > "00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001"
and so on!
(algo inspired from this thread: Turning an integer to its binary representation using C?)