Hacker News new | ask | show | jobs
by anonymoushn 1046 days ago
> Rust has properly composable Option/Result monads, whereas Zig has special-cased ! and ? which don't compose (no Option of Option or Result of Result)

?!!??u32 is a perfectly cromulent type in Zig.

1 comments

How do you express the difference between None and Some(None) in Zig?
I've found that types like these normally come up in generic contexts, so the code I'm writing only usually deals with one layer of Option or Result until I get to the bit where I'm actually using the value and find out I have to write "try try foo();". That said, I think this sort of thing will do it:

  const std = @import("std");
  fn some(x: anytype) ?@TypeOf(x) {
    return x;
  }
  fn print_my_guy(maybe_maybe_x: ??u32) void {
    if(maybe_maybe_x) |maybe_x| {
      if (maybe_x) |x| {
        std.debug.print("that's Some(Some({d})) {any}\n", .{x, maybe_maybe_x});
      } else {
        std.debug.print("that's Some(None) {any}\n", .{maybe_maybe_x});
      }
    } else {
      std.debug.print("that's None {any}\n", .{maybe_maybe_x});
    }
  }
  pub fn main() void {
    const a: ??u32 = 5;
    const b: ??u32 = null;
    const c: ??u32 = some(@as(?u32, null));
    print_my_guy(a);
    print_my_guy(b);
    print_my_guy(c);
  }
What about

  const std = @import("std") ;
  const print = std.debug.print ;
  
  pub fn main() void {
  
    const simple_none : ?u8 = null ;
  
    const double_optional_none : ??u8 = null ;
  
    const double_optional_some_none : ??u8 = simple_none ;

    print("none equals some none: {}", .{ double_optional_none == double_optional_some_none });
    // prints none equals some none: false
  
  }