- Switch from `cabal2nix` and haskell overlay to `developPackage` - Restructure directories to have more descriptive names - Fix `nix run`
2.3 KiB
title | keywords | image | series |
---|---|---|---|
The nix arrow operator | nix, short, language, programming-language | ./images/nix_banner.png | Nix shorts |
There is a specal operator in nix, written as ->
. It is not a C dereference struct pointer operator, nor is it a haskell function type definition. It is a boolean operator, which represents the "implies arrow" from propositional logic. This is especially useful in nix, because of its usage in modules.
The myService
module
Let's say you have made a module for myService
with two options called myService.enable
, and myService.address
. myService
needs an address in order to work properly. If myService
is not enabled, the value of myService.address
doesn't really matter. Set or null
, the result will be the same either way. If myService
is enabled however, it is crucial that we report an error if myService.address
is not set. myService
can not work without it.
In order to make sure that this never happens, we need to assert that this is not the case. This could be done by asserting that this boolean expression is true.
((!myService.enable) || myService.address != null)
or in plain english: "Either myService is not enabled, or the address has to not be null"
This is equivalent to this boolean expression:
myService.enable -> myService.address != null
or in plain english: "myService being enabled implies that the address is not null".
Asserting these kinds of inter-setting dependencies are common enough in nix modules to provide grounds for having ->
as its own boolean operator.
Full example
# modules/myService.nix
{ lib, config }: let
cfg = config.myService;
in {
options = {
enable = lib.mkEnableOption "myService";
address = lib.mkOption {
example = "127.0.0.1";
description = "The address of myService";
type = lib.types.string;
};
};
config = {
# ...
assertions = [
{
assertion = cfg.enable -> cfg.address != null;
message = "myService needs an address";
}
];
};
}