Linked list declaration in Swift with finger type that can transparently insert in either middle or start - swift

I am attempting to declare a linked list in Swift, with a finger type that is a reference to either a node, allowing to insert or remove beyond that node, or to the linked list itself, in which case inserting or removing at the top of the linked list.
I want to see if this can be made uniform down to the implementation, instead of having to special-case everything: Swift is object-oriented, after all.
I previously had a version which required forced casts, but again I'd like to see if this can be made to work without them (e.g. even if they never end up faulting they still imply runtime checks each time).
I currently have this code:
protocol ContainerNodeInterface: class {
associatedtype ContainedItem;
var contents: ContainedItem { get };
}
protocol ParentNodeInterface: class {
associatedtype LinkedItem: ContainerNodeInterface;
var next: LinkedItem? {get set};
}
class ProtoNode<Contents, NodeType: ParentNodeInterface>: ParentNodeInterface where NodeType.ContainedItem==Contents, NodeType.LinkedItem==NodeType { // not meant to be instantiated or directly referenced
typealias LinkedItem = NodeType;
var next: NodeType?;
init() {
next = nil;
}
final func insertThisAfterMe(_ node: NodeType) {
node.next = next;
next = .some(node);
}
final func removeNodeAfterMe() -> NodeType? {
guard let nextNode = next else {
return nil;
}
let result = nextNode;
next = result.next;
result.next = nil;
return nextNode;
}
}
class Node<Contents>: ProtoNode<Contents, Node<Contents>>, ContainerNodeInterface {
typealias ContainedItem = Contents;
typealias NextItem = Node<Contents>;
var contents: Contents;
init(withContents: Contents) {
contents = withContents;
super.init();
}
}
typealias ParentNode<Contents> = ProtoNode<Contents, Node<Contents>>;
But the Swift compiler, via Xcode, is complaining that Type 'Node<Contents>' does not conform to protocol 'ParentNodeInterface'. This makes no sense! And if I add explicit conformance to ParentNodeInterface to Node, then I get simultaneously that error and one of redundant conformance to the same protocol.
What is missing here?
Xcode Version 10.2 (10E125), Swift 5

I resolved it by splitting ProtoNode into an initial declaration and an extension:
protocol ContainerNodeInterface: class {
associatedtype ContainedItem;
var contents: ContainedItem { get };
}
protocol ParentNodeInterface: class {
associatedtype LinkedItem: ContainerNodeInterface;
var next: LinkedItem? {get set};
}
class ProtoNode<Contents, NodeType: ContainerNodeInterface>: ParentNodeInterface where NodeType.ContainedItem==Contents { // not meant to be instantiated or directly referenced
typealias LinkedItem = NodeType;
var next: NodeType?;
init() {
next = nil;
}
}
extension ProtoNode where NodeType: ParentNodeInterface, NodeType.LinkedItem==NodeType
{
final func insertThisAfterMe(_ node: NodeType) {
node.next = next;
next = .some(node);
}
final func removeNodeAfterMe() -> NodeType? {
guard let nextNode = next else {
return nil;
}
let result = nextNode;
next = result.next;
result.next = nil;
return nextNode;
}
}
class Node<Contents>: ProtoNode<Contents, Node<Contents>>, ContainerNodeInterface {
typealias ContainedItem = Contents;
typealias NextItem = Node<Contents>;
var contents: Contents;
init(withContents: Contents) {
contents = withContents;
super.init();
}
}
typealias ParentNode<Contents> = ProtoNode<Contents, Node<Contents>>;
I figure it helps the compiler break the dependency loop, where it has to determine whether Node, as a generic parameter, conforms to the protocol before it can determine the declaration is valid and consider the declared type, i.e. Node, as conforming to the protocol, but still it feels a bit silly for me to have to make this seemingly pointless extension declaration.
At the very least, the compiler could be slightly more helpful…

