Most of the ecosystem has moved to this formatter, and many people configured their editors to autoformat it with this formatter. Closes: https://git.snix.dev/snix/snix/issues/62 Change-Id: Icf39e7836c91fc2ae49fbe22a40a639105bfb0bd Reviewed-on: https://cl.snix.dev/c/snix/+/30671 Reviewed-by: Florian Klink <flokli@flokli.de> Tested-by: besadii Autosubmit: Ilan Joselevich <personal@ilanjoselevich.com>
		
			
				
	
	
		
			85 lines
		
	
	
	
		
			1.7 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			85 lines
		
	
	
	
		
			1.7 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
# Simple state monad represented as
 | 
						|
#
 | 
						|
#     stateMonad s a = s -> { state : s; value : a }
 | 
						|
#
 | 
						|
{ ... }:
 | 
						|
 | 
						|
rec {
 | 
						|
  #
 | 
						|
  # Monad
 | 
						|
  #
 | 
						|
 | 
						|
  # Type: stateMonad s a -> (a -> stateMonad s b) -> stateMonad s b
 | 
						|
  bind =
 | 
						|
    action: f: state:
 | 
						|
    let
 | 
						|
      afterAction = action state;
 | 
						|
    in
 | 
						|
    (f afterAction.value) afterAction.state;
 | 
						|
 | 
						|
  # Type: stateMonad s a -> stateMonad s b -> stateMonad s b
 | 
						|
  after =
 | 
						|
    action1: action2: state:
 | 
						|
    action2 (action1 state).state;
 | 
						|
 | 
						|
  # Type: stateMonad s (stateMonad s a) -> stateMonad s a
 | 
						|
  join = action: bind action (action': action');
 | 
						|
 | 
						|
  # Type: [a] -> (a -> stateMonad s b) -> stateMonad s null
 | 
						|
  for_ = xs: f: builtins.foldl' (laterAction: x: after (f x) laterAction) (pure null) xs;
 | 
						|
 | 
						|
  #
 | 
						|
  # Applicative
 | 
						|
  #
 | 
						|
 | 
						|
  # Type: a -> stateMonad s a
 | 
						|
  pure = value: state: { inherit state value; };
 | 
						|
 | 
						|
  # TODO(sterni): <*>, lift2, …
 | 
						|
 | 
						|
  #
 | 
						|
  # Functor
 | 
						|
  #
 | 
						|
 | 
						|
  # Type: (a -> b) -> stateMonad s a -> stateMonad s b
 | 
						|
  fmap = f: action: bind action (result: pure (f result));
 | 
						|
 | 
						|
  #
 | 
						|
  # State Monad
 | 
						|
  #
 | 
						|
 | 
						|
  # Type: (s -> s) -> stateMonad s null
 | 
						|
  modify = f: state: {
 | 
						|
    value = null;
 | 
						|
    state = f state;
 | 
						|
  };
 | 
						|
 | 
						|
  # Type: stateMonad s s
 | 
						|
  get = state: {
 | 
						|
    value = state;
 | 
						|
    inherit state;
 | 
						|
  };
 | 
						|
 | 
						|
  # Type: s -> stateMonad s null
 | 
						|
  set = new: modify (_: new);
 | 
						|
 | 
						|
  # Type: str -> stateMonad set set.${str}
 | 
						|
  getAttr = attr: fmap (state: state.${attr}) get;
 | 
						|
 | 
						|
  # Type: str -> (any -> any) -> stateMonad s null
 | 
						|
  modifyAttr =
 | 
						|
    attr: f:
 | 
						|
    modify (
 | 
						|
      state:
 | 
						|
      state
 | 
						|
      // {
 | 
						|
        ${attr} = f state.${attr};
 | 
						|
      }
 | 
						|
    );
 | 
						|
 | 
						|
  # Type: str -> any -> stateMonad s null
 | 
						|
  setAttr = attr: value: modifyAttr attr (_: value);
 | 
						|
 | 
						|
  # Type: s -> stateMonad s a -> a
 | 
						|
  run = state: action: (action state).value;
 | 
						|
}
 |