Result
が必要なのって、 async/await
に対する Future
みたいなもので、局所的にしかたなく使うものであって、 API に現れる種類のものじゃないと思うんよね。init
じゃなくて Result
を return
するメソッドとすると↓になる。 extension Foo: Decodable { static func from(_ decoder: Decoder) -> Result<Foo, DecodeError> { return Result { let container = try decoder.container(keyedBy: CodingKeys.self) let a = try container.decode(Int.self, forKey: .a).get() let b = try container.decode(String.self, forKey: .b).get() return Foo(a: a, b: b) } } }
get
で throws
への変換を挟まないともっと悲惨になる。extension Foo: Decodable { static func from(_ decoder: Decoder) -> Result<Foo, DecodeError> { let container = try decoder.container(keyedBy: CodingKeys.self) let a: A switch container.decode(Int.self, forKey: .a) { case .success(let value): a = value case .failure(let error): return .failure(error) } let b: B switch container.decode(Int.self, forKey: .b) { case .success(let value): b = value case .failure(let error): return .failure(error) } return .success(Foo(a: a, b: b)) } }
(edited)decode
を Result
を return
するようにしても何がうれしいのかさっぱりだし、 decode
を throws
のままにするならどこで Result
使うの?って感じ。extension Foo: Decodable { static func from(_ decoder: Decoder) -> Result<Foo, DecodeError> { return decoder.container(keyedBy: CodingKeys.self).flatMap { container in return curry(Foo.init) <^> container.decode(Int.self, forKey: .a) <*> container.decode(String.self, forKey: .b) } } }