First, I would start with a simple linked-list Node type:
final class Node<Value> {
let value: Value
var next: Node<Value>?
init(_ value: Value) {
self.value = value
}
func insert(_ node: Node<Value>) {
node.next = next
next = node
}
func removeNext() -> Node<Value>? {
guard let removedNode = next else { return nil }
next = removedNode.next
removedNode.next = nil
return removedNode
}
}
Then, you can add the concept that you describe: a pointer to "either a node...or to the linked list itself." When you see "or" in a description, that implies a sum type, which in Swift is an enum, either a pointer to the head of a (possibly empty) list, or a pointer to a node. Each has slightly different behaviors, which you manage with switch.
enum NodePointer<Value> {
case head(Node<Value>?)
case node(Node<Value>)
mutating func insert(_ node: Node<Value>) {
switch self {
case .head(let n):
self = .head(node)
node.next = n
case .node(let n):
n.insert(node)
}
}
mutating func removeNext() -> Node<Value>? {
switch self {
case .head(let n):
self = .head(n?.next)
return n
case .node(let n):
return n.removeNext()
}
}
var pointee: Node<Value>? {
switch self {
case .head(let n): return n
case .node(let n): return n
}
}
}
With that you would have an interface like:
var list = Node(1)
list.insert(Node(2))
var ptr = NodePointer.head(list)
ptr.insert(Node(1))
ptr.pointee?.next?.next?.value // 2
Note that the specific problem you ran into (that the compiler couldn't work out the conformance) I believe is a compiler bug, though I also believe it's one that's fixed on master currently. I haven't tested that out though. But I don't believe the protocol-based approach is correct for this problem.

Related

Extends Set's insert in swift for custom logic

I need to have custom logic in a Set that defines when a Hashable can be insert or not.
First I tried to solve this with a observer
var Tenants: Set<Tenant> = [] {
willSet {
// to the business logic here
// ...
But in an observer i can not return an error. So I tried to extend Set to overwrite the insert method.
extension Set where Element == Tenant {
#inlinable mutating func insert(_ newMember: Element) -> (inserted: Bool, memberAfterInsert: Element){
// .... do my logic here ...
return (true, newMember)
}
}
That works so far and the method will be called. I can return true and if my logic did not pass even a false. Ok, but how do I add the Element into the Set? super.insert(). The return is correct, but the Set is empty. How to add the elements into the concrete set?
Implementation so far
/// Global set of known tenants
var Tenants: Set<Tenant> = [] {
willSet {
let newTenants = newValue.symmetricDifference(Tenants)
guard let newTenant = newTenants.first else {
Logging.main.error("Can not find tenant to add.")
return
}
Logging.main.info("Will add new Tenant \(newTenant.name) [\(newTenant.ident)]")
}
}
extension Set where Element == Tenant {
#inlinable mutating func insert(_ newMember: Element) -> (inserted: Bool, memberAfterInsert: Element){
print("Check to add...")
// .... do my logic here ...
// ok
return (true, newMember)
}
}
The result is:
Check to add...
error : Can not find tenant to add.
Check to add...
error : Can not find tenant to add.
This seems to work for "do my logic here"
self = self.union([newMember])
Edit: Because this breaks the semantics of Set, I think it is better to write it as something like this:
struct CheckedSet<T: Hashable> {
private(set) var wrappedSet: Set<T> = []
var shouldInsert: (T) -> Bool = { _ in true }
mutating func maybeInsert(_ t: T) {
guard shouldInsert(t) else { return }
wrappedSet.insert(t)
}
}
var cs = CheckedSet<String>()
cs.shouldInsert = { str in str.allSatisfy(\.isLowercase) }
cs.maybeInsert("HELLO")
cs.wrappedSet // []
cs.maybeInsert("hello")
cs.wrappedSet // ["hello"]
I would do it with a property wrapper:
#propertyWrapper
struct TenantsSet {
var wrappedSet: Set<Tenant>
struct Projected {
let error: Bool
}
var projectedValue = Projected(error: false)
var wrappedValue: Set<Tenant> {
get { wrappedSet }
set {
print("some custom logic")
// set projectedValue appropriately
wrappedSet = newValue
}
}
init(wrappedValue: Set<Tenant>) {
wrappedSet = wrappedValue
}
}
This allows error-reporting by checking the error property on the projected value:
#TenantsSet var tenants = []
func f() {
tenants = [Tenant()]
if $tenants.error {
}
}
As the Swift Guide says:
Extensions add new functionality to an existing class, structure, enumeration, or protocol type.
You are not supposed to use them to modify existing behaviour. It would be very confusing to readers of your code. If you want to use an extension to do this, you should declare a new method, with a different signature. Perhaps call it insert(newTenant:)?

Extension optional Array with Optional Element. Is it even possible?

I have a protocol FooProtocol. and a class Bar<Foo:FooProtocol>. Inside a class an Array var mess: [Foo?]? to keep [foo1, foo2, nil, foo3...] or nil
And I try to make extension for this array to count new Foo object. I prefer to have protocols, because Foos could be very different objects delivered from outer world.
protocol FooProtocol {
....
init(from heaven: Int)
}
extension Optional where
Wrapped: Collection,
Wrapped.Element == Optional,
Wrapped.Element.Wrapped: FooProtocol // 'Wrapped' is not a member type of 'Wrapped.Element'
{
var united: Wrapped.Element.Wrapped { // Nope
let i = ...
return Wrapped.Element.Wrapped(from: i) // Nope
}
}
class Bar<Foo:FooProtocol> {
var mess: [Foo?]?
init (with mess: [Foo?]?) {
self.mess = mess
}
var important: Foo {
return mess.united
}
}
Any ideas? I'm blocked.
Edit 1:
After Leo suggestions I changed some parts of my code. But still stucked. This time more code from Playgrounds.
Any object that could be converted into '[Double]'. Could be color (as RGBA), Bezier curve, square, whatever...
public protocol FooProtocol {
var atomized: () -> [Double] {get}
static var count: Int {get}
init(_ array:[Double])
init()
}
public extension Array where Element: FooProtocol {
var average: Element {
var resultAtoms: [Double] = []
let inputAtoms = self.map {$0.atomized()}
for i in 0..<Element.count {
let s = inputAtoms.reduce(into: 0.0, {$0 += $1[i]}) / Double (Element.count)
resultAtoms.append(s)
}
return Element(resultAtoms)
}
}
extension Optional where
Wrapped: Collection,
Wrapped.Element == Optional<FooProtocol>
{
typealias Foo = Wrapped.Element.Wrapped // Doesn't work. How to get class?
var average: Foo { // I cannot use Wrapped.Element, it's Optional
if let thatsList = self {
let withOptionals = Array(thatsList) // OK, its [Optional<FooProtocol>]
let withoutOptionals = thatsList.compactMap({$0}) // OK, its [FooProtocol]
// This is funny, called from class works and makes 'bingo'.
return withoutOptionals.average // Error: Value of protocol type 'FooProtocol' cannot conform to 'FooProtocol'; only struct/enum/class types can conform to protocols
} else {
return Foo() // Hello? init Wrapped? Foo? How to get Foo()?
}
}
}
class Bar<Foo:FooProtocol> {
var mess: [Foo?]?
init (with mess: [Foo?]?) {
self.mess = mess
}
func workOn() {
let z:Foo = mess.average // OK, I can make 'mess.average ?? Foo()' but prefer not do it
}
// Thats OK
func workHard() { // To prove 'Array extension where Element: FooProtocol' works
if let messExist = mess {
let withoutOptionals = messExist.compactMap({$0})
let bingo = withoutOptionals.average //It's OK
}
}
}
class SomeFoo : FooProtocol {
static var count = 3
required init() {
a = 0
b = 0
c = 0
}
required init(_ array: [Double]) {
self.a = Int(array[0])
self.b = Float(array[1])
self.c = array[2]
}
var atomized: () -> [Double] {
return {return [Double(self.a), Double(self.b), self.c]}
}
var a: Int
var b: Float
var c: Double
}
let aFoo = SomeFoo([1, 2, 3])
let bFoo = SomeFoo([7, 9, 1])
let cFoo = SomeFoo([2, 6, 5])
let barData = [nil, aFoo, nil, bFoo, cFoo]
let barWithData = Bar(with: barData)
let barWithoutData = Bar<SomeFoo>(with: nil)
Maybe I should forget about extending array and make some functions inside a class (I'm almost sure I will need those functions somewhere else)
Edit 2
Even if I try to simplify and to make extension for Array I found troubles.
extension Array where
Element == Optional<FooProtocol>
{
func averageNils <Foo: FooProtocol>() -> Foo {
let withOptionals = Array(self) // OK, its [Optional<FooProtocol>]
let withoutOptionals = self.compactMap({$0}) // OK, its [FooProtocol]
return withoutOptionals.average as! Foo // Error: Value of protocol type 'FooProtocol' cannot conform to 'FooProtocol'; only struct/enum/class types can conform to protocols
}
}
From my understanding, it should work as you did, but one never knows what happens in the swift compiler world (and especially it's error messages).
Anyway, you can circumvent digging deeper into Wrapped.Element.Wrapped by specifyig the Wrapped.Element more precisely to be an Optional<FooProtocol>:
protocol FooProtocol {}
class Foo : FooProtocol {}
extension Optional where
Wrapped: Collection, //OK
Wrapped.Element == Optional<FooProtocol> // still good
{
var unfied: Wrapped.Element // Should be 'Foo' if self is '[Foo?]?' {
{
return 1 == 0 ? nil : Foo()
}
}

Get object type from optional?

Is it possible to get the object type from an optional?
For example, if I have a class that has a property that is an optional string, can I somehow just get back the string type?
The exact use case I have is I have many custom classes all of which have a property that is storing another custom class as an optional value. I would like to write a generic function that will create an instance of the object class stored in the optional.
Here is an example of what I am looking for, although .dynamicType does not work since it is an optional:
class Class1 {
}
class Class2 {
var myOp: Class1?
}
var c = Class2()
c.myOp = c.myOp.dynamicType()
Since you wanted to use this with Generics I tried it for you. It works, but it may not be so useful.
First some setup:
This is a helper protocol to make sure our Generic type will have a known init method.
protocol ZeroParameterInit {
init()
}
This is an extension to get the type from an optional:
extension Optional {
var dynamicWrappedType : Wrapped.Type {
return Wrapped.self
}
}
Implemented in your code:
class Class1 : ZeroParameterInit {
required init() {}
}
class Class2 {
var myOp: Class1?
}
var c = Class2()
c.myOp = c.myOp.dynamicWrappedType.init()
Generic implementation:
class Class1 : ZeroParameterInit {
required init() {}
}
class Class2<T where T : ZeroParameterInit> {
var attribute: Optional<T>// used long syntax to remind you of : Optional<Wrapped>
init(attr:T) {
attribute = attr
attribute = nil
}
}
The function to create the instance:
func myFunc<T>(instance: Class2<T>) -> T {
return instance.attribute.dynamicWrappedType.init()
}
Some tests:
let alpha = Class1()
let beta = Class2(attr: alpha)
beta.attribute = myFunc(beta)
The issue:
You can't create an instance of Class2 without informing it about the type of it's generic attribute. So you need to pass it some object/type and that complicates things again.
Some extra methods that might improve how it all works:
init() {
}
let delta = Class2<Class1>()
delta.attribute = myFunc(delta)
init(type:T.Type) {
}
let epsilon = Class2(type: Class1.self)
epsilon.attribute = myFunc(epsilon)
You just need to check if the optional exist:
func myFunc(c: Class2) -> Class1? {
if let c1 = c.myOp{
return c1.dynamicType()
}
return nil
}
OR
func myFunc(c: Class2) -> Class1? {
if c.myOp != nil{
return c.myOp!.dynamicType()
}
return nil
}
Note the your return type need to be optional as well.
Tried this in simulator, seems like doing the right thing, if I understood you
class Class1 {
}
class Class2 {
var myOp: Class1?
}
func myFunc(c: Class2) -> AnyObject {
if let c1 = c.myOp{
return c1.self
}
return c
}
var object = Class2()
object.myOp = Class1()
myFunc(object) // Class1

Swift generic function calling function with return type overload

just a quick question. I have the following code, which works just fine:
class obA: Printable {
var description: String { get { return "obA" } }
}
class obB: Printable {
var description: String { get { return "obB" } }
}
func giveObject() -> obA { return obA() }
func giveObject() -> obB { return obB() }
var a: obA = giveObject()
var b: obB = giveObject()
println(a)
println(b)
The right variant of giveObject is being called and all is well. Of course this is just a simplified case, in reality in my project there are several dozens of overloads of 'giveObject', all differing in return type. Now, I want to make a generic function to parse all these things. So, next step:
func giveGeneric<T>() -> T {
return giveObject()
}
var c: obA = giveGeneric()
println(c)
And this complains about ambiguous use of giveObject. I can understand where the error comes from, but I don't see right away how I can solve it and use a construct like this...
First of all just a note.
If the generic type of giveGeneric is simply T, then it can be anything (a String, an Int, ...). So how should giveObject() react in this case?
I mean, if you write:
let word : String = giveGeneric()
internally your generic function calls something like:
let result : String = giveObject() // Ambiguous use of giveObject
My solution
I declared a protocol as follow:
protocol MyObject {
init()
}
Then I made your 2 classes conform to the protocol
class obA: Printable, MyObject {
var description: String { get { return "obA" } }
required init() {}
}
class obB: Printable, MyObject {
var description: String { get { return "obB" } }
required init() {}
}
Finally I can write this
func giveGeneric<T:MyObject>() -> T {
return T()
}
Now I can use it:
let a1 : obA = giveGeneric()
let b1 : obB = giveGeneric()
You decide if this is the solution you were looking for or simply a workaround.
That cannot work, even if you implement a giveObject function for any possible type. Since T can be any type, the giveGeneric method cannot determine the correct overload to invoke.
The only way I can think of is by creating a huge swift with as many cases as the number of types you want to handle:
func giveGeneric<T>() -> T? {
switch "\(T.self)" {
case "\(obA.self)":
return giveObject() as obA as? T
case "\(obB.self)":
return giveObject() as obB as? T
default:
return .None
}
}
But I don't think I would use such a solution even with a gun pointed at my head - it's really ugly.
If in all your cases you create instances using a parameterless constructor, then you might create a protocol and constraint the T generic type to implement it:
protocol Instantiable {
init()
}
func giveGeneric<T: Instantiable>() -> T {
return T()
}
You can use with built-in as well as new types - for instance:
extension String : Instantiable {
// `String` already implements `init()`, so nothing to add here
}
let s: String = giveGeneric()
Alternatively, if you prefer you can make the protocol declare a static giveObject method rather than a parameterless constructor:
protocol Instantiable {
static func giveObject() -> Self
}
func giveGeneric<T: Instantiable>() -> T {
return T.giveObject()
}
extension String : Instantiable {
static func giveObject() -> String {
return String()
}
}
let s: String = giveGeneric()

Creating a generic singleton

This is a bit of a head banger (for me). Basically I want to have 2 different singletons that inherit from the same class. In either I want to use a certain class which itself is derived. So I have Utility and both AUtil:Utility and BUtil:Utility. And Singleton that is used as ASingleton using AUtility in its stomach and B respectively. I failed on all frontiers. The last attempt was a factory pattern which simply got Swift 1.2 to Segfault:
protocol Initializable { init() }
class A:Initializable {
var x = "A"
required init() {}
}
class B:Initializable {
var x = "B"
required init() {}
}
class C {
let t:Initializable
init(t:Initializable) {
self.t = t
println(t)
}
func factory() {
println(t.dynamicType())
}
}
As said I also tried to make the following pattern generic:
private let _SingletonSharedInstance = StaticClass()
class StaticClass {
class var sharedInstance : StaticClass {
return _SingletonSharedInstance
}
}
let s = StaticClass.sharedInstance
(This one isn't generic as you see. But all my attempts failed and so I show my starting point.)
Anyway I seem to be lost between doom and death.
Do you mean something like this?
protocol Initializable: class { init() }
private var instances = [String: Initializable]()
func singletonInstance<T: Initializable>(_ ty: T.Type = T.self) -> T {
let name = NSStringFromClass(ty)
if let o = (instances[name] as? T) {
return o
}
let o = ty()
instances[name] = o
return o
}
An use-side of it, for instance.
class Foo: Initializable { required init() {} }
class Bar: Initializable { required init() {} }
let foo1 = singletonInstance() as Foo // or `singletonInstance(Foo.self)`
let foo2 = singletonInstance() as Foo
assert(foo1 === foo2)
let bar1 = singletonInstance() as Bar
let bar2 = singletonInstance() as Bar
assert(bar1 === bar2)
(I've tested the code above and got it to work in Swift 1.2.)
Inspired by findalls implementation, I build my own singleton generator, which is a little more powerful.
You can create a singleton of any Class or Structure type in Swift. The only thing you have to do is to implement one of two different protocols to your type and use Swift 2.0 or newer.
public protocol SingletonType { init() }
private var singletonInstances = [String: SingletonType]()
extension SingletonType {
// this will crash Xcode atm. it's a Swift 2.0 beta bug. Bug-ID: 21850697
public static var singleton: Self { return singleton { $0 } }
public static func singleton(setter: (_: Self) -> Self) -> Self {
guard let instance = singletonInstances["\(self)"] as? Self else {
return setInstance(self.init(), withSetter: setter, overridable: true)
}
return setInstance(instance, withSetter: setter, overridable: false)
}
private static func setInstance(var instance: Self, withSetter setter: (_: Self) -> Self, overridable: Bool) -> Self {
instance = restoreInstanceIfNeeded(instance1: instance, instance2: setter(instance), overridable: overridable)
singletonInstances["\(self)"] = instance
return instance
}
private static func restoreInstanceIfNeeded(instance1 i1: Self, instance2 i2: Self, overridable: Bool) -> Self {
// will work if the bug in Swift 2.0 beta is fixed !!! Bug-ID: 21850627
guard i1.dynamicType is AnyClass else { return i2 }
return ((i1 as! AnyObject) !== (i2 as! AnyObject)) && !overridable ? i1 : i2
}
}
This may look a little scary, but don't be afraid of this code. The public function inside the protocol extension will create two access points for you.
For example you will be able to write code like this now:
// extend your type: as an example I will extend 'Int' here
extension Int : SingletonType {} // nothing else to do, because Int already has an 'init()' initializer by default
// let the magic happen
Int.singleton // this will generate a singleton Int with 0 as default value
Int.singleton { (_) -> Int in 100 } // should set your Int singleton to 100
Int.singleton { $0 - 55 } // your singleton should be 45 now
// I need to mention that Xcode will produce the setter like this and trow an error
Int.singleton { (yourCustomInstanceName) -> Self in // replace 'Self' with 'Int' and you should be fine
return yourCustomInstanceName
}
// btw. we just ignored the return value everywhere
print(Int.singleton) // will print 45 here
var singleton2 = Int.singleton { $0 + 5 }
singleton2 += 10
print(Int.singleton) // should print 50, because 'singleton2' is just a copy of an Int value type
class A : SingletonType {
var name = "no name"
required init() {}
}
A.singleton { $0; let i = A(); i.name = "hello world"; return i } // custom init on first singleton call for type A
print(A.singleton.name)
print(A.singleton { $0.name = "A"; return $0 }.name)
print(A.singleton.name)
// should print "hello world" and twice the string "A"
If you have any idea how to enhance this code and make it even safer, please let me know. I will push this code on GitHub (MIT License) soon, so everyone can benefit from it.
UPDATE: I modified the code a little so you can now pass a custom initialized instance of a class with the setter function when its called the first time.
UPDATE 2: I removed ClassInstance protocol and modified the private restore function. The Instance protocol is now called SingletonType. The setter function is not optional anymore. Right now Xcode 7 beta 3 will crash and provide an illegal instruction: 4 error when you will call the getter. But this is a confirmed beta bug.