[Nix-dev] Nix 1.2 released

Shea Levy shea at shealevy.com
Wed Dec 12 19:22:56 CET 2012


On 12/12/2012 01:12 PM, Florian Friesdorf wrote:
> Eelco Dolstra <eelco.dolstra at logicblox.com> writes:
>> Hi,
>>
>> On 12/12/12 17:15, Shea Levy wrote:
>>
>>>>> The elem library function evaluates all list elements instead of
>>>>> returning "true" after finding a matching element.
>>>> Sure about that?  This seems lazy enough:
>>>>
>>>>     elem =
>>>>       builtins.elem or
>>>>       (x: list: fold (a: bs: x == a || bs) false list);
>>>>
>>> Shouldn't the bs come first? i.e. (a: bs: bs || x == a)?
>> Not if you want to check from left to right.
> Sorry, but I'm not getting it yet. What I understand:
>
> list = [0, 0, 1, 2, 3];
> x = 1;
>
> elem x list
>
> -> a: 3, x == a: false, bs: false
> -> a: 2, x == a: false; bs: false
> -> a: 1, x == a: true; bs: false
> -> a: 0, x == a: false; bs: true
> -> a: 0, x == a: false; bs: true
>
> Probably missing something very basic.

Let op = (a: bs: x == a || bs), and let x `op` y be shorthand for op x 
y. Then, elem x list evaluates to:
     0 `op` (0 `op` (1 `op` (2 `op` (3 `op` (false))))),
which evaluates to:
     x == 0 || (x == 0 ||(x == 1 || (x == 2 || (x == 3 || (false))))),
which evaluates to:
     false || (x == 0 ||(x == 1 || (x == 2 || (x == 3 || (false))))),
which evaluates to:
     x == 0 || (x == 1 || (x == 2 || (x == 3 || (false)))),
which evaluates to:
     false || (x == 1 || (x == 2 || (x == 3 || (false)))),
which evaluates to:
     x == 1 || (x == 2 || (x == 3 || (false))),
which evaluates to:
     true || (x == 2 || (x == 3 || (false))),
which evaluates to true (no need to keep evaluating the ||).

> For completeness sake, fold from lib/lists:
>
>    fold =
>      if builtins ? elemAt
>      then op: nul: list:
>        let
>          len = length list;
>          fold' = n:
>            if n == len
>            then nul
>            else op (builtins.elemAt list n) (fold' (add n 1));
>        in fold' 0
>      else op: nul:
>        let fold' = list:
>          if list == []
>          then nul
>          else op (head list) (fold' (tail list));
>        in fold';
>
>
> The following would not evaluate all, I'd currently claim:
>
>    elem' = x: list: if list == []
>      then false
>      else head list == x || elem' x (tail list);
>



More information about the nix-dev mailing list