Skip to content
This repository was archived by the owner on Jan 10, 2023. It is now read-only.

Reduce some boilerplate without needing higher-kinded types. #7

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions Sources/StructuralCore/Forwardable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// A type that can be converted to and from its structural representation.
public protocol Forwardable {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this just what the Structural protocol provides?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I thought about conforming all the StructuralCons types to Structural themselves, but was concerned that was a little too meta... but if you're intrigued by that direction too, then perhaps it's worth while to explore what that might look like. :-D

/// A structural representation for `Self`.
associatedtype Underlying

/// A structural representation of `self`.
var underlying: Underlying { get set }
}

extension StructuralStruct: Forwardable {
public typealias Underlying = Properties
public var underlying: Properties {
get { properties }
set { properties = newValue }
}
}

extension StructuralProperty: Forwardable {
public typealias Underlying = Value
public var underlying: Value {
get { value }
set { value = newValue }
}
}

extension StructuralEnum: Forwardable {
public typealias Underlying = Cases
public var underlying: Cases {
get { cases }
set { cases = newValue }
}
}

// TODO: StructuralCase?
23 changes: 9 additions & 14 deletions Sources/StructuralExamples/CustomEquatable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ public protocol CustomEquatable {

// Inductive cases.

extension Forwardable where Underlying: CustomEquatable {
public func customEqual(_ other: Self) -> Bool {
return underlying.customEqual(other.underlying)
}
}
extension StructuralProperty: CustomEquatable where Value: CustomEquatable {}
extension StructuralStruct: CustomEquatable where Properties: CustomEquatable {}

extension StructuralCons: CustomEquatable
where Value: CustomEquatable, Next: CustomEquatable {
public func customEqual(_ other: Self) -> Bool {
Expand Down Expand Up @@ -51,29 +59,16 @@ where AssociatedValues: CustomEquatable {
}
}

extension StructuralProperty: CustomEquatable
where Value: CustomEquatable {
public func customEqual(_ other: Self) -> Bool {
return value.customEqual(other.value)
}
}

extension StructuralEnum: CustomEquatable
where Cases: CustomEquatable {
public func customEqual(_ other: Self) -> Bool {
cases.customEqual(other.cases)
}
}

extension StructuralStruct: CustomEquatable
where Properties: CustomEquatable {
public func customEqual(_ other: Self) -> Bool {
properties.customEqual(other.properties)
}
}

// Base cases.

// This would go away with https://github.com/google/swift-structural/pull/5 (except for empty structs).
extension StructuralEmpty: CustomEquatable {
public func customEqual(_ other: StructuralEmpty) -> Bool {
return true
Expand Down
21 changes: 5 additions & 16 deletions Sources/StructuralExamples/CustomHashable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,26 +63,15 @@ where RawValue: CustomHashable, AssociatedValues: CustomHashable {
}
}

extension StructuralProperty: CustomHashable
where Value: CustomHashable {
extension Forwardable where Underlying: CustomHashable {
public func customHash(into hasher: inout Hasher) {
value.customHash(into: &hasher)
underlying.customHash(into: &hasher)
}
}

extension StructuralEnum: CustomHashable
where Cases: CustomHashable {
public func customHash(into hasher: inout Hasher) {
cases.customHash(into: &hasher)
}
}

extension StructuralStruct: CustomHashable
where Properties: CustomHashable {
public func customHash(into hasher: inout Hasher) {
properties.customHash(into: &hasher)
}
}
extension StructuralProperty: CustomHashable where Value: CustomHashable {}
extension StructuralEnum: CustomHashable where Cases: CustomHashable {}
extension StructuralStruct: CustomHashable where Properties: CustomHashable {}

// Base cases.

Expand Down