digitalmars.D.learn - Implicit conversion from 'Ok' to 'Result' type when returning
- David Zhang (21/21) May 21 2017 Hi,
- Nicholas Wilson (9/30) May 21 2017 have free functions
- David Zhang (3/12) May 21 2017 Ah, I think you misread. ErrorEnum is a template type, like `T`.
- Nicholas Wilson (7/22) May 21 2017 Well then it becomes
- David Zhang (6/13) May 21 2017 But how would it be inferred? Like the `ok` function, `T` could
- Nicholas Wilson (11/26) May 21 2017 As in the function signature of the function you call `ok` or
- David Zhang (34/44) May 22 2017 This is what I've got right now.
Hi, I was reading a bit about this in Rust, and their enum type. I was wondering if this is replicate-able in D. What I've got right now is rather clunky, and involves using `typeof(return).ok` and `typeof(return).error)`. While that's not too bad, it does involve a lot more typing, and thus more area for human error. If you're not familiar with the Result and Option types, it allows you to do something like this: --- Result!(string, ErrorEnum) someFunction(...) { return Ok("Hello!"); } Result!(string, ErrorEnum) someFunction2(...) { return Error(ErrorEnum.dummyError); } --- I'm not entirely sure it's possible... but I figured I might give it a try.
May 21 2017
On Sunday, 21 May 2017 at 08:44:31 UTC, David Zhang wrote:Hi, I was reading a bit about this in Rust, and their enum type. I was wondering if this is replicate-able in D. What I've got right now is rather clunky, and involves using `typeof(return).ok` and `typeof(return).error)`. While that's not too bad, it does involve a lot more typing, and thus more area for human error. If you're not familiar with the Result and Option types, it allows you to do something like this: --- Result!(string, ErrorEnum) someFunction(...) { return Ok("Hello!"); } Result!(string, ErrorEnum) someFunction2(...) { return Error(ErrorEnum.dummyError); } --- I'm not entirely sure it's possible... but I figured I might give it a try.have free functions Result!(T, ErrorEnum) ok(T)(T t) { return Result(t); } Result!(T, ErrorEnum) error(T)(ErrorEnum e) { return Result(e); } then go if (!foo) return ok(42); else return error(Error.fooHappened);
May 21 2017
On Sunday, 21 May 2017 at 09:15:56 UTC, Nicholas Wilson wrote:have free functions Result!(T, ErrorEnum) ok(T)(T t) { return Result(t); } Result!(T, ErrorEnum) error(T)(ErrorEnum e) { return Result(e); } then go if (!foo) return ok(42); else return error(Error.fooHappened);Ah, I think you misread. ErrorEnum is a template type, like `T`. There's no ErrorEnum enum specified.
May 21 2017
On Sunday, 21 May 2017 at 09:29:40 UTC, David Zhang wrote:On Sunday, 21 May 2017 at 09:15:56 UTC, Nicholas Wilson wrote:Well then it becomes Result!(T, E) ok(T,E) (T t) { return Result(t); } Result!(T, E) error(T,E)(E e) { return Result(e); } and then provided it can be inferred (e.g. from the function signature) it will still work.have free functions Result!(T, ErrorEnum) ok(T)(T t) { return Result(t); } Result!(T, ErrorEnum) error(T)(ErrorEnum e) { return Result(e); } then go if (!foo) return ok(42); else return error(Error.fooHappened);Ah, I think you misread. ErrorEnum is a template type, like `T`. There's no ErrorEnum enum specified.
May 21 2017
On Sunday, 21 May 2017 at 09:37:46 UTC, Nicholas Wilson wrote:On Sunday, 21 May 2017 at 09:29:40 UTC, David Zhang wrote: Well then it becomes Result!(T, E) ok(T,E) (T t) { return Result(t); } Result!(T, E) error(T,E)(E e) { return Result(e); } and then provided it can be inferred (e.g. from the function signature) it will still work.But how would it be inferred? Like the `ok` function, `T` could be inferred, but E? I'm not sure I understand. If you have to specify the types every time, it kinda defeats the purpose. With the function signature as it is, you'd have to specify the type of the other type (e.g. you'd need to specify E for `ok()`).
May 21 2017
On Sunday, 21 May 2017 at 09:55:41 UTC, David Zhang wrote:On Sunday, 21 May 2017 at 09:37:46 UTC, Nicholas Wilson wrote:As in the function signature of the function you call `ok` or `error` in. Result!(int, SomeEnum) myfunc(bool foo) { if(!foo) return ok(42); else return error(SomeEnum.fooHappened); } should work.On Sunday, 21 May 2017 at 09:29:40 UTC, David Zhang wrote: Well then it becomes Result!(T, E) ok(T,E) (T t) { return Result(t); } Result!(T, E) error(T,E)(E e) { return Result(e); } and then provided it can be inferred (e.g. from the function signature) it will still work.But how would it be inferred? Like the `ok` function, `T` could be inferred, but E? I'm not sure I understand. If you have to specify the types every time, it kinda defeats the purpose. With the function signature as it is, you'd have to specify the type of the other type (e.g. you'd need to specify E for `ok()`).
May 21 2017
On Sunday, 21 May 2017 at 10:03:58 UTC, Nicholas Wilson wrote:As in the function signature of the function you call `ok` or `error` in. Result!(int, SomeEnum) myfunc(bool foo) { if(!foo) return ok(42); else return error(SomeEnum.fooHappened); } should work.This is what I've got right now. --- [module 1] struct Result(OkType, ErrType) { this(OkType ok) pure nothrow { isOk = true; okPayload = ok; } this(ErrType error) pure nothrow { isOk = false; errorPayload = error; } bool isOk; union { OkType okPayload; ErrType errorPayload; } } auto ok(T, E)(T payload) { return Result!(T, E)(payload); } auto error(T, E)(T payload) { return Result!(T, E)(payload); } --- [module 2] Result!(string, int) fn(bool shouldErr) { if (!shouldErr) return ok("No problem"); return error(0); } --- But it can't infer the second parameter. "template result.ok cannot deduce function from argument types !()(string)"
May 22 2017