Skip to content

Commit

Permalink
(WIP) Add a contracts.yants compatibility attribute set
Browse files Browse the repository at this point in the history
  • Loading branch information
yvan-sraka committed Feb 2, 2023
1 parent bf1f553 commit e9acfc7
Showing 1 changed file with 43 additions and 2 deletions.
45 changes: 43 additions & 2 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ is = contract { message = s: "Value should be of type `${s.type}':"; };
# TODO I'm not sure if this would be really handy:
# FunctionArgs = args: f: args == builtins.functionArgs f;
# ... because I would prefer something like:
fn = Args: f: x: f (is (def Args) x);
fn = arg: f: x: f (is (def arg) x);

/* Force the concrete evaluation of a contract or any datatype */
strict = e: builtins.deepSeq e e;
Expand Down Expand Up @@ -135,6 +135,10 @@ match = regex: # FIXME check if `regex` is of `Regex` type!
# From https://www.rfc-editor.org/rfc/rfc3986#page-50
Url = match ''^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?'';

Drv = declare { name = "Derivation"; } { type = "derivation"; };
Maybe = declare { name = "Maybe"; } (x: enum [ Null x ]);
Unit = declare { name = "{}"; } { }; # TODO: This just behaves like Set type ...

/* *** Some type ideas for the future *** */
Hash = TODO; # FIXME SRI hashes used by Nix :)
Regex = TODO; # It would be nice to check if a RegEx is valid ...
Expand All @@ -146,7 +150,44 @@ SemVer = TODO; # ... or if a software version is in SemVer format!
# This is internal mixture that helps to have declared types available here:
prelude = (builtins.mapAttrs (n: _: declare { name = n; } types.${n}) types);

# Compatibility with https://code.tvl.fyi/about/nix/yants :)
# blob: cb9fc08287fb1f81159d996947c0aaf1cc1672be

yants = with prelude;
let opt = x: if isString arg then (declare { name = x; }) else (def arg); in
rec {
any = Any;
attrs = setOf;
bool = Bool;

# FIXME: This buggy and not yet understand how to write it correctly ...
# FIXME: Should declare it as { name = "λ :: A -> B -> C" }?
defun = args: f: a: let x = builtins.head args; xs = builtins.tail args; in
fn x (if builtins.length args > 1 then (defun xs f) else (f a));

drv = Drv;
either = t1: t2: enum [ t1 t2 ];
eitherN = enum;

# FIXME: Does not support pattern matching as .match "foo" { foo = ...; }
enum = opt enum;

float = Float;
function = enum [ Lambda Functor ];
int = Int;
list = listOf;
null = Null;
option = Maybe;
path = Path;
restrict = name: pred: t: x: contract {name = name; } (pred (def t x));
string = String;
struct = opt;
sum = opt both;
type = Type;
unit = Unit;
};

in prelude // {
# Explicitly choose what would be our library interface (and eventually not)
inherit declare def default contract is fn strict;
inherit declare def default contract is fn strict yants;
}

0 comments on commit e9acfc7

Please sign in to comment.