# ❄ NixTypes (nt) ❄
Because Nix never held your hand. It shot off your fingers and spat out God's longest stack trace
>[!WARNING] > ✨ **Under Construction** ✨ > > NixTypes is **quite** a large project to do alone, but it's been staring at me for the last 12 months. > If you're interested feel free to contact me and/or submit pull requests :yellow_heart::yellow_heart: > > **Be not afraid!** It's only a matter of time until NixTypes is ready for use! >[!CAUTION] > The current syntax is quite ugly and **no it's not final.** NixTypes is in an > **extremely experimental** prototyping stage! ## 💙 Huh? Nix has no type system duh!? Sure that's fine for configuring your distro, but what about developing in Nix itself? The code people write tends to be unnecessarily complex or full or bugs. Nix needs standards, and NixTypes gives you those. ## :rainbow: More Than Types NixTypes isn't *exactly* just a type system. **You didn't think I'd give you types then say goodbye did you?** Then we'd be right back where we started... Instead there's a whole standard library built from the ashes. Some of the sweet sweet batteries included: 1. **Pattern Matching** (finally!!) 2. **Attribute Set Parsing** 3. **Pretty Printing** (no more `builtins.toString` errors) 4. **A Module System** (say goodbye to managing all your `imports`) 5. **Types, Types, & More Types** (Maybe/Some/None, Monads, Tree, Rose, etc) 6. **Support For Pipe Operators** (cleaner code with `<|` and `|>` ) ## Types For Humans Let's design a `Result` type using the NixTypes system! We'll start simple and use the following attribute set as our naive basis: ```nix Result = success: value: assert builtins.isBool success; { inherit success value; }; }; ``` We can ```nix let inherit (nt) print toString Bool Fn Type ; in rec { Result = Type (Self: { ops = { # we need to make a constructor mk = Fn [Bool Any] Self (success: value: { inherit success value; }); # create some alternative constructors mkSuccess = Self.mk true; mkFail = Self.mk false; isSuccess = self: self.success; isFail = self: ! self.success; unwrap = self: self.value; }; }); # Example Usage: tryGetAttr = name: attrs: let success = attrs ? name; value = attrs.${name} or "AttrSet missing attribute name \"${name}\""; in Result success value; # prints myAttr and returns the default value (same as builtins.trace!) printMyAttr = attrs: default: let result = tryGetAttr "myAttr"; in if result.isSuccess then print (toString result.unwrap) default else default; } ``` Now let's try something a little harder and try to make our `Result` type act more like Rust's `std::result` crate: ```rust enum Result