Giter Site home page Giter Site logo

chrisballinger / poly Goto Github PK

View Code? Open in Web Editor NEW

This project forked from mattpolzin/poly

0.0 2.0 0.0 43 KB

A general-purpose library to help represent situations where the type of a value is one of a set of types.

License: MIT License

Swift 90.46% Ruby 9.54%

poly's Introduction

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 to Either (a common generic functional programming Type).

Dev Environment

Prerequisites

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

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

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>] = [
  .init(dog),
  .init(cat),
  .init(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):
    print(dog)
  case .b(let cat):
    print(cat)
  case .c(let rat):
    print(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 }

Codable

All of the Polytypes are Encodable/Decodable when every generic on which they are specialized is Ecodable/Decodable. This works by attempting to encode or decode each type and using the first successfuly attempt. That means the behavior only works as expected if all of the types have different encoding/decoding requirements or at least types are ordered with more restrictive rules coming first.

For example, given the following type

struct Type1: Decodable {
    let x: Poly2<Double, Int> 
}

an integer value will never be decoded as an Int because Double is capable of decoding all Int values.

You can fix this by swapping the order to Poly2<Int, Double>. Now Poly will attempt to decode an Int and only attempt to decode a Double if an Int was not found.

poly's People

Contributors

mattpolzin avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.