I am trying practice writing transducers in swift, but I cannot successfully translate this functional javascript code to swift.
http://phuu.net/2014/08/31/csp-and-transducers.html
function mapping(transform) {
return function (reduce) {
return function (result, input) {
return reduce(result, transform(input));
};
};
}
func mapping<T,U> ( transform:(T)-> T ) -> ( (U,T)-> ( (U,T)->U ) ) {
return { ( transducer:(U,T) ) -> ( (U,T)->U ) in
return { (initial:U,element:T) -> U in
var transformedElement = transform(element);
var mInitial = transducer(initial,transformedElement); // this line is the problem
return mInitial;
}
}
func addOne (a:Int) -> (Int) {
return a+1;
}
func concat (c:Array<Int>,element:Int) -> (Array<Int>) {
var collection = c;
collection.append(element);
return collection;
}
var example3 = [1,2,3].reduce([], concat( mapping ( addOne ) ) );
According to http://phuu.net/2014/08/31/csp-and-transducers.html
and http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming,
a reducing function has the signature
whatever, input -> whatever
In Swift, this is a function (or closure) of the type
(U, T) -> U
(using the usual short names T, U for generic types).
A transducer is a function that takes one reducing function as an argument
and returns another reducing function
(whatever, input -> whatever) -> (whatever, input -> whatever)
The corresponding Swift type is
((U,T) -> U) -> (U,T) -> U
mapping() takes a transformation as an argument an returns a transducer,
so it must be defined as
func mapping<T,U> (transform:(T) -> T) -> ((U,T)->U) -> (U,T) -> U
(Also the parameter in the first inner function of mapping is better called
"reducer" instead of "transducer", because it is the argument of the return value.)
In your example,
concat : ([Int], Int) -> [Int]
is a reducing function and mapping(addOne) is a transducer, therefore
mapping(addOne)(concat) : ([Int], Int) -> [Int]
is another reducing function, so that
var example3 = [1,2,3].reduce([], mapping(addOne)(concat))
gives the result [2,3,4].
Complete sample code:
func mapping<T,U> (transform:(T) -> T) -> ((U,T)->U) -> (U,T) -> U {
return { (reducer:((U,T) -> U)) -> (U,T) -> U in
return { (initial:U, element:T) -> U in
return reducer(initial,transform(element))
}
}
}
func addOne (a:Int) -> (Int) {
return a+1;
}
// Slightly simplified and generalized:
func concat<T> (c:[T], element:T) -> [T] {
return c + [element];
}
var example3 = [1,2,3].reduce([], mapping (addOne)(concat))
println(example3) // [2, 3, 4]
Related
I recently downloaded the Advanced NSOperations sample app from Apple and found this code...
// Operators to use in the switch statement.
private func ~=(lhs: (String, Int, String?), rhs: (String, Int, String?)) -> Bool {
return lhs.0 ~= rhs.0 && lhs.1 ~= rhs.1 && lhs.2 == rhs.2
}
private func ~=(lhs: (String, OperationErrorCode, String), rhs: (String, Int, String?)) -> Bool {
return lhs.0 ~= rhs.0 && lhs.1.rawValue ~= rhs.1 && lhs.2 == rhs.2
}
It seems to use the ~= operator against Strings and Ints but I've never seen it before.
What is it?
Simply use as a shortcut to "range": you can construct a range and "~=" means "contains".
(other can add more theoretical details, but the sense is this). Read it as "contains"
let n: Int = 100
// verify if n is in a range, say: 10 to 100 (included)
if n>=10 && n<=100 {
print("inside!")
}
// using "patterns"
if 10...100 ~= n {
print("inside! (using patterns)")
}
try with some values of n.
Is used widely for example in HTTP response:
if let response = response as? HTTPURLResponse , 200...299 ~= response.statusCode {
let contentLength : Int64 = response.expectedContentLength
completionHandler(contentLength)
} else {
completionHandler(nil)
It is an operator used for pattern matching in a case statement.
You can take a look here to know how you can use and leverage it providing your own implementation:
http://oleb.net/blog/2015/09/swift-pattern-matching/
http://austinzheng.com/2014/12/17/custom-pattern-matching/
Here is a simple example of defining a custom one and using it:
struct Person {
let name : String
}
// Function that should return true if value matches against pattern
func ~=(pattern: String, value: Person) -> Bool {
return value.name == pattern
}
let p = Person(name: "Alessandro")
switch p {
// This will call our custom ~= implementation, all done through type inference
case "Alessandro":
print("Hey it's me!")
default:
print("Not me")
}
// Output: "Hey it's me!"
if case "Alessandro" = p {
print("It's still me!")
}
// Output: "It's still me!"
You can look into Define Swift
func ~=<I : IntervalType>(pattern: I, value: I.Bound) -> Bool
func ~=<T>(lhs: _OptionalNilComparisonType, rhs: T?) -> Bool
func ~=<T : Equatable>(a: T, b: T) -> Bool
func ~=<I : ForwardIndexType where I : Comparable>(pattern: Range<I>, value: I) -> Bool
I am playing around with the custom operator >>> for function composition that is suggested here.
I have defined the following:
infix operator >>> { associativity left }
func >>> <A, B, C>(f: B -> C, g: A -> B) -> (A -> C) {
return { x in f(g(x)) }
}
func toChars(s: String) -> [Character] {
return s.characters.reduce([]) { (acc, c) in acc + [c] }
}
func myReverse(xs: [Character]) -> String {
if let (head, tail) = xs.decompose {
return String(myReverse(tail)) + String(head)
}
return ""
}
Now, when I want to put together those two functions like this:
func reverseString(s: String) -> String {
return myReverse >>> toChars
}
I am getting the compiler error:
Cannot convert value of type ([Character]) -> String to expected
argument type _ -> _.
According to my understanding this should work. >>> is defined to take two functions f : B -> C and g : A -> B. Looking at the structure of my usage, the following becomes clear:
g in this case is toChar : String -> [Character], so A is String and B is [Character]
f in this case is myReverse : [Character] -> String, so B is [Character] and C is String
This matches the type definitions form above, however I am still getting a compiler error. Does anyone know what I am doing wrong? Is there a syntax issue with the code?
Note, I am using an Array extension where the function decompose is defined like so:
var decompose : (head: Element, tail: [Element])? {
if count > 0 {
return (self[0], Array(self[1..<count]))
}
return nil
}
myReverse >>> toChars returns a closure of type String -> String,
you still have to call the closure with a string argument:
func reverseString(s: String) -> String {
return (myReverse >>> toChars)(s)
}
But what you probably want is:
let reverseString = myReverse >>> toChars
In both cases, reverseString has the type String -> String,
so you can call it as
print(reverseString("foo"))
// oof
am studying with a tutorial for a game app and there is a line of code that i didn't understood it looks like it's of type tuple
this is my code:
var algorithmResult = algorithm(value: value)
func rowCheck(#value: Int) -> (location: String, pattern: String)? {
var acceptableFinds = ["011", "101", "110"]
var findFunc = [checkTop, checkBottom, checkMiddleAcross, checkRight, checkMiddleDown, checkLeft, checkDiagLeftRight, checkDiagRightLeft]
for algorithm in findFunc {
var algorithmResult = algorithm(value: value)
if (find(acceptableFinds, algorithmResult.pattern) != nil) {
return algorithmResult
}
}
return nil
}
In:
var algorithmResult = algorithm(value: value)
algorithm represents one element in the findFunc array (as defined in for algorithm in findFunc).
From the names, I'm guessing each of those elements is a function. Those functions are passed value and the result of the function is stored in algorithmResult.
Here's a similar example. Create two functions:
func add(operand : Int) -> Int {
return operand + operand
}
func multiply(operand : Int) -> Int {
return operand * operand
}
Store them in an array:
let funcs = [add, multiply]
Call them in a loop:
for function in funcs {
let x = function(5)
print(x)
}
This prints:
10
25
It applies each function from findFunc array to the value, which was passed to rowCheck function.
I would like to have a function returning a function that returns a function with the same signature as the first function. I.e. the function should be able to provide itself as a return value.
Is this possible in swift?
Example (this does not compile!):
typealias nextStep = ((char: CChar) -> nextStep)
func process(char: CChar) -> nextStep {...}
Thomas's answer should work, but if you want a more typesafe alternative:
struct F {
let f: (Character) -> F
}
func f(ch: Character) -> F {
println("I've been called with an \(ch)!")
return F(f: f)
}
let g = f("a")
let h = g.f("b")
h.f("c")
Use Anylike this:
typealias nextStep = ((char: CChar) -> Any)
func process(char: CChar) -> nextStep {
return process
}
The below code throws the error ,'Int' is not a subtype of '()'
func addHelpFunction() -> (Int -> Int){
func adderfunc() -> Int {
return 6
}
return adderfunc
}
Now, if I parameterise the inner function it works fine
func addHelpFunction() -> (Int -> Int){
func adderfunc(number: Int) -> Int {
return 6
}
return adderfunc
}
after compiling the code , it throws a new error "failed with exit code 254"
Your addHelpFunction() function is returning a function typed as (Int) -> (Int). In your first example, you are returning adderFunc() that is typed as () -> (Int) and thus violates the required return type. In your second example, adderFunc() is typed properly.
Note that a more idiomatic way to implement addHelpFunction() is to return an anonymous closure as:
func addHelpFunction() -> (Int -> Int) {
return { (n:Int) -> (Int) in return 6 }
}
In action:
41> var ret6 = addHelpFunction()
ret6: (Int -> Int) =
42> ret6(10)
$R19: (Int) = 6
Perhaps using the idiomatic closure will avoid the possible compiler error.