Skip to content

Optional traversal #28

@marcprux

Description

@marcprux

Is there no way to lens through an optional? I've tried with Party.lpartyCaterer() • User.userName and Party.lpartyCaterer() • _Some • User.userName, to no avail.

// A party has a host, an optional caterer and an array of guests
class Party {
    var host : User
    var caterer : User?
    var guests : [User]

    init(h : User, c : User? = nil, g : [User] = []) {
        host = h
        caterer = c
        guests = g
    }

    class func lpartyHost() -> Lens<Party, Party, User, User> {
        let getter = { (party : Party) -> User in party.host }
        let setter = { (party : Party, host : User) -> Party in Party(h: host, c: party.caterer, g: party.guests) }
        return Lens(get: getter, set: setter)
    }

    class func lpartyCaterer() -> Lens<Party, Party, User?, User?> {
        let getter = { (party : Party) -> User? in party.caterer }
        let setter = { (party : Party, caterer : User?) -> Party in Party(h: party.host, c: caterer, g: party.guests) }
        return Lens(get: getter, set: setter)
    }

    class func lpartyGuests() -> Lens<Party, Party, [User], [User]> {
        let getter = { (party : Party) -> [User] in party.guests }
        let setter = { (party : Party, guests : [User]) -> Party in Party(h: party.host, c: party.caterer, g: guests) }
        return Lens(get: getter, set: setter)
    }
}

class PartySpec : XCTestCase {
    func testLens() {
        let party = Party(h: User("max", 1, [], "one"))
        let hostnameLens = Party.lpartyHost()  User.userName

        XCTAssert(hostnameLens.get(party) == "max")

        let updatedParty: Party = (Party.lpartyHost()  User.userName).set(party, "Max")
        XCTAssert(hostnameLens.get(updatedParty) == "Max")

        let catererLens = Party.lpartyCaterer()  User.userName

        let cateredParty: Party = (Party.lpartyCaterer()  User.userName).set(party, "Marc")
        XCTAssert(catererLens.get(updatedParty) == "Marc")

    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions