GithubHelp home page GithubHelp logo

emilien-io / swift-phantom-type-example Goto Github PK

View Code? Open in Web Editor NEW
0.0 1.0 0.0 11 KB

In this project, we are trying to demonstrate the power of phantom types. Based on a class custom type, we show how we could handle generic bank transfers to local account (USD to USD) and specific transfers (USD to EUR) while adding type-checks at compile time.

Swift 100.00%
phantom-types swift

swift-phantom-type-example's Introduction

Phantom types

Ambiguous data is arguably one of the most common sources of bugs and problems within apps in general. While Swift helps us avoid many sources of ambiguity through its strong type system and thorough compiler — whenever we’re unable to create a compile-time guarantee that a given piece of data will always match our requirements, there’s always a risk that we’ll end up in an ambiguous or unpredictable state.

This week, let’s take a look at a technique that can let us leverage Swift’s type system to perform even more kinds of data validation at compile time — removing more potential sources of ambiguity, and helping us preserve type safety throughout our code base — by using phantom types. (John Sundell, on swiftbysundell)

In this project, we are trying to demonstrate the power of phantom types. Based on a class custom type, we show how we could handle generic bank transfers to local account (USD to USD) and specific transfers (USD to EUR) while adding type-checks at compile time.

  • class BankAccount<CurrencyType>

    Our main class is instantiated using a CurrencyType and for that we will be using an enum containing enums but without cases (see below). This is what we call phantom type, instead of creating a value that would differentiate your objects, you use a phantom type that will not be instantiated be used as a marker.

enum Currency {
    enum Dollar {}
    enum Euro {}
}

This way you can create many BankAccount that will conform to different APIs based on their custom types.

Note: This code has for only purpose of being an example. You could easily make the whole thing more generic by checking the type of your object during a transfer, for example if self is BankAccount<Currency.Dollar>.

Going further

In addition, you can manage the behaviour of your object with extensions based on its type. For example, you can say that an USD account trying to transfer money to an external account that the destination has to be in EUR (for example because exchange in other currency is not handled yet).

extension BankAccount where CurrencyType == Currency.Dollar {
	func transferUSDEUR(_ value: Double, to receiver: BankAccount<Currency.Euro>) {
		...
	}
}

Example

let accountUSD1 = BankAccount<Currency.Dollar>("USD1", withBalance: 1000.0)
let accountUSD2 = BankAccount<Currency.Dollar>("USD2", withBalance: 1000.0)
let accountEUR1 = BankAccount<Currency.Euro>("EUR1", withBalance: 1000.0)

accountUSD1.transfer(200, to: accountUSD2)
accountUSD1.transfer(200, to: accountEUR1)
// ^- This line won't compile since the `transfer(_, _)`
//  method only works with accounts with the same `CurrencyType`

accountUSD1.transferUSDEUR(100, to: accountEUR1)
accountUSD1.transferUSDEUR(100, to: accountUSD2)
// ^- This line won't compile since the `transferUSDEUR(_, _)`
//  method asks for a destination account in EUR

accountUSD1.transferEURUSD(100, to: accountEUR1)
// ^- This line won't compile since the `transferEURUSD(_, _)`
//  method is only available for account in EUR

Few references

swift-phantom-type-example's People

Contributors

emilien-io avatar

Watchers

 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.