use with builtins nib.types
This commit is contained in:
parent
ead4d37ca7
commit
600cac3ce3
6 changed files with 36 additions and 31 deletions
|
|
@ -1,10 +1,11 @@
|
||||||
{nib, ...} @ args: let
|
{nib, ...} @ args: let
|
||||||
struct = import ./struct.nix args;
|
struct = import ./struct.nix args;
|
||||||
in
|
in
|
||||||
nib.types.mergeAttrsList [
|
with nib.types;
|
||||||
# submodule is included directly to this module (ie self.myFunc)
|
mergeAttrsList [
|
||||||
struct
|
# submodule is included directly to this module (ie self.myFunc)
|
||||||
|
struct
|
||||||
|
|
||||||
# submodule content is accessible first by submodule name
|
# submodule content is accessible first by submodule name
|
||||||
# then by the name of the content (ie self.submodule.myFunc)
|
# then by the name of the content (ie self.submodule.myFunc)
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,23 @@
|
||||||
{nib, ...}:
|
{nib, ...}:
|
||||||
with builtins nib.types; rec {
|
with builtins nib.types; rec {
|
||||||
cmpStructErr' = errBadKeys: errBadValues: path: S: T:
|
cmpStructErr' = errBadKeys: errBadValues: path: S: T:
|
||||||
if builtins.isAttrs S && builtins.isAttrs T
|
if isAttrs S && isAttrs T
|
||||||
then let
|
then let
|
||||||
keysS = builtins.attrNames S;
|
keysS = attrNames S;
|
||||||
keysT = builtins.attrNames T;
|
keysT = attrNames T;
|
||||||
in
|
in
|
||||||
# ensure all key names match, then recurse
|
# ensure all key names match, then recurse
|
||||||
if !(keysS == keysT)
|
if !(keysS == keysT)
|
||||||
then errBadKeys path keysS keysT
|
then errBadKeys path keysS keysT
|
||||||
else
|
else
|
||||||
(firstErr
|
(firstErr
|
||||||
(builtins.map
|
(map
|
||||||
(k: cmpStructErr' errBadKeys errBadValues (path ++ [k]) (keysS.${k}) (keysT.${k}))
|
(k: cmpStructErr' errBadKeys errBadValues (path ++ [k]) (keysS.${k}) (keysT.${k}))
|
||||||
keysS))
|
keysS))
|
||||||
else
|
else
|
||||||
# terminating leaf in recursion tree reached
|
# terminating leaf in recursion tree reached
|
||||||
# ensure values' types match
|
# ensure values' types match
|
||||||
(builtins.typeOf S == builtins.typeOf T)
|
(typeOf S == typeOf T)
|
||||||
|| errBadValues path S T;
|
|| errBadValues path S T;
|
||||||
|
|
||||||
cmpStructErr = errBadKeys: errBadValues: cmpStructErr' errBadKeys errBadValues [];
|
cmpStructErr = errBadKeys: errBadValues: cmpStructErr' errBadKeys errBadValues [];
|
||||||
|
|
@ -60,9 +60,9 @@ with builtins nib.types; rec {
|
||||||
in
|
in
|
||||||
errOr ({...}:
|
errOr ({...}:
|
||||||
Ok (
|
Ok (
|
||||||
attrs.mapAttrsRecursive (
|
mapAttrsRecursive (
|
||||||
path: value: let
|
path: value: let
|
||||||
valueS = attrs.attrValueAt S path;
|
valueS = attrValueAt S path;
|
||||||
in
|
in
|
||||||
if valueS != null
|
if valueS != null
|
||||||
then valueS
|
then valueS
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
{nib, ...}: rec {
|
{nib, ...}:
|
||||||
|
with builtins; rec {
|
||||||
nameValuePair = name: value: {inherit name value;};
|
nameValuePair = name: value: {inherit name value;};
|
||||||
|
|
||||||
identityAttrs = value: {${value} = value;};
|
identityAttrs = value: {${value} = value;};
|
||||||
|
|
||||||
identityAttrsList = values: builtins.map (v: identityAttrs v) values;
|
identityAttrsList = values: map (v: identityAttrs v) values;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Generate an attribute set by mapping a function over a list of
|
Generate an attribute set by mapping a function over a list of
|
||||||
|
|
@ -73,13 +74,13 @@
|
||||||
|
|
||||||
:::
|
:::
|
||||||
*/
|
*/
|
||||||
genAttrs' = xs: f: builtins.listToAttrs (map f xs);
|
genAttrs' = xs: f: listToAttrs (map f xs);
|
||||||
|
|
||||||
mapAttrsRecursiveCond = cond: f: set: let
|
mapAttrsRecursiveCond = cond: f: set: let
|
||||||
recurse = path:
|
recurse = path:
|
||||||
builtins.mapAttrs (
|
mapAttrs (
|
||||||
name: value:
|
name: value:
|
||||||
if builtins.isAttrs value && cond value
|
if isAttrs value && cond value
|
||||||
then recurse (path ++ [name]) value
|
then recurse (path ++ [name]) value
|
||||||
else f (path ++ [name]) value
|
else f (path ++ [name]) value
|
||||||
);
|
);
|
||||||
|
|
@ -92,7 +93,7 @@
|
||||||
# given path as a list of strings, return that value of an
|
# given path as a list of strings, return that value of an
|
||||||
# attribute set at that path
|
# attribute set at that path
|
||||||
attrValueAt = nib.types.foldl (l: r:
|
attrValueAt = nib.types.foldl (l: r:
|
||||||
if l != null && builtins.hasAttr r l
|
if l != null && hasAttr r l
|
||||||
then l.${r}
|
then l.${r}
|
||||||
else null);
|
else null);
|
||||||
|
|
||||||
|
|
@ -108,11 +109,11 @@
|
||||||
binaryMerge start (start + (end - start) / 2) // binaryMerge (start + (end - start) / 2) end
|
binaryMerge start (start + (end - start) / 2) // binaryMerge (start + (end - start) / 2) end
|
||||||
else
|
else
|
||||||
# Otherwise there will be exactly 1 element due to the invariant, in which case we just return it directly
|
# Otherwise there will be exactly 1 element due to the invariant, in which case we just return it directly
|
||||||
builtins.elemAt list start;
|
elemAt list start;
|
||||||
in
|
in
|
||||||
if list == []
|
if list == []
|
||||||
then
|
then
|
||||||
# Calling binaryMerge as below would not satisfy its invariant
|
# Calling binaryMerge as below would not satisfy its invariant
|
||||||
{}
|
{}
|
||||||
else binaryMerge 0 (builtins.length list);
|
else binaryMerge 0 (length list);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
{...}: rec {
|
{...}:
|
||||||
|
with builtins; rec {
|
||||||
# Fault Monad
|
# Fault Monad
|
||||||
# Wrapper around an error (ie builtins.abort)
|
# Wrapper around an error (ie builtins.abort)
|
||||||
Fault = error: {
|
Fault = error: {
|
||||||
|
|
@ -6,7 +7,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
# Pattern Matching
|
# Pattern Matching
|
||||||
isFault = F: builtins.attrNames F == ["error"];
|
isFault = F: attrNames F == ["error"];
|
||||||
|
|
||||||
# Unwrap (Monadic Return Operation)
|
# Unwrap (Monadic Return Operation)
|
||||||
unwrapFault = F: F.error;
|
unwrapFault = F: F.error;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
{...}: rec {
|
{...}:
|
||||||
|
with builtins; rec {
|
||||||
foldl = op: nul: list: let
|
foldl = op: nul: list: let
|
||||||
foldl' = n:
|
foldl' = n:
|
||||||
if n == -1
|
if n == -1
|
||||||
then nul
|
then nul
|
||||||
else op (foldl' (n - 1)) (builtins.elemAt list n);
|
else op (foldl' (n - 1)) (elemAt list n);
|
||||||
in
|
in
|
||||||
foldl' (builtins.length list - 1);
|
foldl' (length list - 1);
|
||||||
|
|
||||||
crossLists = f: foldl (fs: args: builtins.concatMap (f: map f args) fs) [f];
|
crossLists = f: foldl (fs: args: concatMap (f: map f args) fs) [f];
|
||||||
|
|
||||||
findFirstIndex = pred: default: list: let
|
findFirstIndex = pred: default: list: let
|
||||||
# A naive recursive implementation would be much simpler, but
|
# A naive recursive implementation would be much simpler, but
|
||||||
|
|
@ -23,7 +24,7 @@
|
||||||
#
|
#
|
||||||
# We start with index -1 and the 0'th element of the list, which satisfies the invariant
|
# We start with index -1 and the 0'th element of the list, which satisfies the invariant
|
||||||
resultIndex =
|
resultIndex =
|
||||||
builtins.foldl' (
|
foldl' (
|
||||||
index: el:
|
index: el:
|
||||||
if index < 0
|
if index < 0
|
||||||
then
|
then
|
||||||
|
|
@ -50,5 +51,5 @@
|
||||||
in
|
in
|
||||||
if index == null
|
if index == null
|
||||||
then default
|
then default
|
||||||
else builtins.elemAt list index;
|
else elemAt list index;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
{nib, ...}: rec {
|
{nib, ...}:
|
||||||
|
with builtins; rec {
|
||||||
# Res (Result) Monad
|
# Res (Result) Monad
|
||||||
Res = success: value: {inherit success value;};
|
Res = success: value: {inherit success value;};
|
||||||
Ok = value: Res true value;
|
Ok = value: Res true value;
|
||||||
|
|
@ -7,7 +8,7 @@
|
||||||
Err' = Err "err";
|
Err' = Err "err";
|
||||||
|
|
||||||
# Pattern Matching
|
# Pattern Matching
|
||||||
isRes = R: builtins.attrNames R == ["success" "value"];
|
isRes = R: attrNames R == ["success" "value"];
|
||||||
isOk = R: isRes R && R.success;
|
isOk = R: isRes R && R.success;
|
||||||
isErr = R: isRes R && !R.success;
|
isErr = R: isRes R && !R.success;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue