feat: Add rough initial version of sum types
Sum types are represented as attribute sets with a single key in them.
This commit is contained in:
parent
ef4ded7b98
commit
f6635fec98
2 changed files with 32 additions and 1 deletions
16
yants.nix
16
yants.nix
|
@ -74,6 +74,20 @@ with builtins; let
|
||||||
else actions."${__functor { inherit name check; } x}";
|
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: {
|
mkFunc = sig: f: {
|
||||||
inherit sig;
|
inherit sig;
|
||||||
__toString = self: foldl' (s: t: "${s} -> ${t.name}")
|
__toString = self: foldl' (s: t: "${s} -> ${t.name}")
|
||||||
|
@ -111,4 +125,4 @@ in (typeSet [
|
||||||
)) true (attrValues v))))
|
)) true (attrValues v))))
|
||||||
|
|
||||||
(poly2 "either" (t1: t2: v: t1.check v || t2.check v))
|
(poly2 "either" (t1: t2: v: t1.check v || t2.check v))
|
||||||
]) // { inherit struct enum defun; }
|
]) // { inherit struct enum sum defun; }
|
||||||
|
|
|
@ -46,6 +46,23 @@ deepSeq rec {
|
||||||
green = throw "It should not be green!";
|
green = throw "It should not be green!";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Test sum type definitions
|
||||||
|
creature = sum "creature" {
|
||||||
|
human = struct {
|
||||||
|
name = string;
|
||||||
|
age = option int;
|
||||||
|
};
|
||||||
|
|
||||||
|
pet = enum "pet" [ "dog" "lizard" "cat" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testSum = creature {
|
||||||
|
human = {
|
||||||
|
name = "Brynhjulf";
|
||||||
|
age = 42;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# Test curried function definitions
|
# Test curried function definitions
|
||||||
func = defun [ string int string ]
|
func = defun [ string int string ]
|
||||||
(name: age: "${name} is ${toString age} years old");
|
(name: age: "${name} is ${toString age} years old");
|
||||||
|
|
Loading…
Add table
Reference in a new issue