about summary refs log tree commit diff
path: root/yants.nix
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2019-08-08T22·32+0100
committerVincent Ambo <tazjin@google.com>2019-08-28T13·36+0100
commit5949663fcd843fe746f602f4a2509a11d8a94f06 (patch)
treef11213b9b86752c3eb2ec026062cb0adbf00b2a5 /yants.nix
parent1da22249bd65ffeb6de1382d0a39da9240e63091 (diff)
feat: Implement support for typing functions
The defun helper takes a type signature and a function and makes a
typed version. Because we can.
Diffstat (limited to 'yants.nix')
-rw-r--r--yants.nix15
1 files changed, 14 insertions, 1 deletions
diff --git a/yants.nix b/yants.nix
index a24792f8a5..51bc5fe5c4 100644
--- a/yants.nix
+++ b/yants.nix
@@ -74,6 +74,19 @@ with builtins; let
        else actions."${__functor { inherit name check; } x}";
   };
 
+  mkFunc = sig: f: {
+    inherit sig;
+    __toString = self: foldl' (s: t: "${s} -> ${t.name}")
+                              "λ :: ${(head self.sig).name}" (tail self.sig);
+    __functor = _: f;
+  };
+  defun' = sig: func: if length sig > 2
+    then mkFunc sig (x: defun' (tail sig) (func ((head sig) x)))
+    else mkFunc sig (x: ((head (tail sig)) (func ((head sig) x))));
+
+  defun = sig: func: if length sig < 2
+    then (throw "Signature must at least have two types (a -> b)")
+    else defun' sig func;
 in (typeSet [
   # Primitive types
   (typedef "any" (_: true))
@@ -98,4 +111,4 @@ in (typeSet [
   )) true (attrValues v))))
 
   (poly2 "either" (t1: t2: v: t1.check v || t2.check v))
-]) // { inherit struct enum; }
+]) // { inherit struct enum defun; }