From 1812effbd7b24e9e82aa80d232321b6eadc3b1e7 Mon Sep 17 00:00:00 2001 From: derped Date: Sat, 30 Nov 2024 21:10:07 +0100 Subject: [PATCH] fn.meetsConDo: improve performance and add documentation. --- fn.nix | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/fn.nix b/fn.nix index 48ec761..fb3c65c 100644 --- a/fn.nix +++ b/fn.nix @@ -65,17 +65,44 @@ rec { # Not sure how list operations are implemented in Nix # This might be a tad bit inefficient. - # TODO: look for better implementation (map is a builtin function so checking that probably won't help) # Sequentially checks elements of list (l) for condition (cond) and executes do on first match. + /** + Run lambda "(do element)" on the first element of list "l" where (cond element) returns true otherwise return false. + + # Type + ``` + meetsConDo :: (any -> bool) -> (any -> any) -> [any] -> any + ``` + + # Arguments: + - [cond] Condition function + - [do] Function to run on element if cond returns true + - [list] List of elements + + # Example: + ```nix + meetsConDo (element: element >= 5) (element: element + 1) [ 4 2 0 5 1 ] + => 6 + + meetsConDo (element: element >= 5) (element: element + 1) [ 4 2 0 1 ] + => false + ``` + */ meetsConDo = - cond: do: l: - ifelse (l == [ ]) false ( - let - h = head l; - t = tail l; - in - ifelse (cond h) (do h) (meetsConDo cond do t) - ); + cond: do: list: + let + listLen = length list; + meetsConDo' = + currentIndex: + ifelse (currentIndex == listLen) false ( + let + head = elemAt list currentIndex; + in + ifelse (cond head) (do head) (meetsConDo' (currentIndex + 1)) + ); + in + meetsConDo' 0; + deps = p: ifelse (isAttrs p) (filter isAttrs (