What's generic types T and U in Swift? - swift

What's generic types T and U in Swift?
take a look about function "func map(transform: (T) -> U) -> [U]"
What's the T?
What's the U?
Does T and U are different?

Its a generic closure that takes T as parameter and return U, T is the array type you want to map and U is the return type of what you want to extract
For example:
let map = ["",""].map { $0.isEmpty }
T is [String] and U is [Bool]

Related

How can a closure in Swift only be passed in a * for the reduce function?

extension Array {
func reduce<T>(_ initial: T, combine: (T, Element) -> T) -> T {
var result = initial
for x in self {
result = combine(result, x)
}
return result
}
}
How does the below function work when it only passes a * to the combine closure?
func productUsingReduce(integers: [Int]) -> Int {
return integers.reduce(1, combine: *)
}
static func * (lhs: Self, rhs: Self) -> Self is an operator function defined on the Numeric protocol. So, you are really just passing in a function that takes two arguments.
What does the declaration mean?
combine: (T, Element) -> T
It says: the combine parameter is a function that takes two parameters, a T and an Element, and returns a T.
Well, in Swift, operators are functions, and * is such a function. So it suffices to pass a reference to this function as the combine parameter. The bare name, *, is that reference.

Generic of Generics ? class A<T<U>>?

Can I somehow force the generic type to have a generic type ?
I want to have some functions, that have as a parameter type U, so how can I do that ?
Code:
class TableViewViewModel<T<U>> {
typealias SectionDataType = T
typealias RowDataType = U
var sections = [SectionDataType<RowDataType>]()
}
Try declaring a protocol SectionDataType that requires an associated type. This means that any conforming type (like Section below) must implement a typealias. Then, in TableViewViewModel you can access the type which you were calling U through that typealias.
protocol SectionDataType {
associatedtype RowDataType
}
struct Section<U>: SectionDataType {
typealias RowDataType = U
}
class TableViewViewModel<T: SectionDataType> {
typealias RowDataType = T.RowDataType
var sections = [T]()
}
All you have to do with a generic, is declare the types (what you are doing with the angle brackets). After that, it's syntax-as-usual. I'm not sure exactly what you want to do, so I'll just post an example. The following function declares three generic types (T, U, Z), takes a type U and a function as parameters, the function itself takes a value of type U and returns a value of type T. All of this returns a value of type Z. (This is a pretty useless func as-is, but an example of how to use generics in a complex fashion):
func myFunc<U,T,Z>(curry : (U) -> T, value : U) -> Z {
return curry(value) as! Z
}

Call function with empty variadic param

I have a function with one variadic param (tuple) like this:
func conditions<T>(conditions: ([String : T], LogicalOperator)...) -> [AnyObject]?
Is there any way how to call it without that param? Somehow pass an empty array of variadic params? I just want to be able to support an option when there are no conditions at all.
You can do it, but not as a generic function. Why? Because it can't infer the type, so the compiler doesn't know what T is, even tho your tuple will be optional. So code below in theory would work, but the execution will fall:
struct Test<T> {
func conditions<T>(conditions: ([String : T], String)?...) -> [AnyObject]? {
return nil
}
}
var t = Test<Int>()
t.conditions() // Error infering type
However, this one does work (if it does satisfy your needs):
struct Test<T> {
typealias testAlias = ([String : T], String)
func conditions(conditions: testAlias...) -> [AnyObject]? {
return nil
}
}
var t = Test<Int>()
t.conditions()
You can accomplish what you want with function overloading.
You could overload your function definition to accept no arguments...
func conditions() -> [AnyObject]?
or, you could overload it to accept an array of your type...
func conditions<T>(conditions: [([String : T], LogicalOperator)]) -> [AnyObject]?
or you could make it accept optional values and pass nil.
func conditions<T>(conditions: ([String : T], LogicalOperator)?...) -> [AnyObject]?

Swift higher order function (Church pair aka cons) with generic parameter types not accepting input parameter types

I was messing around with the functional programming in Swift 2.1, trying to implement the Church encoding pair/cons function (cons = λx λy λf f x y in untyped lambda calculus), which I had read couldn't be done in earlier versions of Swift.
With generics it looks like
func cons<S,T,U>(x:S,_ y:T) -> ((S,T) -> U) -> U
{
return { (f:((S,T) -> U)) -> U in return f(x,y)}
}
cons(1,2)
//error: cannot invoke 'cons' with an argument list of type '(Int, Int)'
//note: expected an argument list of type '(S, T)'
which doesn't work, and gives an error I cannot understand (surely parameter list of type (Int,Int) can match generic type variables (S,T)?)
If you get rid of the generic types, and declare them all Ints, the function works, but of course we want to be able to cons together lists longer than 2; consing a list of length 3 is consing an Int with an (Int,Int) -> Int, for example.
Another option is to type everything as Any (see Type Casting for Any and AnyObject), but I couldn't make that work either.
Do you have any ideas? Is this possible in Swift yet? I'm sure there are simpler ways to implement cons/car/cdr, but I'm specifically interested in the Church encoding, where the list elements are arguments to anonymous functions (lambdas).
func cons<S,T,U>(x:S,_ y:T) -> ((S,T) -> U) -> U
{
return { (f:((S,T) -> U)) -> U in return f(x,y)}
}
let i: ((Int,Int)->Int)->Int = cons(1,2)
let d: ((Int,Int)->Double)->Double = cons(2,3)
let e: ((Double,Int)->String)->String = cons(2.2, 1)
let e: ((Double,Int)->Double)->Double = cons(2.2, 1)
stil one of type is an 'extra' type and could not be inferred by compilator. if you define the types, you can see, that not all combinations are valid. Just define the output type and the compilator should be happy
func cons<S,T, U>(x:S,_ y:T, outptAs: U.Type) -> ((S,T) -> U ) -> U
{
return { (f:((S,T) -> U)) -> U in return f(x,y) }
}
let i = cons(1.2 ,"A", outptAs: Int.self)
let j = cons("alfa","beta", outptAs: Double.self)

Generic within a generic in Swift

Trying to make sense of the code below.
I understand that T is passed by when instantiating the Optional, as in Optional, but what about the U type in map. What type does that assume?
enum Optional<T> : LogicValue, Reflectable {
case None
case Some(T)
init()
init(_ some: T)
/// Allow use in a Boolean context.
func getLogicValue() -> Bool
/// Haskell's fmap, which was mis-named
func map<U>(f: (T) -> U) -> U?
func getMirror() -> Mirror
}
The type U comes from the f parameter to the map function. So if you pass a closure that returns a Int, then map returns a Int?. If you pass a closure that returns a Array<Int>, then map returns a Array<Int>?.
For example, try this:
var opt1: Optional<Int> = .Some(1)
var opt2 = opt1.map { (i: Int) -> String in return "String: \(i)" }
You'll find that opt1 is an Int? and opt2 is a String?.
When calling the map function the caller must provide a single argument which is a closure that:
Has a single argument that is the same type as the one used to
instantiate Optional, i.e. T
Has a return value of some type.
U will then be the type of said return value.