about summary refs log tree commit diff
path: root/yants.nix
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2019-08-24T13·10+0100
committerVincent Ambo <tazjin@google.com>2019-08-28T13·36+0100
commitf6635fec982ecf892f77dde82568689631932d85 (patch)
treefad487487f543d066c67d9244a23d0056b7f62c8 /yants.nix
parentef4ded7b98f503b6d39c9e2fb843fb8de94279d9 (diff)
feat: Add rough initial version of sum types
Sum types are represented as attribute sets with a single key in them.
Diffstat (limited to 'yants.nix')
-rw-r--r--yants.nix16
1 files changed, 15 insertions, 1 deletions
diff --git a/yants.nix b/yants.nix
index 51bc5fe5c433..26c5b317c9fb 100644
--- a/yants.nix
+++ b/yants.nix
@@ -74,6 +74,20 @@ with builtins; let
        else actions."${__functor { inherit name check; } x}";
   };
 
+  sum = name: values: let
+    isVariant = x:
+      let name = elemAt (attrNames x) 0;
+      in if hasAttr name values
+        then values."${name}".check x."${name}"
+        else false;
+    check = x: isAttrs x && length (attrNames x) == 1 && isVariant x;
+  in {
+    inherit name values check;
+    __functor = self: x: if self.check x
+      then x
+      else throw "'${toPretty x}' is not a valid variant of '${name}'";
+  };
+
   mkFunc = sig: f: {
     inherit sig;
     __toString = self: foldl' (s: t: "${s} -> ${t.name}")
@@ -111,4 +125,4 @@ in (typeSet [
   )) true (attrValues v))))
 
   (poly2 "either" (t1: t2: v: t1.check v || t2.check v))
-]) // { inherit struct enum defun; }
+]) // { inherit struct enum sum defun; }