pointfreeco / swift-tagged Goto Github PK
View Code? Open in Web Editor NEW๐ท A wrapper type for safer, expressive code.
Home Page: https://www.pointfree.co/episodes/ep12-tagged
License: MIT License
๐ท A wrapper type for safer, expressive code.
Home Page: https://www.pointfree.co/episodes/ep12-tagged
License: MIT License
Consider the following:
enum _StringTag { }
typealias MyString = Tagged<_StringTag, String>
let aString = "bar"
let myString = MyString(aString)
Compiler complains that the MyString.init()
call is ambiguous. I would expect this to just work, since I am passing a String
where RawValue == String
.
[...]:18:16: error: ambiguous use of 'init(_:)'
let myString = MyString(aString)
^
[...]/Tagged.swift:9:10: note: found this candidate
public init(_ rawValue: RawValue) {
^
[...]/Tagged.swift:199:10: note: found this candidate
public init?(_ description: String) {
And indeed, from Tagged.swift
:
[...]
public init(_ rawValue: RawValue) {
self.rawValue = rawValue
}
[...]
extension Tagged: LosslessStringConvertible where RawValue: LosslessStringConvertible {
public init?(_ description: String) {
guard let rawValue = RawValue(description) else { return nil }
self.init(rawValue: rawValue)
}
}
Hi, I updated to the latest version and I run into an issue with custom date decoding. I think commit 4e607f7 broke that, and now a custom date decoding strategy can't be used for Tagged types, it is simply ignored. This seems like a swift bug to me, but for now I think the best option is to revert that change.
Hi there ๐
I was noticing that since the merge of #10, my projects using Tagged
have more transitive dependencies.
This seems due to this dependency specifier in Package.swift
:
.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.2.0"),
From what I can see in the rest of Package.swift
, none of the library or test targets depend on any targets from XcodeGen
. I'm curious if/why this is needed, or if it's something that can be removed.
Thanks!
I just discovered that when a dictionary whose keys are a Tagged
type, they get encoded as an array of alternating {key}
, {value}
, ... pairs instead of as an actual object. This is a well known problem with Dictionaries of non "simple" key types (see here, and apparently a (relatively) new solution to this is to have the key type implement the CodingKeyRepresentable
protocol.
I was able to add this conformance to Tagged
as an extension, but it made me wonder if it makes sense for this conformance to be added to Tagged
directly.
Has the latest version (0.4
) deployed to CocoaPods?
brad$ pod install --repo-update
Updating local specs repositories
Analyzing dependencies
[!] CocoaPods could not find compatible versions for pod "Tagged":
In Podfile:
Tagged (~> 0.4)
None of your spec sources contain a spec satisfying the dependency: `Tagged (~> 0.4)`.
You have either:
* mistyped the name or version.
* not added the source repo that hosts the Podspec to your Podfile.
Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.
I tried implementing conformity to EntityIdentifierConvertible
in AppIntents, but I couldn't make it work. I'd like to be able to do the following:
import Tagged
struct Route: Identifiable, Codable, Sendable {
typealias ID = Tagged< Route, String>
let id: ID
}
import AppIntents
struct RouteEntity: AppEntity, Identifiable {
var id: Route.ID
var name: String
// ...
}
Now, as a work-around I define id in the entity as Route.ID.RawValue
but that defeats the purpose a bit. What do you think?
๐ hi, thank you for this library and your work on point free. Curious if there will be a new release with the changes in master
since 0.4.0
.
Please remove, I made a mistake ;)
swift-tagged/Sources/Tagged/Tagged.swift
Line 207 in 926e8e0
I get the following error
error: conditional conformance of type 'Tagged<Tag, RawValue>' to protocol 'Value' does not imply conformance to inherited protocol 'Expressible'
both when I try
extension Tagged: Value where Tag == MyTag, RawValue == Int {
public static var declaredDatatype = Int.declaredDatatype
public typealias ValueType = Tagged<MyTag, Int>
public typealias DataType = Int
public var datatypeValue: Int {
return self.rawValue
}
public static func fromDatatypeValue(_ datatypeValue: Int) -> Tagged<MyTag, Int> {
return Tagged<MyTag, Int>(datatypeValue)
}
}
and when I try
extension Tagged: Value where Tag == MyEntity, RawValue == Int {
public static var declaredDatatype = Int.declaredDatatype
public typealias ValueType = MyEntity.Id
public typealias DataType = Int
public var datatypeValue: Int {
return self.rawValue
}
public static func fromDatatypeValue(_ datatypeValue: Int) -> MyEntity.Id {
return MyEntity.Id(datatypeValue)
}
}
So I try to add Expressible
to the list of conformances, but I can't figure out how to implement Expressible
s requirements. If I don't try to add a function to conform to Expressible
, I get a crash.
Fatal error: 'try!' expression unexpectedly raised an error:
Unexpected null value for column `"my_entity_id"`:
file .build/checkouts/SQLite.swift/Sources/SQLite/Typed/Query.swift, line 1113
In a current project I am using Tagged
as the Interval
of a type Note
conforming to Strideable
. This works great as far as it goes. However, I have a ClosedRange<Note>
on which I would like to be able to compute count
. This requires Tagged
conform to SignedInteger where RawValue: SignedInteger
.
Tagged
has a number of conditional conformances and does conditionally support Numeric
and SignedNumeric
, there currently is not support for SignedInteger
as far as I can tell. I'm curious if this was intentionally left out, or if it would be reasonable to add?
Hey @stephencelis and @mbrandonw!
I'm using Tagged in my latest project and it works great but I found the following issue and I'm not sure where the error is.
I'm trying to decode JSON into a Dictionary where the key is a tagged type like this:
let json = """
{
"data": {
"key": "value"
}
}
""".data(using: .utf8)!
struct SomeStruct: Decodable {
typealias Key = Tagged<SomeStruct, String>
let data: [Key: String]
}
Strangely I receive this error message on decoding:
typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil)], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))
When I change the type of the dictionary to [String : String]
it works as expected.
Any ideas?
Thank you in advance and keep up the great work with Pointfree.co!
Hey all, I was just trying something out and ran into an odd issue. I am not entirely sure what the compiler is thinking.
The below code has a problem when it comes to decoding, with JSONDecoder
throwing Expected to decode Array<Any> but found a dictionary instead.
on files
, what is interesting is if we change the type to: [String: File]
it works perfectly fine. I didn't dig in to it much, but it seems like the ExpressibleByArrayLiteral
conformance is being interpreted incorrectly.
Problem code:
struct Gist {
let id: Self.ID
let files: [File.Name: File]
typealias ID = Tagged<Self, String>
}
extension Gist: Identifiable {}
extension Gist: Codable {}
struct File {
let filename: Name
let content: String
typealias Name = Tagged<Self, String>
}
extension File: Codable {}
I have a user id that, for legacy reasons, can come back as either a String
or an Int
and when adding Tagged
to handle this case I was hoping to extend Tagged
for this type specifically and add a custom Codable
implementation to clean this up. The only problem is that the runtime always calls the default conditional conformance implementations rather than my custom ones.
This is a more general Swift question perhaps, but is there a way to override this implementation and make sure the runtime calls my version? Here's the code:
public struct User: Codable {
public enum UserIdTag {}
public typealias Id = Tagged<UserIdTag, String>
let id: Id
}
extension Tagged where Tag == User.UserIdTag, RawValue == String {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
do {
try self.init(rawValue: String(container.decode(Int.self)))
} catch {
try self.init(rawValue: container.decode(String.self))
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(Int(rawValue))
}
}
I have an app that targets iOS 11 and when trying the new iOS/Xcode betas I had an issue with Tagged where when it is compiled it targets the latest version and gives messages like this: "Module file's minimum deployment target is ios12.0"
I worked around this by adding an iOS Deployment Target in addition to the macOS Deployment Target already present, this seems to have fixed the issue
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.