Swiftpack.co - Package - mattpolzin/Poly


MIT license Swift 4.2 Swift 5.0 Build Status

Poly is a small library to provide an alternative to rolling your own type-erasure when a value has one of a small set of Types. The Poly library contains the Types Poly1, Poly2, Poly3, etc. for representing increasingly larger pools of possible Types. Poly2 is isomorphic Either (a common generic functional programming Type).

Dev Environment


  1. Swift 4.2+
  2. Swift Package Manager 5.0 OR Cocoapods


To use this framework in your project via Cocoapods instead of Swift Package Manager, add the following dependency to your Podfile.

	pod 'Poly', :git => 'https://github.com/mattpolzin/Poly.git'

Xcode project

To create an Xcode project for Poly, run swift package generate-xcodeproj


Usage will be explained by way of an example. Suppose you have some code with three different Types: Dog, Cat, and Rat. You also have a protocol, Animal, that they all belong to.

If you need to store animals of all three Types in one place (maybe an array), that looks like:

let dog = Dog()
let cat = Cat()
let rat = Rat()

let animals: [Poly3<Dog, Cat, Rat>] = [

To access all animals of a certain type, you can use subscripting like:

let dogs = animals[Dog.self]
let cats = animals[Cat.self]
let rats = animals[Rat.self]

You can get the Dog, Cat, or Rat value back out again, but you won't get any guarantees of which Type is being stored in a given Poly:

let animal = Poly3<Dog, Cat, Rat>(Dog())

let maybeDog: Dog? = animal.a
let maybeCat: Cat? = animal.b
let maybeRat: Rat? = animal.c

Or use the subscript operator to make accessing one of the possible values of a Poly a bit more intuitive:

let maybeDog2 = animal[Dog.self]
let maybeCat2 = animal[Cat.self]
let maybeRat2 = animal[Rat.self]

Or switch over the possible values:

switch animal {
  case .a(let dog):
  case .b(let cat):
  case .c(let rat):

You might consider making a typealias to make your life easier:

typealias AnyAnimal = Poly3<Dog, Cat, Rat>

You also might find it worthwhile to go the extra mile and add Animal conformance to Poly<Dog, Cat, Rat>:

protocol Animal {
  var speak: String { get }

extension Poly3: Animal where A == Dog, B == Cat, C == Rat {
  var speak: String {
    switch self {
      case .a(let animal as Animal),
           .b(let animal as Animal),
           .c(let animal as Animal):
          return animal.speak

So now you can take the array of animals from the first example above and:

let animalSounds = animals.map { $0.speak }


Stars: 0
Help us keep the lights on


Used By



2.0.0 - Apr 17, 2019

Breaking change: Requires Swift Tools version 5.0 (shipped with Xcode 10.2).

1.1.0 - Apr 15, 2019

1.0.0 - Jan 14, 2019

Added ability to access sub-collections based on Type using the subscript operator.

0.1.0 - Jan 13, 2019

Already proven to be a really useful set of Types for me, but I might want to consider adding some monad or functor sugar into the mix before calling this 1.0