Add purescript/switcheroo
* commit 'ca3cb6ae29f55d184ca1df95b5287859e847e1f2': purescript(switcheroo): Simplified types purescript(switcheroo): POC purescript(switcheroo): Initialized repo
This commit is contained in:
commit
1510efc23e
11
purescript/switcheroo/.gitignore
vendored
Normal file
11
purescript/switcheroo/.gitignore
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
/bower_components/
|
||||
/node_modules/
|
||||
/.pulp-cache/
|
||||
/output/
|
||||
/generated-docs/
|
||||
/.psc-package/
|
||||
/.psc*
|
||||
/.purs*
|
||||
/.psa*
|
||||
/.spago
|
||||
main.js
|
640
purescript/switcheroo/flake.lock
Normal file
640
purescript/switcheroo/flake.lock
Normal file
|
@ -0,0 +1,640 @@
|
|||
{
|
||||
"nodes": {
|
||||
"deadnix": {
|
||||
"inputs": {
|
||||
"fenix": "fenix",
|
||||
"naersk": "naersk",
|
||||
"nixpkgs": "nixpkgs_4",
|
||||
"utils": "utils"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1655647809,
|
||||
"narHash": "sha256-npyHYIJW7HyGIFpCZZK+t5JM/v2LsyFhAGJxX1DXO7E=",
|
||||
"owner": "astro",
|
||||
"repo": "deadnix",
|
||||
"rev": "83c42cc64d190ecb72f5929eab0f64fe88e25dc4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "astro",
|
||||
"repo": "deadnix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"deadnix_2": {
|
||||
"inputs": {
|
||||
"fenix": "fenix_2",
|
||||
"naersk": "naersk_2",
|
||||
"nixpkgs": "nixpkgs_8",
|
||||
"utils": "utils_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1656370114,
|
||||
"narHash": "sha256-XBbSWeBuF6Ck0jc634yAp2hjPXWM2JyRDPCdK0dh3w4=",
|
||||
"owner": "astro",
|
||||
"repo": "deadnix",
|
||||
"rev": "9f450f7250ad7680cb5f12ce5985cc18496c2d5f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "astro",
|
||||
"repo": "deadnix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"docs-search": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1661787609,
|
||||
"narHash": "sha256-jgOl8PKisRmcaHOya3HzArI3eKjVErx+XIBGminh9Zk=",
|
||||
"owner": "purs-nix",
|
||||
"repo": "purescript-docs-search",
|
||||
"rev": "4620575e21886fcbf516d0b43910ba4ead2a60d0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "purs-nix",
|
||||
"repo": "purescript-docs-search",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"fenix": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"rust-analyzer-src": "rust-analyzer-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1655533500,
|
||||
"narHash": "sha256-qJJmLVoMYfDLywI9MNL7sb0W/GsKQF9HDatdHm1tSl0=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "b6630603af13df17d0dd4df8629e9a24e6ba0fbd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"fenix_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_6",
|
||||
"rust-analyzer-src": "rust-analyzer-src_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1655533500,
|
||||
"narHash": "sha256-qJJmLVoMYfDLywI9MNL7sb0W/GsKQF9HDatdHm1tSl0=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "b6630603af13df17d0dd4df8629e9a24e6ba0fbd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"fenix_3": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"purs-nix",
|
||||
"statix",
|
||||
"nixpkgs"
|
||||
],
|
||||
"rust-analyzer-src": "rust-analyzer-src_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1645251813,
|
||||
"narHash": "sha256-cQ66tGjnZclBCS3nD26mZ5fUH+3/HnysGffBiWXUSHk=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "9892337b588c38ec59466a1c89befce464aae7f8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1618217525,
|
||||
"narHash": "sha256-WGrhVczjXTiswQaoxQ+0PTfbLNeOQM6M36zvLn78AYg=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "c6169a2772643c4a93a0b5ac1c61e296cba68544",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_2": {
|
||||
"locked": {
|
||||
"lastModified": 1618217525,
|
||||
"narHash": "sha256-WGrhVczjXTiswQaoxQ+0PTfbLNeOQM6M36zvLn78AYg=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "c6169a2772643c4a93a0b5ac1c61e296cba68544",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"get-flake": {
|
||||
"locked": {
|
||||
"lastModified": 1644686428,
|
||||
"narHash": "sha256-zkhYsURWFrvEZLkIoBeqFBzSu+cA2u5mo6M8vq9LN7M=",
|
||||
"owner": "ursi",
|
||||
"repo": "get-flake",
|
||||
"rev": "703f15558daa56dfae19d1858bb3046afe68831a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "ursi",
|
||||
"repo": "get-flake",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"purs-nix",
|
||||
"statix",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1635165013,
|
||||
"narHash": "sha256-o/BdVjNwcB6jOmzZjOH703BesSkkS5O7ej3xhyO8hAY=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "5b9e0ff9d3b551234b4f3eb3983744fa354b17f1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"make-shell": {
|
||||
"locked": {
|
||||
"lastModified": 1634940815,
|
||||
"narHash": "sha256-P69OmveboXzS+es1vQGS4bt+ckwbeIExqxfGLjGuJqA=",
|
||||
"owner": "ursi",
|
||||
"repo": "nix-make-shell",
|
||||
"rev": "8add91681170924e4d0591b22f294aee3f5516f9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "ursi",
|
||||
"ref": "1",
|
||||
"repo": "nix-make-shell",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"make-shell_2": {
|
||||
"locked": {
|
||||
"lastModified": 1634940815,
|
||||
"narHash": "sha256-P69OmveboXzS+es1vQGS4bt+ckwbeIExqxfGLjGuJqA=",
|
||||
"owner": "ursi",
|
||||
"repo": "nix-make-shell",
|
||||
"rev": "8add91681170924e4d0591b22f294aee3f5516f9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "ursi",
|
||||
"ref": "1",
|
||||
"repo": "nix-make-shell",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"naersk": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1655042882,
|
||||
"narHash": "sha256-9BX8Fuez5YJlN7cdPO63InoyBy7dm3VlJkkmTt6fS1A=",
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"rev": "cddffb5aa211f50c4b8750adbec0bbbdfb26bb9f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"naersk_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_7"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1655042882,
|
||||
"narHash": "sha256-9BX8Fuez5YJlN7cdPO63InoyBy7dm3VlJkkmTt6fS1A=",
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"rev": "cddffb5aa211f50c4b8750adbec0bbbdfb26bb9f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1675698036,
|
||||
"narHash": "sha256-BgsQkQewdlQi8gapJN4phpxkI/FCE/2sORBaFcYbp/A=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "1046c7b92e908a1202c0f1ba3fc21d19e1cf1b62",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_10": {
|
||||
"locked": {
|
||||
"lastModified": 1645013224,
|
||||
"narHash": "sha256-b7OEC8vwzJv3rsz9pwnTX2LQDkeOWz2DbKypkVvNHXc=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b66b39216b1fef2d8c33cc7a5c72d8da80b79970",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1655400192,
|
||||
"narHash": "sha256-49OBVVRgb9H/PSmNT9W61+NRdDbuSJVuDDflwXlaUKU=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3d7435c638baffaa826b85459df0fff47f12317d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1655481042,
|
||||
"narHash": "sha256-XHbcywq2vIQ5CeH1OK3TN793jkiNAAZsSctS1PFgseo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "103a4c0ae46afa9cf008c30744175315ca38e9f9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs_4": {
|
||||
"locked": {
|
||||
"lastModified": 1655481042,
|
||||
"narHash": "sha256-XHbcywq2vIQ5CeH1OK3TN793jkiNAAZsSctS1PFgseo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "103a4c0ae46afa9cf008c30744175315ca38e9f9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs_5": {
|
||||
"locked": {
|
||||
"lastModified": 1646506091,
|
||||
"narHash": "sha256-sWNAJE2m+HOh1jtXlHcnhxsj6/sXrHgbqVNcVRlveK4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3e644bd62489b516292c816f70bf0052c693b3c7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_6": {
|
||||
"locked": {
|
||||
"lastModified": 1655400192,
|
||||
"narHash": "sha256-49OBVVRgb9H/PSmNT9W61+NRdDbuSJVuDDflwXlaUKU=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3d7435c638baffaa826b85459df0fff47f12317d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_7": {
|
||||
"locked": {
|
||||
"lastModified": 1655481042,
|
||||
"narHash": "sha256-XHbcywq2vIQ5CeH1OK3TN793jkiNAAZsSctS1PFgseo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "103a4c0ae46afa9cf008c30744175315ca38e9f9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs_8": {
|
||||
"locked": {
|
||||
"lastModified": 1655481042,
|
||||
"narHash": "sha256-XHbcywq2vIQ5CeH1OK3TN793jkiNAAZsSctS1PFgseo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "103a4c0ae46afa9cf008c30744175315ca38e9f9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs_9": {
|
||||
"locked": {
|
||||
"lastModified": 1656549732,
|
||||
"narHash": "sha256-eILutFZGjfk2bEzfim8S/qyYc//0S1KsCeO+OWbtoR0=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d3248619647234b5dc74a6921bcdf6dd8323eb22",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"parsec": {
|
||||
"locked": {
|
||||
"lastModified": 1635533376,
|
||||
"narHash": "sha256-/HrG0UPGnI5VdkhrNrpDiM2+nhdL6lD/bqyGtYv0QDE=",
|
||||
"owner": "nprindle",
|
||||
"repo": "nix-parsec",
|
||||
"rev": "1bf25dd9c5de1257a1c67de3c81c96d05e8beb5e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nprindle",
|
||||
"repo": "nix-parsec",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"ps-tools": {
|
||||
"inputs": {
|
||||
"deadnix": "deadnix_2",
|
||||
"make-shell": "make-shell_2",
|
||||
"nixpkgs": "nixpkgs_9",
|
||||
"utils": "utils_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1658374818,
|
||||
"narHash": "sha256-WxbQ/BR4Ep8tBbaOikXechspyZlvwfL5XNmRNEnaOFo=",
|
||||
"owner": "purs-nix",
|
||||
"repo": "purescript-tools",
|
||||
"rev": "c0f887f60ea2331dfdc5b0e8be2e732976887345",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "purs-nix",
|
||||
"repo": "purescript-tools",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"purs-nix": {
|
||||
"inputs": {
|
||||
"deadnix": "deadnix",
|
||||
"docs-search": "docs-search",
|
||||
"get-flake": "get-flake",
|
||||
"make-shell": "make-shell",
|
||||
"nixpkgs": "nixpkgs_5",
|
||||
"parsec": "parsec",
|
||||
"ps-tools": "ps-tools",
|
||||
"statix": "statix",
|
||||
"utils": "utils_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1674243319,
|
||||
"narHash": "sha256-o39rBVSNqchahHrMYNixdlasDro8omlf/n7yQZsdNI8=",
|
||||
"owner": "purs-nix",
|
||||
"repo": "purs-nix",
|
||||
"rev": "2b7761ffaded363d0d00afe320350cc5c9ee9012",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "purs-nix",
|
||||
"ref": "ps-0.15",
|
||||
"repo": "purs-nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs",
|
||||
"ps-tools": [
|
||||
"purs-nix",
|
||||
"ps-tools"
|
||||
],
|
||||
"purs-nix": "purs-nix",
|
||||
"utils": "utils_5"
|
||||
}
|
||||
},
|
||||
"rust-analyzer-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1655507737,
|
||||
"narHash": "sha256-o+AqNsjL6o2RHh4InZHQVpkmqg570YFJL4Db8mKq+fs=",
|
||||
"owner": "rust-lang",
|
||||
"repo": "rust-analyzer",
|
||||
"rev": "12dd81092e37df28b7a3591cae9675e668927198",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "rust-lang",
|
||||
"ref": "nightly",
|
||||
"repo": "rust-analyzer",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"rust-analyzer-src_2": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1655507737,
|
||||
"narHash": "sha256-o+AqNsjL6o2RHh4InZHQVpkmqg570YFJL4Db8mKq+fs=",
|
||||
"owner": "rust-lang",
|
||||
"repo": "rust-analyzer",
|
||||
"rev": "12dd81092e37df28b7a3591cae9675e668927198",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "rust-lang",
|
||||
"ref": "nightly",
|
||||
"repo": "rust-analyzer",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"rust-analyzer-src_3": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1645205556,
|
||||
"narHash": "sha256-e4lZW3qRyOEJ+vLKFQP7m2Dxh5P44NrnekZYLxlucww=",
|
||||
"owner": "rust-analyzer",
|
||||
"repo": "rust-analyzer",
|
||||
"rev": "acf5874b39f3dc5262317a6074d9fc7285081161",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "rust-analyzer",
|
||||
"ref": "nightly",
|
||||
"repo": "rust-analyzer",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"statix": {
|
||||
"inputs": {
|
||||
"fenix": "fenix_3",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": "nixpkgs_10"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1657460333,
|
||||
"narHash": "sha256-5o6zMBASEsGKtjKDb3SizJnN9A7qpOcbzWBXsacfMyc=",
|
||||
"owner": "nerdypepper",
|
||||
"repo": "statix",
|
||||
"rev": "6422c959d365dee2fda5eda8858fefad31f17b25",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nerdypepper",
|
||||
"repo": "statix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"utils": {
|
||||
"locked": {
|
||||
"lastModified": 1653893745,
|
||||
"narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"utils_2": {
|
||||
"locked": {
|
||||
"lastModified": 1653893745,
|
||||
"narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"utils_3": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1656044990,
|
||||
"narHash": "sha256-f01BB7CaOyntOab9XnpH9HD63rGcnu2iyL4M2ubs5F8=",
|
||||
"owner": "ursi",
|
||||
"repo": "flake-utils",
|
||||
"rev": "f53b674a2c90f6202a2f4cd491aba121775490b5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "ursi",
|
||||
"ref": "8",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"utils_4": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1656044990,
|
||||
"narHash": "sha256-f01BB7CaOyntOab9XnpH9HD63rGcnu2iyL4M2ubs5F8=",
|
||||
"owner": "ursi",
|
||||
"repo": "flake-utils",
|
||||
"rev": "f53b674a2c90f6202a2f4cd491aba121775490b5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "ursi",
|
||||
"ref": "8",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"utils_5": {
|
||||
"locked": {
|
||||
"lastModified": 1667395993,
|
||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
53
purescript/switcheroo/flake.nix
Normal file
53
purescript/switcheroo/flake.nix
Normal file
|
@ -0,0 +1,53 @@
|
|||
{ inputs =
|
||||
{ nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
ps-tools.follows = "purs-nix/ps-tools";
|
||||
purs-nix.url = "github:purs-nix/purs-nix/ps-0.15";
|
||||
utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { nixpkgs, utils, ... }@inputs:
|
||||
utils.lib.eachSystem [ "x86_64-linux" "x86_64-darwin" ]
|
||||
(system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
ps-tools = inputs.ps-tools.legacyPackages.${system};
|
||||
purs-nix = inputs.purs-nix { inherit system; };
|
||||
|
||||
ps =
|
||||
purs-nix.purs
|
||||
{ dependencies =
|
||||
with purs-nix.ps-pkgs;
|
||||
[ console
|
||||
effect
|
||||
prelude
|
||||
exists
|
||||
tuples
|
||||
indexed-monad
|
||||
aff
|
||||
];
|
||||
|
||||
dir = ./.;
|
||||
};
|
||||
in
|
||||
{ packages.default = ps.bundle {};
|
||||
|
||||
devShells.default =
|
||||
pkgs.mkShell
|
||||
{ packages =
|
||||
with pkgs;
|
||||
[ entr
|
||||
nodejs
|
||||
(ps.command {})
|
||||
ps-tools.for-0_15.purescript-language-server
|
||||
purs-nix.esbuild
|
||||
purs-nix.purescript
|
||||
];
|
||||
|
||||
shellHook =
|
||||
''
|
||||
alias watch="find src | entr -s 'echo bundling; purs-nix bundle'"
|
||||
'';
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
122
purescript/switcheroo/src/Main.purs
Normal file
122
purescript/switcheroo/src/Main.purs
Normal file
|
@ -0,0 +1,122 @@
|
|||
module Main where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Control.Monad.Indexed.Qualified as Ix
|
||||
import Data.Array as Array
|
||||
import Data.Identity (Identity(..))
|
||||
import Effect (Effect)
|
||||
import Effect.Console (log)
|
||||
import Safe.Coerce (coerce)
|
||||
import Swictheroo.Stream (ConsumeM, Producer, constantProducer, runConsumeM_, unitProducer)
|
||||
import Swictheroo.Stream as Stream
|
||||
|
||||
type Producers m =
|
||||
{ download :: Producer m Int
|
||||
, reportDownload :: Producer m String
|
||||
, ping :: Producer m Boolean
|
||||
}
|
||||
|
||||
program :: forall m. Monad m => Producers m -> ConsumeM m Unit Unit String
|
||||
program producers = Ix.do
|
||||
Stream.replace producers.download
|
||||
a <- Stream.pull
|
||||
|
||||
Stream.replace producers.reportDownload
|
||||
b <- Stream.pull
|
||||
|
||||
Stream.replace producers.ping
|
||||
c <- Stream.pull
|
||||
|
||||
Stream.replace unitProducer
|
||||
|
||||
pure $ Array.fold
|
||||
[ "Download: "
|
||||
, show a
|
||||
, ", Report: "
|
||||
, show b
|
||||
, ", Ping: "
|
||||
, show c
|
||||
]
|
||||
|
||||
{-
|
||||
Pseudo-code for testing:
|
||||
|
||||
data SyntheticEvent = Download Int | Report String | Ping Int
|
||||
|
||||
producers =
|
||||
{ download: case _ of
|
||||
Download s -> Just s
|
||||
_ -> Nothing
|
||||
, report: ...
|
||||
, ping: ...
|
||||
}
|
||||
|
||||
story =
|
||||
[ Emit (Download 7)
|
||||
, Expect Cancel
|
||||
, Emit (Report 7)
|
||||
, Expect Cancel
|
||||
, Emit (Ping 7)
|
||||
, Expect Cancel
|
||||
]
|
||||
-}
|
||||
|
||||
{- How do we cancel our program?
|
||||
|
||||
The program would require an extra producer called "cancel".
|
||||
Every time we call "Stream.replace", we would merge "cancel" with
|
||||
the respective new stream. This way, when we call "Stream.pull" we can
|
||||
either receive a "Left" (which means we must cancel) or a "Right"
|
||||
(which means we have gotten our value and can keep going).
|
||||
-}
|
||||
|
||||
{- All async effects should be avoided outside the internals of our monad!
|
||||
|
||||
Eg: do
|
||||
a <- lift $ Aff.wait ...
|
||||
|
||||
This is *bad*, because it means we cannot receive a cancellation event.
|
||||
|
||||
A better idea would be:
|
||||
do
|
||||
Stream.mapSource (\old -> merge old (fromAff (Aff.wait ...)))
|
||||
|
||||
result <- Stream.pull
|
||||
|
||||
case result of
|
||||
-- Our effect finished running!
|
||||
Left effectResult -> do
|
||||
-- Return to old producer
|
||||
Stream.mapSource Either.hush
|
||||
-- Do stuff with the result of the effect
|
||||
...
|
||||
|
||||
-- Try again later!
|
||||
Right otherResult -> do
|
||||
-- Handle the other result
|
||||
...
|
||||
|
||||
This does not block the other events at any point!
|
||||
Although this might look complicated, it's possible to create helpers for
|
||||
common patterns like this one!
|
||||
|
||||
Note that in an actual production codebase we would receive
|
||||
(fromAff (Aff.wait ...)) from the exterior in order to
|
||||
allow mocking and to not tie ourselves to a specific monad.
|
||||
-}
|
||||
|
||||
{- One cool thing about this approach is
|
||||
that simple state can be kept without the need for StateT!
|
||||
(because we can simply pass around values)
|
||||
-}
|
||||
|
||||
main :: Effect Unit
|
||||
main = log (coerce result)
|
||||
where
|
||||
result :: Identity _
|
||||
result = runConsumeM_ $ program
|
||||
{ download: constantProducer 3
|
||||
, reportDownload: constantProducer "foo"
|
||||
, ping: constantProducer true
|
||||
}
|
167
purescript/switcheroo/src/Stream.purs
Normal file
167
purescript/switcheroo/src/Stream.purs
Normal file
|
@ -0,0 +1,167 @@
|
|||
module Swictheroo.Stream where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Control.Alt (class Alt)
|
||||
import Control.Alternative (class Plus, (<|>))
|
||||
import Control.Applicative.Indexed (class IxApplicative, class IxApply, class IxFunctor)
|
||||
import Control.Bind.Indexed (class IxBind)
|
||||
import Control.Monad.Indexed (class IxMonad, iap, iapply, ibind, imap, ipure)
|
||||
import Control.Parallel (parOneOf, parSequence_)
|
||||
import Data.Bifunctor (bimap)
|
||||
import Data.Either (Either(..))
|
||||
import Data.Lazy (Lazy)
|
||||
import Data.Lazy as Lazy
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Data.Profunctor.Strong (first)
|
||||
import Data.Tuple.Nested (type (/\), (/\))
|
||||
import Effect.Aff (Aff, never)
|
||||
|
||||
-- | A producer can:
|
||||
-- | - Produce values
|
||||
-- | - Destroy itself
|
||||
newtype Producer m a =
|
||||
Producer
|
||||
{ destroy :: m Unit
|
||||
-- | Producers advance to a new version once they produce a value.
|
||||
-- | This allows pure producers to exist. For example, a pure producer
|
||||
-- | could hold an array of events, return the first one, and then create
|
||||
-- | a new producer from the tail of the array
|
||||
, produce :: m (Lazy (a /\ Producer m a))
|
||||
}
|
||||
|
||||
produce :: forall m i. Monad m => Producer m i -> m (i /\ Producer m i)
|
||||
produce (Producer producer) = producer.produce <#> Lazy.force
|
||||
|
||||
destroyProducer :: forall m i. Monad m => Producer m i -> m Unit
|
||||
destroyProducer (Producer producer) = producer.destroy
|
||||
|
||||
constantProducer :: forall m a. Monad m => a -> Producer m a
|
||||
constantProducer value = Producer
|
||||
{ destroy: pure unit
|
||||
, produce: pure $ Lazy.defer \_ -> value /\ (constantProducer value)
|
||||
}
|
||||
|
||||
unitProducer :: forall m. Monad m => Producer m Unit
|
||||
unitProducer = constantProducer unit
|
||||
|
||||
filterMapProducer :: forall a b m. Monad m => (a -> Maybe b) -> Producer m a -> Producer m b
|
||||
filterMapProducer f producer = Producer
|
||||
{ destroy: destroyProducer producer
|
||||
, produce: loop producer
|
||||
}
|
||||
where
|
||||
-- Keeps producing values until one matches the given predicate!
|
||||
loop producer = do
|
||||
value /\ producer' <- produce producer
|
||||
case f value of
|
||||
Nothing -> loop producer'
|
||||
Just updated -> pure $ Lazy.defer \_ -> updated /\ (filterMapProducer f producer')
|
||||
|
||||
-- | Type parameter explanation:
|
||||
-- | - m = underlying monad
|
||||
-- | - i = what the producer present when
|
||||
-- | the computation *starts* needs to produce
|
||||
-- | - o = what the producer present when
|
||||
-- | the computation *ends* needs to produce
|
||||
-- | - a = result of the computation
|
||||
-- |
|
||||
-- | This monad encapsulates the followin 3 operations:
|
||||
-- | - Consuming values from a producer
|
||||
-- | - Cancelling + replacing the current producer with a different one.
|
||||
newtype ConsumeM m i o a = ConsumeM
|
||||
( Producer m i -> m (a /\ Producer m o)
|
||||
)
|
||||
|
||||
pull :: forall m i. Monad m => ConsumeM m i i i
|
||||
pull = ConsumeM produce
|
||||
|
||||
replace :: forall m i o. Monad m => Producer m o -> ConsumeM m i o Unit
|
||||
replace producer' = ConsumeM \producer -> do
|
||||
destroyProducer producer
|
||||
pure (unit /\ producer')
|
||||
|
||||
lift :: forall m i a. Monad m => m a -> ConsumeM m i i a
|
||||
lift computation = ConsumeM \producer -> do
|
||||
result <- computation
|
||||
pure (result /\ producer)
|
||||
|
||||
producer :: forall m i. Monad m => ConsumeM m i i (Producer m i)
|
||||
producer = ConsumeM \p -> pure (p /\ p)
|
||||
|
||||
mapSource :: forall m i o. Monad m => (Producer m i -> Producer m o) -> ConsumeM m i o Unit
|
||||
mapSource f = ConsumeM \producer -> do
|
||||
pure (unit /\ f producer)
|
||||
|
||||
runConsumeM :: forall m i o a. Monad m => Producer m i -> ConsumeM m i o a -> m a
|
||||
runConsumeM producer (ConsumeM run) = do
|
||||
result /\ producer' <- run producer
|
||||
destroyProducer producer'
|
||||
pure result
|
||||
|
||||
runConsumeM_ :: forall m a o. Monad m => ConsumeM m Unit o a -> m a
|
||||
runConsumeM_ = runConsumeM unitProducer
|
||||
|
||||
---------- Typeclass instances
|
||||
instance Functor m => Functor (Producer m) where
|
||||
map f (Producer producer) = Producer
|
||||
{ destroy: producer.destroy
|
||||
, produce: producer.produce <#> map (bimap f (map f))
|
||||
}
|
||||
|
||||
instance Functor m => IxFunctor (ConsumeM m) where
|
||||
imap f (ConsumeM consumer) = ConsumeM
|
||||
\producer -> consumer producer <#> first f
|
||||
|
||||
instance Functor m => Functor (ConsumeM m i i) where
|
||||
map = imap
|
||||
|
||||
instance Monad m => IxApply (ConsumeM m) where
|
||||
iapply = iap
|
||||
|
||||
instance Monad m => Apply (ConsumeM m i i) where
|
||||
apply = iapply
|
||||
|
||||
instance Monad m => IxApplicative (ConsumeM m) where
|
||||
ipure a = ConsumeM \p -> pure (a /\ p)
|
||||
|
||||
instance Monad m => Applicative (ConsumeM m i i) where
|
||||
pure = ipure
|
||||
|
||||
instance Monad m => IxBind (ConsumeM m) where
|
||||
ibind (ConsumeM consumer) f = ConsumeM
|
||||
\producer -> do
|
||||
result /\ producer' <- consumer producer
|
||||
let (ConsumeM consumer') = f result
|
||||
consumer' producer'
|
||||
|
||||
instance Monad m => Bind (ConsumeM m i i) where
|
||||
bind = ibind
|
||||
|
||||
instance Monad m => IxMonad (ConsumeM m)
|
||||
instance Monad m => Monad (ConsumeM m i i)
|
||||
|
||||
---------- Merge producers
|
||||
type AffProducer = Producer Aff
|
||||
|
||||
instance Alt AffProducer where
|
||||
alt first second = Producer
|
||||
{ destroy:
|
||||
parSequence_
|
||||
[ destroyProducer first
|
||||
, destroyProducer second
|
||||
]
|
||||
, produce: ado
|
||||
result <- parOneOf
|
||||
[ produce first <#> Left
|
||||
, produce second <#> Right
|
||||
]
|
||||
in
|
||||
pure case result of
|
||||
Left (result /\ first') -> result /\ (first' <|> second)
|
||||
Right (result /\ second') -> result /\ (first <|> second')
|
||||
}
|
||||
|
||||
instance Plus AffProducer where
|
||||
empty = Producer { destroy: pure unit, produce: never }
|
||||
|
Loading…
Reference in a new issue