├── .gitignore ├── .purty.dhall ├── LICENSE ├── README.md ├── docs ├── Purescript-Concur-Performance.png └── logo.png ├── package.json ├── pnpm-lock.yaml ├── spago.lock ├── spago.yaml ├── src ├── Concur │ ├── Core.purs │ └── Core │ │ ├── DOM.purs │ │ ├── LiftWidget.purs │ │ ├── Patterns.purs │ │ └── Types.purs └── Control │ ├── MonadFix.js │ ├── MonadFix.purs │ ├── MultiAlternative.purs │ └── ShiftMap.purs └── test └── Test └── Main.purs /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | npm-debug.log 3 | node_modules/ 4 | bower_components/ 5 | tmp/ 6 | output/ 7 | html/index.js 8 | /.psc-package 9 | /.cache 10 | /dist 11 | /.psci_modules 12 | /.spago 13 | /package-lock.json 14 | .spago 15 | .cache 16 | dist 17 | /.psc-ide-port 18 | -------------------------------------------------------------------------------- /.purty.dhall: -------------------------------------------------------------------------------- 1 | { formatting = 2 | < Dynamic = {=} | Static : {} > 3 | , output = 4 | < InPlace = {=} | StdOut : {} > 5 | , verbosity = 6 | < NotVerbose = {=} | Verbose : {} > 7 | } 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017-2020 Anupam Jain 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a 4 | copy of this software and associated documentation files (the 5 | "Software"), in the Software without restriction, including without 6 | limitation the rights to use, copy, modify, merge, publish, distribute, 7 | sublicense, and/or sell copies of the Software, and to permit persons to 8 | whom the Software is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Purescript Concur Core 3 |

4 |

5 | 6 |

7 |

8 | 9 | Join the chat at https://gitter.im/concurhaskell 10 | 11 | 12 | Join the chat at https://gitter.im/concurhaskell 13 | 14 | 15 | Purescript-Concur-Core on Pursuit 17 | 18 | 19 |

20 | 21 | [Concur UI Lib](https://github.com/ajnsit/concur) is a brand new client side Web UI framework that explores an entirely new paradigm. It does not follow FRP (think Reflex or Reactive Banana), or Elm architecture, but aims to combine the best parts of both. This repo contains the Concur implementation for Purescript, Core components only. It does **NOT** include a UI backend. For example, please look at [Purescript-Concur-React](https://pursuit.purescript.org/packages/purescript-concur-react) to use the React backend. 22 | 23 | ## Documentation 24 | 25 | Work in progress tutorials are published in the [Concur Documentation site](https://github.com/ajnsit/concur-documentation/blob/master/README.md) 26 | 27 | API documentation is [published on Pursuit](https://pursuit.purescript.org/packages/purescript-concur-core). 28 | 29 | ## Performance 30 | 31 | Purescript-Concur is reasonably light. The [entire *uncompressed* JS bundle](https://github.com/purescript-concur/purescript-concur-react/blob/master/docs/index.prod.minified.0dfb135e.js), including react and all libraries, for the entire example application in this repo clocks in at 180KB. You can build this bundle yourself with the command `npm run prod` (*currently broken* due to the move to spago). 32 | 33 | This leads to pretty fast initial load times. Running the Chrome audit on https://ajnsit.github.io/purescript-concur/ produces - 34 | 35 |

36 | 37 |

38 | 39 | ## Ports to other languages 40 | 41 | Concur's model translates well to other platforms. 42 | 43 | 1. [Concur for Haskell](https://github.com/ajnsit/concur) - The original version of Concur written in Haskell. 44 | 2. [Concur for Javascript](https://github.com/ajnsit/concur-js) - An official but experimental port to Javascript. 45 | 3. [Concur for Python](https://github.com/potocpav/python-concur) - An unofficial and experimental port to Python. Uses ImgUI for graphics. Created and Maintained by [potocpav](https://github.com/potocpav). 46 | 47 | ## Installation 48 | 49 | You can quickly get a production setup going (using Spago and Parcel) by cloning the [Purescript Concur Starter](https://github.com/purescript-concur/purescript-concur-starter). 50 | 51 | Else, if you use Spago - 52 | 53 | ```bash 54 | spago install concur-core 55 | ``` 56 | 57 | Or if you use Bower - 58 | 59 | ```bash 60 | bower install purescript-concur-core 61 | ``` 62 | 63 | ## Building from source 64 | 65 | ```bash 66 | git clone https://github.com/purescript-concur/purescript-concur-core.git 67 | cd purescript-concur-core 68 | npm install 69 | # Build source and examples 70 | npm run build 71 | ``` 72 | 73 | #### Note that you will need to choose a Concur backend (such as the [React backend](https://pursuit.purescript.org/packages/purescript-concur-react)) before you can use the library to build UIs. 74 | -------------------------------------------------------------------------------- /docs/Purescript-Concur-Performance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purescript-concur/purescript-concur-core/733d283e8993cac7867b70fda51e1fc013cc451b/docs/Purescript-Concur-Performance.png -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purescript-concur/purescript-concur-core/733d283e8993cac7867b70fda51e1fc013cc451b/docs/logo.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "purescript-concur-core", 3 | "version": "0.5.0", 4 | "description": "Concur UI framework for Purescript, Core framework.", 5 | "license": "MIT", 6 | "repository": "purescript-concur/purescript-concur-core", 7 | "author": { 8 | "name": "Anupam Jain", 9 | "email": "ajnsit@gmail.com" 10 | }, 11 | "files": [], 12 | "scripts": { 13 | "build": "spago build", 14 | "test": "spago -x test.dhall test" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | spago-legacy: 12 | specifier: ^0.21.0 13 | version: 0.21.0 14 | 15 | packages: 16 | 17 | '@isaacs/cliui@8.0.2': 18 | resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} 19 | engines: {node: '>=12'} 20 | 21 | '@npmcli/fs@3.1.1': 22 | resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} 23 | engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} 24 | 25 | '@pkgjs/parseargs@0.11.0': 26 | resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} 27 | engines: {node: '>=14'} 28 | 29 | '@tootallnate/once@2.0.0': 30 | resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} 31 | engines: {node: '>= 10'} 32 | 33 | agent-base@6.0.2: 34 | resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} 35 | engines: {node: '>= 6.0.0'} 36 | 37 | agentkeepalive@4.5.0: 38 | resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} 39 | engines: {node: '>= 8.0.0'} 40 | 41 | aggregate-error@3.1.0: 42 | resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} 43 | engines: {node: '>=8'} 44 | 45 | ansi-regex@5.0.1: 46 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 47 | engines: {node: '>=8'} 48 | 49 | ansi-regex@6.1.0: 50 | resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} 51 | engines: {node: '>=12'} 52 | 53 | ansi-styles@4.3.0: 54 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 55 | engines: {node: '>=8'} 56 | 57 | ansi-styles@6.2.1: 58 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} 59 | engines: {node: '>=12'} 60 | 61 | balanced-match@1.0.2: 62 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 63 | 64 | brace-expansion@2.0.1: 65 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} 66 | 67 | cacache@17.1.4: 68 | resolution: {integrity: sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==} 69 | engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} 70 | 71 | chownr@2.0.0: 72 | resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} 73 | engines: {node: '>=10'} 74 | 75 | clean-stack@2.2.0: 76 | resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} 77 | engines: {node: '>=6'} 78 | 79 | color-convert@2.0.1: 80 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 81 | engines: {node: '>=7.0.0'} 82 | 83 | color-name@1.1.4: 84 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 85 | 86 | cross-spawn@7.0.3: 87 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} 88 | engines: {node: '>= 8'} 89 | 90 | debug@4.3.4: 91 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 92 | engines: {node: '>=6.0'} 93 | peerDependencies: 94 | supports-color: '*' 95 | peerDependenciesMeta: 96 | supports-color: 97 | optional: true 98 | 99 | eastasianwidth@0.2.0: 100 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} 101 | 102 | emoji-regex@8.0.0: 103 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 104 | 105 | emoji-regex@9.2.2: 106 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 107 | 108 | encoding@0.1.13: 109 | resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} 110 | 111 | err-code@2.0.3: 112 | resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} 113 | 114 | foreground-child@3.3.0: 115 | resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} 116 | engines: {node: '>=14'} 117 | 118 | fs-minipass@2.1.0: 119 | resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} 120 | engines: {node: '>= 8'} 121 | 122 | fs-minipass@3.0.3: 123 | resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} 124 | engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} 125 | 126 | glob@10.4.5: 127 | resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} 128 | hasBin: true 129 | 130 | http-cache-semantics@4.1.1: 131 | resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} 132 | 133 | http-proxy-agent@5.0.0: 134 | resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} 135 | engines: {node: '>= 6'} 136 | 137 | https-proxy-agent@5.0.1: 138 | resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} 139 | engines: {node: '>= 6'} 140 | 141 | humanize-ms@1.2.1: 142 | resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} 143 | 144 | iconv-lite@0.6.3: 145 | resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} 146 | engines: {node: '>=0.10.0'} 147 | 148 | imurmurhash@0.1.4: 149 | resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} 150 | engines: {node: '>=0.8.19'} 151 | 152 | indent-string@4.0.0: 153 | resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} 154 | engines: {node: '>=8'} 155 | 156 | ip-address@9.0.5: 157 | resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} 158 | engines: {node: '>= 12'} 159 | 160 | is-fullwidth-code-point@3.0.0: 161 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 162 | engines: {node: '>=8'} 163 | 164 | is-lambda@1.0.1: 165 | resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} 166 | 167 | isexe@2.0.0: 168 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 169 | 170 | jackspeak@3.4.3: 171 | resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} 172 | 173 | jsbn@1.1.0: 174 | resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} 175 | 176 | lru-cache@10.4.3: 177 | resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} 178 | 179 | lru-cache@7.18.3: 180 | resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} 181 | engines: {node: '>=12'} 182 | 183 | make-fetch-happen@11.1.1: 184 | resolution: {integrity: sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==} 185 | engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} 186 | 187 | minimatch@9.0.5: 188 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} 189 | engines: {node: '>=16 || 14 >=14.17'} 190 | 191 | minipass-collect@1.0.2: 192 | resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} 193 | engines: {node: '>= 8'} 194 | 195 | minipass-fetch@3.0.5: 196 | resolution: {integrity: sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==} 197 | engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} 198 | 199 | minipass-flush@1.0.5: 200 | resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} 201 | engines: {node: '>= 8'} 202 | 203 | minipass-pipeline@1.2.4: 204 | resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} 205 | engines: {node: '>=8'} 206 | 207 | minipass-sized@1.0.3: 208 | resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} 209 | engines: {node: '>=8'} 210 | 211 | minipass@3.3.6: 212 | resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} 213 | engines: {node: '>=8'} 214 | 215 | minipass@5.0.0: 216 | resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} 217 | engines: {node: '>=8'} 218 | 219 | minipass@7.1.2: 220 | resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} 221 | engines: {node: '>=16 || 14 >=14.17'} 222 | 223 | minizlib@2.1.2: 224 | resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} 225 | engines: {node: '>= 8'} 226 | 227 | mkdirp@1.0.4: 228 | resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} 229 | engines: {node: '>=10'} 230 | hasBin: true 231 | 232 | ms@2.1.2: 233 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 234 | 235 | ms@2.1.3: 236 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 237 | 238 | negotiator@0.6.3: 239 | resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} 240 | engines: {node: '>= 0.6'} 241 | 242 | p-map@4.0.0: 243 | resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} 244 | engines: {node: '>=10'} 245 | 246 | package-json-from-dist@1.0.1: 247 | resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} 248 | 249 | path-key@3.1.1: 250 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 251 | engines: {node: '>=8'} 252 | 253 | path-scurry@1.11.1: 254 | resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} 255 | engines: {node: '>=16 || 14 >=14.18'} 256 | 257 | promise-retry@2.0.1: 258 | resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} 259 | engines: {node: '>=10'} 260 | 261 | retry@0.12.0: 262 | resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} 263 | engines: {node: '>= 4'} 264 | 265 | safer-buffer@2.1.2: 266 | resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} 267 | 268 | semver@7.6.1: 269 | resolution: {integrity: sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==} 270 | engines: {node: '>=10'} 271 | hasBin: true 272 | 273 | shebang-command@2.0.0: 274 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 275 | engines: {node: '>=8'} 276 | 277 | shebang-regex@3.0.0: 278 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 279 | engines: {node: '>=8'} 280 | 281 | signal-exit@4.1.0: 282 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 283 | engines: {node: '>=14'} 284 | 285 | smart-buffer@4.2.0: 286 | resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} 287 | engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} 288 | 289 | socks-proxy-agent@7.0.0: 290 | resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} 291 | engines: {node: '>= 10'} 292 | 293 | socks@2.8.3: 294 | resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} 295 | engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} 296 | 297 | spago-legacy@0.21.0: 298 | resolution: {integrity: sha512-tGxrzcqlcsJ69nS8Bxtmmvf8L23Obzouf5OX2oE3O/A5mSN8mKjoknjFtUgX9zyI+8wgaYOUF9Jag3kTYaTRiA==} 299 | hasBin: true 300 | 301 | sprintf-js@1.1.3: 302 | resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} 303 | 304 | ssri@10.0.6: 305 | resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} 306 | engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} 307 | 308 | string-width@4.2.3: 309 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 310 | engines: {node: '>=8'} 311 | 312 | string-width@5.1.2: 313 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} 314 | engines: {node: '>=12'} 315 | 316 | strip-ansi@6.0.1: 317 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 318 | engines: {node: '>=8'} 319 | 320 | strip-ansi@7.1.0: 321 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} 322 | engines: {node: '>=12'} 323 | 324 | tar@6.2.1: 325 | resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} 326 | engines: {node: '>=10'} 327 | 328 | unique-filename@3.0.0: 329 | resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} 330 | engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} 331 | 332 | unique-slug@4.0.0: 333 | resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} 334 | engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} 335 | 336 | which@2.0.2: 337 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 338 | engines: {node: '>= 8'} 339 | hasBin: true 340 | 341 | wrap-ansi@7.0.0: 342 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 343 | engines: {node: '>=10'} 344 | 345 | wrap-ansi@8.1.0: 346 | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} 347 | engines: {node: '>=12'} 348 | 349 | yallist@4.0.0: 350 | resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} 351 | 352 | snapshots: 353 | 354 | '@isaacs/cliui@8.0.2': 355 | dependencies: 356 | string-width: 5.1.2 357 | string-width-cjs: string-width@4.2.3 358 | strip-ansi: 7.1.0 359 | strip-ansi-cjs: strip-ansi@6.0.1 360 | wrap-ansi: 8.1.0 361 | wrap-ansi-cjs: wrap-ansi@7.0.0 362 | 363 | '@npmcli/fs@3.1.1': 364 | dependencies: 365 | semver: 7.6.1 366 | 367 | '@pkgjs/parseargs@0.11.0': 368 | optional: true 369 | 370 | '@tootallnate/once@2.0.0': {} 371 | 372 | agent-base@6.0.2: 373 | dependencies: 374 | debug: 4.3.4 375 | transitivePeerDependencies: 376 | - supports-color 377 | 378 | agentkeepalive@4.5.0: 379 | dependencies: 380 | humanize-ms: 1.2.1 381 | 382 | aggregate-error@3.1.0: 383 | dependencies: 384 | clean-stack: 2.2.0 385 | indent-string: 4.0.0 386 | 387 | ansi-regex@5.0.1: {} 388 | 389 | ansi-regex@6.1.0: {} 390 | 391 | ansi-styles@4.3.0: 392 | dependencies: 393 | color-convert: 2.0.1 394 | 395 | ansi-styles@6.2.1: {} 396 | 397 | balanced-match@1.0.2: {} 398 | 399 | brace-expansion@2.0.1: 400 | dependencies: 401 | balanced-match: 1.0.2 402 | 403 | cacache@17.1.4: 404 | dependencies: 405 | '@npmcli/fs': 3.1.1 406 | fs-minipass: 3.0.3 407 | glob: 10.4.5 408 | lru-cache: 7.18.3 409 | minipass: 7.1.2 410 | minipass-collect: 1.0.2 411 | minipass-flush: 1.0.5 412 | minipass-pipeline: 1.2.4 413 | p-map: 4.0.0 414 | ssri: 10.0.6 415 | tar: 6.2.1 416 | unique-filename: 3.0.0 417 | 418 | chownr@2.0.0: {} 419 | 420 | clean-stack@2.2.0: {} 421 | 422 | color-convert@2.0.1: 423 | dependencies: 424 | color-name: 1.1.4 425 | 426 | color-name@1.1.4: {} 427 | 428 | cross-spawn@7.0.3: 429 | dependencies: 430 | path-key: 3.1.1 431 | shebang-command: 2.0.0 432 | which: 2.0.2 433 | 434 | debug@4.3.4: 435 | dependencies: 436 | ms: 2.1.2 437 | 438 | eastasianwidth@0.2.0: {} 439 | 440 | emoji-regex@8.0.0: {} 441 | 442 | emoji-regex@9.2.2: {} 443 | 444 | encoding@0.1.13: 445 | dependencies: 446 | iconv-lite: 0.6.3 447 | optional: true 448 | 449 | err-code@2.0.3: {} 450 | 451 | foreground-child@3.3.0: 452 | dependencies: 453 | cross-spawn: 7.0.3 454 | signal-exit: 4.1.0 455 | 456 | fs-minipass@2.1.0: 457 | dependencies: 458 | minipass: 3.3.6 459 | 460 | fs-minipass@3.0.3: 461 | dependencies: 462 | minipass: 7.1.2 463 | 464 | glob@10.4.5: 465 | dependencies: 466 | foreground-child: 3.3.0 467 | jackspeak: 3.4.3 468 | minimatch: 9.0.5 469 | minipass: 7.1.2 470 | package-json-from-dist: 1.0.1 471 | path-scurry: 1.11.1 472 | 473 | http-cache-semantics@4.1.1: {} 474 | 475 | http-proxy-agent@5.0.0: 476 | dependencies: 477 | '@tootallnate/once': 2.0.0 478 | agent-base: 6.0.2 479 | debug: 4.3.4 480 | transitivePeerDependencies: 481 | - supports-color 482 | 483 | https-proxy-agent@5.0.1: 484 | dependencies: 485 | agent-base: 6.0.2 486 | debug: 4.3.4 487 | transitivePeerDependencies: 488 | - supports-color 489 | 490 | humanize-ms@1.2.1: 491 | dependencies: 492 | ms: 2.1.3 493 | 494 | iconv-lite@0.6.3: 495 | dependencies: 496 | safer-buffer: 2.1.2 497 | optional: true 498 | 499 | imurmurhash@0.1.4: {} 500 | 501 | indent-string@4.0.0: {} 502 | 503 | ip-address@9.0.5: 504 | dependencies: 505 | jsbn: 1.1.0 506 | sprintf-js: 1.1.3 507 | 508 | is-fullwidth-code-point@3.0.0: {} 509 | 510 | is-lambda@1.0.1: {} 511 | 512 | isexe@2.0.0: {} 513 | 514 | jackspeak@3.4.3: 515 | dependencies: 516 | '@isaacs/cliui': 8.0.2 517 | optionalDependencies: 518 | '@pkgjs/parseargs': 0.11.0 519 | 520 | jsbn@1.1.0: {} 521 | 522 | lru-cache@10.4.3: {} 523 | 524 | lru-cache@7.18.3: {} 525 | 526 | make-fetch-happen@11.1.1: 527 | dependencies: 528 | agentkeepalive: 4.5.0 529 | cacache: 17.1.4 530 | http-cache-semantics: 4.1.1 531 | http-proxy-agent: 5.0.0 532 | https-proxy-agent: 5.0.1 533 | is-lambda: 1.0.1 534 | lru-cache: 7.18.3 535 | minipass: 5.0.0 536 | minipass-fetch: 3.0.5 537 | minipass-flush: 1.0.5 538 | minipass-pipeline: 1.2.4 539 | negotiator: 0.6.3 540 | promise-retry: 2.0.1 541 | socks-proxy-agent: 7.0.0 542 | ssri: 10.0.6 543 | transitivePeerDependencies: 544 | - supports-color 545 | 546 | minimatch@9.0.5: 547 | dependencies: 548 | brace-expansion: 2.0.1 549 | 550 | minipass-collect@1.0.2: 551 | dependencies: 552 | minipass: 3.3.6 553 | 554 | minipass-fetch@3.0.5: 555 | dependencies: 556 | minipass: 7.1.2 557 | minipass-sized: 1.0.3 558 | minizlib: 2.1.2 559 | optionalDependencies: 560 | encoding: 0.1.13 561 | 562 | minipass-flush@1.0.5: 563 | dependencies: 564 | minipass: 3.3.6 565 | 566 | minipass-pipeline@1.2.4: 567 | dependencies: 568 | minipass: 3.3.6 569 | 570 | minipass-sized@1.0.3: 571 | dependencies: 572 | minipass: 3.3.6 573 | 574 | minipass@3.3.6: 575 | dependencies: 576 | yallist: 4.0.0 577 | 578 | minipass@5.0.0: {} 579 | 580 | minipass@7.1.2: {} 581 | 582 | minizlib@2.1.2: 583 | dependencies: 584 | minipass: 3.3.6 585 | yallist: 4.0.0 586 | 587 | mkdirp@1.0.4: {} 588 | 589 | ms@2.1.2: {} 590 | 591 | ms@2.1.3: {} 592 | 593 | negotiator@0.6.3: {} 594 | 595 | p-map@4.0.0: 596 | dependencies: 597 | aggregate-error: 3.1.0 598 | 599 | package-json-from-dist@1.0.1: {} 600 | 601 | path-key@3.1.1: {} 602 | 603 | path-scurry@1.11.1: 604 | dependencies: 605 | lru-cache: 10.4.3 606 | minipass: 7.1.2 607 | 608 | promise-retry@2.0.1: 609 | dependencies: 610 | err-code: 2.0.3 611 | retry: 0.12.0 612 | 613 | retry@0.12.0: {} 614 | 615 | safer-buffer@2.1.2: 616 | optional: true 617 | 618 | semver@7.6.1: {} 619 | 620 | shebang-command@2.0.0: 621 | dependencies: 622 | shebang-regex: 3.0.0 623 | 624 | shebang-regex@3.0.0: {} 625 | 626 | signal-exit@4.1.0: {} 627 | 628 | smart-buffer@4.2.0: {} 629 | 630 | socks-proxy-agent@7.0.0: 631 | dependencies: 632 | agent-base: 6.0.2 633 | debug: 4.3.4 634 | socks: 2.8.3 635 | transitivePeerDependencies: 636 | - supports-color 637 | 638 | socks@2.8.3: 639 | dependencies: 640 | ip-address: 9.0.5 641 | smart-buffer: 4.2.0 642 | 643 | spago-legacy@0.21.0: 644 | dependencies: 645 | make-fetch-happen: 11.1.1 646 | tar: 6.2.1 647 | transitivePeerDependencies: 648 | - supports-color 649 | 650 | sprintf-js@1.1.3: {} 651 | 652 | ssri@10.0.6: 653 | dependencies: 654 | minipass: 7.1.2 655 | 656 | string-width@4.2.3: 657 | dependencies: 658 | emoji-regex: 8.0.0 659 | is-fullwidth-code-point: 3.0.0 660 | strip-ansi: 6.0.1 661 | 662 | string-width@5.1.2: 663 | dependencies: 664 | eastasianwidth: 0.2.0 665 | emoji-regex: 9.2.2 666 | strip-ansi: 7.1.0 667 | 668 | strip-ansi@6.0.1: 669 | dependencies: 670 | ansi-regex: 5.0.1 671 | 672 | strip-ansi@7.1.0: 673 | dependencies: 674 | ansi-regex: 6.1.0 675 | 676 | tar@6.2.1: 677 | dependencies: 678 | chownr: 2.0.0 679 | fs-minipass: 2.1.0 680 | minipass: 5.0.0 681 | minizlib: 2.1.2 682 | mkdirp: 1.0.4 683 | yallist: 4.0.0 684 | 685 | unique-filename@3.0.0: 686 | dependencies: 687 | unique-slug: 4.0.0 688 | 689 | unique-slug@4.0.0: 690 | dependencies: 691 | imurmurhash: 0.1.4 692 | 693 | which@2.0.2: 694 | dependencies: 695 | isexe: 2.0.0 696 | 697 | wrap-ansi@7.0.0: 698 | dependencies: 699 | ansi-styles: 4.3.0 700 | string-width: 4.2.3 701 | strip-ansi: 6.0.1 702 | 703 | wrap-ansi@8.1.0: 704 | dependencies: 705 | ansi-styles: 6.2.1 706 | string-width: 5.1.2 707 | strip-ansi: 7.1.0 708 | 709 | yallist@4.0.0: {} 710 | -------------------------------------------------------------------------------- /spago.lock: -------------------------------------------------------------------------------- 1 | { 2 | "workspace": { 3 | "packages": { 4 | "concur-core": { 5 | "path": "./", 6 | "core": { 7 | "dependencies": [ 8 | "arrays", 9 | "control", 10 | "effect", 11 | "either", 12 | "foldable-traversable", 13 | "identity", 14 | "maybe", 15 | "newtype", 16 | "prelude", 17 | "profunctor-lenses", 18 | "refs", 19 | "tailrec", 20 | "transformers", 21 | "tuples", 22 | "unsafe-reference" 23 | ], 24 | "build_plan": [ 25 | "arrays", 26 | "bifunctors", 27 | "const", 28 | "contravariant", 29 | "control", 30 | "distributive", 31 | "effect", 32 | "either", 33 | "exceptions", 34 | "exists", 35 | "foldable-traversable", 36 | "foreign-object", 37 | "functions", 38 | "functors", 39 | "gen", 40 | "identity", 41 | "invariant", 42 | "lazy", 43 | "lists", 44 | "maybe", 45 | "newtype", 46 | "nonempty", 47 | "ordered-collections", 48 | "orders", 49 | "partial", 50 | "prelude", 51 | "profunctor", 52 | "profunctor-lenses", 53 | "record", 54 | "refs", 55 | "safe-coerce", 56 | "st", 57 | "tailrec", 58 | "transformers", 59 | "tuples", 60 | "type-equality", 61 | "typelevel-prelude", 62 | "unfoldable", 63 | "unsafe-coerce", 64 | "unsafe-reference" 65 | ] 66 | }, 67 | "test": { 68 | "dependencies": [ 69 | "console", 70 | "spec" 71 | ], 72 | "build_plan": [ 73 | "aff", 74 | "ansi", 75 | "arrays", 76 | "avar", 77 | "bifunctors", 78 | "catenable-lists", 79 | "console", 80 | "const", 81 | "contravariant", 82 | "control", 83 | "datetime", 84 | "distributive", 85 | "effect", 86 | "either", 87 | "enums", 88 | "exceptions", 89 | "exists", 90 | "foldable-traversable", 91 | "fork", 92 | "free", 93 | "functions", 94 | "functors", 95 | "gen", 96 | "identity", 97 | "integers", 98 | "invariant", 99 | "lazy", 100 | "lists", 101 | "maybe", 102 | "mmorph", 103 | "newtype", 104 | "nonempty", 105 | "now", 106 | "numbers", 107 | "ordered-collections", 108 | "orders", 109 | "parallel", 110 | "partial", 111 | "pipes", 112 | "prelude", 113 | "profunctor", 114 | "refs", 115 | "safe-coerce", 116 | "spec", 117 | "st", 118 | "strings", 119 | "tailrec", 120 | "transformers", 121 | "tuples", 122 | "type-equality", 123 | "unfoldable", 124 | "unsafe-coerce" 125 | ] 126 | } 127 | } 128 | }, 129 | "package_set": { 130 | "address": { 131 | "registry": "61.3.1" 132 | }, 133 | "compiler": ">=0.15.15 <0.16.0", 134 | "content": { 135 | "abc-parser": "2.0.1", 136 | "ace": "9.1.0", 137 | "address-rfc2821": "0.1.1", 138 | "aff": "8.0.0", 139 | "aff-bus": "6.0.0", 140 | "aff-coroutines": "9.0.0", 141 | "aff-promise": "4.0.0", 142 | "aff-retry": "2.0.0", 143 | "affjax": "13.0.0", 144 | "affjax-node": "1.0.0", 145 | "affjax-web": "1.0.0", 146 | "ansi": "7.0.0", 147 | "apexcharts": "0.5.0", 148 | "applicative-phases": "1.0.0", 149 | "argonaut": "9.0.0", 150 | "argonaut-aeson-generic": "0.4.1", 151 | "argonaut-codecs": "9.1.0", 152 | "argonaut-core": "7.0.0", 153 | "argonaut-generic": "8.0.0", 154 | "argonaut-traversals": "10.0.0", 155 | "argparse-basic": "2.0.0", 156 | "array-builder": "0.1.2", 157 | "array-search": "0.6.0", 158 | "arraybuffer": "13.2.0", 159 | "arraybuffer-builder": "3.1.0", 160 | "arraybuffer-types": "3.0.2", 161 | "arrays": "7.3.0", 162 | "arrays-extra": "0.6.1", 163 | "arrays-zipper": "2.0.1", 164 | "ask": "1.0.0", 165 | "assert": "6.0.0", 166 | "assert-multiple": "0.4.0", 167 | "avar": "5.0.0", 168 | "b64": "0.0.8", 169 | "barbies": "1.0.1", 170 | "barlow-lens": "0.9.0", 171 | "bifunctors": "6.0.0", 172 | "bigints": "7.0.1", 173 | "bolson": "0.3.9", 174 | "bookhound": "0.1.7", 175 | "bower-json": "3.0.0", 176 | "call-by-name": "4.0.1", 177 | "canvas": "6.0.0", 178 | "canvas-action": "9.0.0", 179 | "cartesian": "1.0.6", 180 | "catenable-lists": "7.0.0", 181 | "cbor-stream": "1.3.0", 182 | "chameleon": "1.0.0", 183 | "chameleon-halogen": "1.0.3", 184 | "chameleon-react-basic": "1.1.0", 185 | "chameleon-styled": "2.5.0", 186 | "chameleon-transformers": "1.0.0", 187 | "channel": "1.0.0", 188 | "checked-exceptions": "3.1.1", 189 | "choku": "1.0.2", 190 | "classless": "0.1.1", 191 | "classless-arbitrary": "0.1.1", 192 | "classless-decode-json": "0.1.1", 193 | "classless-encode-json": "0.1.3", 194 | "classnames": "2.0.0", 195 | "codec": "6.1.0", 196 | "codec-argonaut": "10.0.0", 197 | "codec-json": "2.0.0", 198 | "colors": "7.0.1", 199 | "concur-core": "0.5.0", 200 | "concur-react": "0.5.0", 201 | "concurrent-queues": "3.0.0", 202 | "console": "6.1.0", 203 | "const": "6.0.0", 204 | "contravariant": "6.0.0", 205 | "control": "6.0.0", 206 | "convertable-options": "1.0.0", 207 | "coroutines": "7.0.0", 208 | "css": "6.0.0", 209 | "css-class-name-extractor": "0.0.3", 210 | "css-frameworks": "1.0.1", 211 | "csv-stream": "2.3.0", 212 | "data-mvc": "0.0.2", 213 | "datetime": "6.1.0", 214 | "datetime-parsing": "0.2.0", 215 | "debounce": "0.1.0", 216 | "debug": "6.0.2", 217 | "decimals": "7.1.0", 218 | "default-values": "1.0.1", 219 | "deku": "0.9.23", 220 | "deno": "0.0.5", 221 | "dissect": "1.0.0", 222 | "distributive": "6.0.0", 223 | "dom-filereader": "7.0.0", 224 | "dom-indexed": "12.0.0", 225 | "dom-simple": "0.4.0", 226 | "dotenv": "4.0.3", 227 | "droplet": "0.6.0", 228 | "dts": "1.0.0", 229 | "dual-numbers": "1.0.3", 230 | "dynamic-buffer": "3.0.1", 231 | "echarts-simple": "0.0.1", 232 | "effect": "4.0.0", 233 | "either": "6.1.0", 234 | "elmish": "0.13.0", 235 | "elmish-enzyme": "0.1.1", 236 | "elmish-hooks": "0.10.3", 237 | "elmish-html": "0.9.0", 238 | "elmish-testing-library": "0.3.2", 239 | "email-validate": "7.0.0", 240 | "encoding": "0.0.9", 241 | "enums": "6.0.1", 242 | "env-names": "0.4.0", 243 | "error": "2.0.0", 244 | "eta-conversion": "0.3.2", 245 | "exceptions": "6.1.0", 246 | "exists": "6.0.0", 247 | "exitcodes": "4.0.0", 248 | "expect-inferred": "3.0.0", 249 | "ezfetch": "1.1.0", 250 | "fahrtwind": "2.0.0", 251 | "fallback": "0.1.0", 252 | "fast-vect": "1.2.0", 253 | "fetch": "4.1.0", 254 | "fetch-argonaut": "1.0.1", 255 | "fetch-core": "5.1.0", 256 | "fetch-yoga-json": "1.1.0", 257 | "ffi-simple": "0.5.1", 258 | "fft-js": "0.1.0", 259 | "filterable": "5.0.0", 260 | "fix-functor": "0.1.0", 261 | "fixed-points": "7.0.0", 262 | "fixed-precision": "5.0.0", 263 | "flame": "1.3.0", 264 | "float32": "2.0.0", 265 | "fmt": "0.2.1", 266 | "foldable-traversable": "6.0.0", 267 | "foldable-traversable-extra": "0.0.6", 268 | "foreign": "7.0.0", 269 | "foreign-object": "4.1.0", 270 | "foreign-readwrite": "3.4.0", 271 | "forgetmenot": "0.1.0", 272 | "fork": "6.0.0", 273 | "form-urlencoded": "7.0.0", 274 | "formatters": "7.0.0", 275 | "framer-motion": "1.0.1", 276 | "free": "7.1.0", 277 | "freeap": "7.0.0", 278 | "freer-free": "0.0.1", 279 | "freet": "7.0.0", 280 | "functions": "6.0.0", 281 | "functor1": "3.0.0", 282 | "functors": "5.0.0", 283 | "fuzzy": "0.4.0", 284 | "gen": "4.0.0", 285 | "generate-values": "1.0.1", 286 | "generic-router": "0.0.1", 287 | "geojson": "0.0.5", 288 | "geometria": "2.2.0", 289 | "gojs": "0.1.1", 290 | "grain": "3.0.0", 291 | "grain-router": "3.0.0", 292 | "grain-virtualized": "3.0.0", 293 | "graphs": "8.1.0", 294 | "group": "4.1.1", 295 | "halogen": "7.0.0", 296 | "halogen-bootstrap5": "5.3.2", 297 | "halogen-canvas": "1.0.0", 298 | "halogen-css": "10.0.0", 299 | "halogen-echarts-simple": "0.0.4", 300 | "halogen-formless": "4.0.3", 301 | "halogen-helix": "1.0.1", 302 | "halogen-hooks": "0.6.3", 303 | "halogen-hooks-extra": "0.9.0", 304 | "halogen-infinite-scroll": "1.1.0", 305 | "halogen-store": "0.5.4", 306 | "halogen-storybook": "2.0.0", 307 | "halogen-subscriptions": "2.0.0", 308 | "halogen-svg-elems": "8.0.0", 309 | "halogen-typewriter": "1.0.4", 310 | "halogen-vdom": "8.0.0", 311 | "halogen-vdom-string-renderer": "0.5.0", 312 | "halogen-xterm": "2.0.0", 313 | "heckin": "2.0.1", 314 | "heterogeneous": "0.6.0", 315 | "homogeneous": "0.4.0", 316 | "http-methods": "6.0.0", 317 | "httpurple": "4.0.0", 318 | "huffman": "0.4.0", 319 | "humdrum": "0.0.1", 320 | "hyrule": "2.3.8", 321 | "identity": "6.0.0", 322 | "identy": "4.0.1", 323 | "indexed-db": "1.0.0", 324 | "indexed-monad": "3.0.0", 325 | "int64": "3.0.0", 326 | "integers": "6.0.0", 327 | "interpolate": "5.0.2", 328 | "intersection-observer": "1.0.1", 329 | "invariant": "6.0.0", 330 | "jarilo": "1.0.1", 331 | "jelly": "0.10.0", 332 | "jelly-router": "0.3.0", 333 | "jelly-signal": "0.4.0", 334 | "jest": "1.0.0", 335 | "js-abort-controller": "1.0.0", 336 | "js-bigints": "2.2.1", 337 | "js-date": "8.0.0", 338 | "js-fetch": "0.2.1", 339 | "js-fileio": "3.0.0", 340 | "js-intl": "1.1.4", 341 | "js-iterators": "0.1.1", 342 | "js-maps": "0.1.2", 343 | "js-promise": "1.0.0", 344 | "js-promise-aff": "1.0.0", 345 | "js-timers": "6.1.0", 346 | "js-uri": "3.1.0", 347 | "jsdom": "1.0.0", 348 | "json": "1.1.0", 349 | "json-codecs": "5.0.0", 350 | "justifill": "0.5.0", 351 | "jwt": "0.0.9", 352 | "labeled-data": "0.2.0", 353 | "language-cst-parser": "0.14.0", 354 | "lazy": "6.0.0", 355 | "lazy-joe": "1.0.0", 356 | "lcg": "4.0.0", 357 | "leibniz": "5.0.0", 358 | "leveldb": "1.0.1", 359 | "liminal": "1.0.1", 360 | "linalg": "6.0.0", 361 | "lists": "7.0.0", 362 | "literals": "1.0.2", 363 | "logging": "3.0.0", 364 | "logging-journald": "0.4.0", 365 | "lumi-components": "18.0.0", 366 | "machines": "7.0.0", 367 | "maps-eager": "0.5.0", 368 | "marionette": "1.0.0", 369 | "marionette-react-basic-hooks": "0.1.1", 370 | "marked": "0.1.0", 371 | "matrices": "5.0.1", 372 | "matryoshka": "1.0.0", 373 | "maybe": "6.0.0", 374 | "media-types": "6.0.0", 375 | "meowclient": "1.0.0", 376 | "midi": "4.0.0", 377 | "milkis": "9.0.0", 378 | "minibench": "4.0.1", 379 | "mmorph": "7.0.0", 380 | "monad-control": "5.0.0", 381 | "monad-logger": "1.3.1", 382 | "monad-loops": "0.5.0", 383 | "monad-unlift": "1.0.1", 384 | "monoid-extras": "0.0.1", 385 | "monoidal": "0.16.0", 386 | "morello": "0.4.0", 387 | "mote": "3.0.0", 388 | "motsunabe": "2.0.0", 389 | "mvc": "0.0.1", 390 | "mysql": "6.0.1", 391 | "n3": "0.1.0", 392 | "nano-id": "1.1.0", 393 | "nanoid": "0.1.0", 394 | "naturals": "3.0.0", 395 | "nested-functor": "0.2.1", 396 | "newtype": "5.0.0", 397 | "nextjs": "0.1.1", 398 | "nextui": "0.2.0", 399 | "node-buffer": "9.0.0", 400 | "node-child-process": "11.1.0", 401 | "node-event-emitter": "3.0.0", 402 | "node-execa": "5.0.0", 403 | "node-fs": "9.2.0", 404 | "node-glob-basic": "1.3.0", 405 | "node-http": "9.1.0", 406 | "node-http2": "1.1.1", 407 | "node-human-signals": "1.0.0", 408 | "node-net": "5.1.0", 409 | "node-os": "5.1.0", 410 | "node-path": "5.0.0", 411 | "node-process": "11.2.0", 412 | "node-readline": "8.1.1", 413 | "node-sqlite3": "8.0.0", 414 | "node-stream-pipes": "2.1.6", 415 | "node-streams": "9.0.0", 416 | "node-tls": "0.3.1", 417 | "node-url": "7.0.1", 418 | "node-zlib": "0.4.0", 419 | "nonempty": "7.0.0", 420 | "now": "6.0.0", 421 | "npm-package-json": "2.0.0", 422 | "nullable": "6.0.0", 423 | "numberfield": "0.2.2", 424 | "numbers": "9.0.1", 425 | "oak": "3.1.1", 426 | "oak-debug": "1.2.2", 427 | "object-maps": "0.3.0", 428 | "ocarina": "1.5.4", 429 | "oooooooooorrrrrrrmm-lib": "0.0.1", 430 | "open-colors-scales-and-schemes": "1.0.0", 431 | "open-folds": "6.4.0", 432 | "open-foreign-generic": "11.0.3", 433 | "open-memoize": "6.2.0", 434 | "open-mkdirp-aff": "1.2.0", 435 | "open-pairing": "6.2.0", 436 | "open-smolder": "12.0.2", 437 | "options": "7.0.0", 438 | "optparse": "5.0.1", 439 | "ordered-collections": "3.2.0", 440 | "ordered-set": "0.4.0", 441 | "orders": "6.0.0", 442 | "owoify": "1.2.0", 443 | "pairs": "9.0.1", 444 | "parallel": "7.0.0", 445 | "parsing": "10.2.0", 446 | "parsing-dataview": "3.2.4", 447 | "partial": "4.0.0", 448 | "pathy": "9.0.0", 449 | "pha": "0.13.0", 450 | "phaser": "0.7.0", 451 | "phylio": "1.1.2", 452 | "pipes": "8.0.0", 453 | "pirates-charm": "0.0.1", 454 | "pmock": "0.9.0", 455 | "point-free": "1.0.0", 456 | "pointed-list": "0.5.1", 457 | "polymorphic-vectors": "4.0.0", 458 | "posix-types": "6.0.0", 459 | "postgresql": "2.0.20", 460 | "precise": "6.0.0", 461 | "precise-datetime": "7.0.0", 462 | "prelude": "6.0.1", 463 | "prettier-printer": "3.0.0", 464 | "printf": "0.1.0", 465 | "priority-queue": "0.1.2", 466 | "profunctor": "6.0.1", 467 | "profunctor-lenses": "8.0.0", 468 | "protobuf": "4.4.0", 469 | "psa-utils": "8.0.0", 470 | "psci-support": "6.0.0", 471 | "punycode": "1.0.0", 472 | "qualified-do": "2.2.0", 473 | "quantities": "12.2.0", 474 | "quickcheck": "8.0.1", 475 | "quickcheck-combinators": "0.1.3", 476 | "quickcheck-laws": "7.0.0", 477 | "quickcheck-utf8": "0.0.0", 478 | "random": "6.0.0", 479 | "rationals": "6.0.0", 480 | "rdf": "0.1.0", 481 | "react": "11.0.0", 482 | "react-aria": "0.2.0", 483 | "react-basic": "17.0.0", 484 | "react-basic-classic": "3.0.0", 485 | "react-basic-dnd": "10.1.0", 486 | "react-basic-dom": "7.0.0", 487 | "react-basic-dom-beta": "0.1.1", 488 | "react-basic-emotion": "7.1.0", 489 | "react-basic-hooks": "8.2.0", 490 | "react-basic-storybook": "2.0.0", 491 | "react-dom": "8.0.0", 492 | "react-halo": "3.0.0", 493 | "react-icons": "1.1.5", 494 | "react-markdown": "0.1.0", 495 | "react-testing-library": "4.0.1", 496 | "react-virtuoso": "1.0.0", 497 | "reactix": "0.6.1", 498 | "read": "1.0.1", 499 | "recharts": "1.1.0", 500 | "record": "4.0.0", 501 | "record-extra": "5.0.1", 502 | "record-ptional-fields": "0.1.2", 503 | "record-studio": "1.0.4", 504 | "refs": "6.0.0", 505 | "remotedata": "5.0.1", 506 | "repr": "0.5.0", 507 | "resize-observer": "1.0.0", 508 | "resource": "2.0.1", 509 | "resourcet": "1.0.0", 510 | "result": "1.0.3", 511 | "return": "0.2.0", 512 | "ring-modules": "5.0.1", 513 | "rito": "0.3.4", 514 | "roman": "0.4.0", 515 | "rough-notation": "1.0.2", 516 | "routing": "11.0.0", 517 | "routing-duplex": "0.7.0", 518 | "run": "5.0.0", 519 | "safe-coerce": "2.0.0", 520 | "safely": "4.0.1", 521 | "school-of-music": "1.3.0", 522 | "selection-foldable": "0.2.0", 523 | "selective-functors": "1.0.1", 524 | "semirings": "7.0.0", 525 | "signal": "13.0.0", 526 | "simple-emitter": "3.0.1", 527 | "simple-i18n": "2.0.1", 528 | "simple-json": "9.0.0", 529 | "simple-json-generics": "0.2.1", 530 | "simple-ulid": "3.0.0", 531 | "sized-matrices": "1.0.0", 532 | "sized-vectors": "5.0.2", 533 | "slug": "3.1.0", 534 | "small-ffi": "4.0.1", 535 | "soundfonts": "4.1.0", 536 | "sparse-matrices": "2.0.1", 537 | "sparse-polynomials": "3.0.1", 538 | "spec": "8.1.1", 539 | "spec-discovery": "8.4.0", 540 | "spec-mocha": "5.1.1", 541 | "spec-node": "0.0.3", 542 | "spec-quickcheck": "5.0.2", 543 | "spec-reporter-xunit": "0.7.1", 544 | "splitmix": "2.1.0", 545 | "ssrs": "1.0.0", 546 | "st": "6.2.0", 547 | "statistics": "0.3.2", 548 | "strictlypositiveint": "1.0.1", 549 | "string-parsers": "8.0.0", 550 | "strings": "6.0.1", 551 | "strings-extra": "4.0.0", 552 | "stringutils": "0.0.12", 553 | "substitute": "0.2.3", 554 | "supply": "0.2.0", 555 | "svg-parser": "3.0.0", 556 | "systemd-journald": "0.3.0", 557 | "tagged": "4.0.2", 558 | "tailrec": "6.1.0", 559 | "tecton": "0.2.1", 560 | "tecton-halogen": "0.2.0", 561 | "test-unit": "17.0.0", 562 | "thermite": "6.3.1", 563 | "thermite-dom": "0.3.1", 564 | "these": "6.0.0", 565 | "threading": "0.0.3", 566 | "tldr": "0.0.0", 567 | "toestand": "0.9.0", 568 | "transformation-matrix": "1.0.1", 569 | "transformers": "6.1.0", 570 | "tree-rose": "4.0.2", 571 | "ts-bridge": "4.0.0", 572 | "tuples": "7.0.0", 573 | "two-or-more": "1.0.0", 574 | "type-equality": "4.0.1", 575 | "typedenv": "2.0.1", 576 | "typelevel": "6.0.0", 577 | "typelevel-lists": "2.1.0", 578 | "typelevel-peano": "1.0.1", 579 | "typelevel-prelude": "7.0.0", 580 | "typelevel-regex": "0.0.3", 581 | "typelevel-rows": "0.1.0", 582 | "typisch": "0.4.0", 583 | "uint": "7.0.0", 584 | "ulid": "3.0.1", 585 | "uncurried-transformers": "1.1.0", 586 | "undefined": "2.0.0", 587 | "undefined-is-not-a-problem": "1.1.0", 588 | "unfoldable": "6.0.0", 589 | "unicode": "6.0.0", 590 | "unique": "0.6.1", 591 | "unlift": "1.0.1", 592 | "unordered-collections": "3.1.0", 593 | "unsafe-coerce": "6.0.0", 594 | "unsafe-reference": "5.0.0", 595 | "untagged-to-tagged": "0.1.4", 596 | "untagged-union": "1.0.0", 597 | "uri": "9.0.0", 598 | "url-immutable": "1.0.0", 599 | "uuid": "9.0.0", 600 | "uuidv4": "1.0.0", 601 | "validation": "6.0.0", 602 | "variant": "8.0.0", 603 | "variant-encodings": "2.0.0", 604 | "vectorfield": "1.0.1", 605 | "vectors": "2.1.0", 606 | "versions": "7.0.0", 607 | "visx": "0.0.2", 608 | "web-clipboard": "6.0.0", 609 | "web-cssom": "2.0.0", 610 | "web-cssom-view": "0.1.0", 611 | "web-dom": "6.0.0", 612 | "web-dom-parser": "8.0.0", 613 | "web-dom-xpath": "3.0.0", 614 | "web-encoding": "3.0.0", 615 | "web-events": "4.0.0", 616 | "web-fetch": "4.0.1", 617 | "web-file": "4.0.0", 618 | "web-geometry": "0.1.0", 619 | "web-html": "4.1.0", 620 | "web-pointerevents": "2.0.0", 621 | "web-proletarian": "1.0.0", 622 | "web-promise": "3.2.0", 623 | "web-resize-observer": "2.1.0", 624 | "web-router": "1.0.0", 625 | "web-socket": "4.0.0", 626 | "web-storage": "5.0.0", 627 | "web-streams": "4.0.0", 628 | "web-touchevents": "4.0.0", 629 | "web-uievents": "5.0.0", 630 | "web-url": "2.0.0", 631 | "web-workers": "1.1.0", 632 | "web-xhr": "5.0.1", 633 | "webextension-polyfill": "0.1.0", 634 | "webgpu": "0.0.1", 635 | "which": "2.0.0", 636 | "xterm": "1.0.0", 637 | "yoga-fetch": "1.0.1", 638 | "yoga-json": "5.1.0", 639 | "yoga-om": "0.1.0", 640 | "yoga-postgres": "6.0.0", 641 | "yoga-subtlecrypto": "0.1.0", 642 | "yoga-tree": "1.0.0", 643 | "z3": "0.0.2", 644 | "zipperarray": "2.0.0" 645 | } 646 | }, 647 | "extra_packages": {} 648 | }, 649 | "packages": { 650 | "aff": { 651 | "type": "registry", 652 | "version": "8.0.0", 653 | "integrity": "sha256-5MmdI4+0RHBtSBy+YlU3/Cq4R5W2ih3OaRedJIrVHdk=", 654 | "dependencies": [ 655 | "bifunctors", 656 | "control", 657 | "datetime", 658 | "effect", 659 | "either", 660 | "exceptions", 661 | "foldable-traversable", 662 | "functions", 663 | "maybe", 664 | "newtype", 665 | "parallel", 666 | "prelude", 667 | "refs", 668 | "tailrec", 669 | "transformers", 670 | "unsafe-coerce" 671 | ] 672 | }, 673 | "ansi": { 674 | "type": "registry", 675 | "version": "7.0.0", 676 | "integrity": "sha256-ZMB6HD+q9CXvn9fRCmJ8dvuDrOVHcjombL3oNOerVnE=", 677 | "dependencies": [ 678 | "foldable-traversable", 679 | "lists", 680 | "strings" 681 | ] 682 | }, 683 | "arrays": { 684 | "type": "registry", 685 | "version": "7.3.0", 686 | "integrity": "sha256-tmcklBlc/muUtUfr9RapdCPwnlQeB3aSrC4dK85gQlc=", 687 | "dependencies": [ 688 | "bifunctors", 689 | "control", 690 | "foldable-traversable", 691 | "functions", 692 | "maybe", 693 | "nonempty", 694 | "partial", 695 | "prelude", 696 | "safe-coerce", 697 | "st", 698 | "tailrec", 699 | "tuples", 700 | "unfoldable", 701 | "unsafe-coerce" 702 | ] 703 | }, 704 | "avar": { 705 | "type": "registry", 706 | "version": "5.0.0", 707 | "integrity": "sha256-e7hf0x4hEpcygXP0LtvfvAQ49Bbj2aWtZT3gqM///0A=", 708 | "dependencies": [ 709 | "aff", 710 | "effect", 711 | "either", 712 | "exceptions", 713 | "functions", 714 | "maybe" 715 | ] 716 | }, 717 | "bifunctors": { 718 | "type": "registry", 719 | "version": "6.0.0", 720 | "integrity": "sha256-/gZwC9YhNxZNQpnHa5BIYerCGM2jeX9ukZiEvYxm5Nw=", 721 | "dependencies": [ 722 | "const", 723 | "either", 724 | "newtype", 725 | "prelude", 726 | "tuples" 727 | ] 728 | }, 729 | "catenable-lists": { 730 | "type": "registry", 731 | "version": "7.0.0", 732 | "integrity": "sha256-76vYENhwF4BWTBsjeLuErCH2jqVT4M3R1HX+4RwSftA=", 733 | "dependencies": [ 734 | "control", 735 | "foldable-traversable", 736 | "lists", 737 | "maybe", 738 | "prelude", 739 | "tuples", 740 | "unfoldable" 741 | ] 742 | }, 743 | "console": { 744 | "type": "registry", 745 | "version": "6.1.0", 746 | "integrity": "sha256-CxmAzjgyuGDmt9FZW51VhV6rBPwR6o0YeKUzA9rSzcM=", 747 | "dependencies": [ 748 | "effect", 749 | "prelude" 750 | ] 751 | }, 752 | "const": { 753 | "type": "registry", 754 | "version": "6.0.0", 755 | "integrity": "sha256-tNrxDW8D8H4jdHE2HiPzpLy08zkzJMmGHdRqt5BQuTc=", 756 | "dependencies": [ 757 | "invariant", 758 | "newtype", 759 | "prelude" 760 | ] 761 | }, 762 | "contravariant": { 763 | "type": "registry", 764 | "version": "6.0.0", 765 | "integrity": "sha256-TP+ooAp3vvmdjfQsQJSichF5B4BPDHp3wAJoWchip6c=", 766 | "dependencies": [ 767 | "const", 768 | "either", 769 | "newtype", 770 | "prelude", 771 | "tuples" 772 | ] 773 | }, 774 | "control": { 775 | "type": "registry", 776 | "version": "6.0.0", 777 | "integrity": "sha256-sH7Pg9E96JCPF9PIA6oQ8+BjTyO/BH1ZuE/bOcyj4Jk=", 778 | "dependencies": [ 779 | "newtype", 780 | "prelude" 781 | ] 782 | }, 783 | "datetime": { 784 | "type": "registry", 785 | "version": "6.1.0", 786 | "integrity": "sha256-g/5X5BBegQWLpI9IWD+sY6mcaYpzzlW5lz5NBzaMtyI=", 787 | "dependencies": [ 788 | "bifunctors", 789 | "control", 790 | "either", 791 | "enums", 792 | "foldable-traversable", 793 | "functions", 794 | "gen", 795 | "integers", 796 | "lists", 797 | "maybe", 798 | "newtype", 799 | "numbers", 800 | "ordered-collections", 801 | "partial", 802 | "prelude", 803 | "tuples" 804 | ] 805 | }, 806 | "distributive": { 807 | "type": "registry", 808 | "version": "6.0.0", 809 | "integrity": "sha256-HTDdmEnzigMl+02SJB88j+gAXDx9VKsbvR4MJGDPbOQ=", 810 | "dependencies": [ 811 | "identity", 812 | "newtype", 813 | "prelude", 814 | "tuples", 815 | "type-equality" 816 | ] 817 | }, 818 | "effect": { 819 | "type": "registry", 820 | "version": "4.0.0", 821 | "integrity": "sha256-eBtZu+HZcMa5HilvI6kaDyVX3ji8p0W9MGKy2K4T6+M=", 822 | "dependencies": [ 823 | "prelude" 824 | ] 825 | }, 826 | "either": { 827 | "type": "registry", 828 | "version": "6.1.0", 829 | "integrity": "sha256-6hgTPisnMWVwQivOu2PKYcH8uqjEOOqDyaDQVUchTpY=", 830 | "dependencies": [ 831 | "control", 832 | "invariant", 833 | "maybe", 834 | "prelude" 835 | ] 836 | }, 837 | "enums": { 838 | "type": "registry", 839 | "version": "6.0.1", 840 | "integrity": "sha256-HWaD73JFLorc4A6trKIRUeDMdzE+GpkJaEOM1nTNkC8=", 841 | "dependencies": [ 842 | "control", 843 | "either", 844 | "gen", 845 | "maybe", 846 | "newtype", 847 | "nonempty", 848 | "partial", 849 | "prelude", 850 | "tuples", 851 | "unfoldable" 852 | ] 853 | }, 854 | "exceptions": { 855 | "type": "registry", 856 | "version": "6.1.0", 857 | "integrity": "sha256-K0T89IHtF3vBY7eSAO7eDOqSb2J9kZGAcDN5+IKsF8E=", 858 | "dependencies": [ 859 | "effect", 860 | "either", 861 | "maybe", 862 | "prelude" 863 | ] 864 | }, 865 | "exists": { 866 | "type": "registry", 867 | "version": "6.0.0", 868 | "integrity": "sha256-A0JQHpTfo1dNOj9U5/Fd3xndlRSE0g2IQWOGor2yXn8=", 869 | "dependencies": [ 870 | "unsafe-coerce" 871 | ] 872 | }, 873 | "foldable-traversable": { 874 | "type": "registry", 875 | "version": "6.0.0", 876 | "integrity": "sha256-fLeqRYM4jUrZD5H4WqcwUgzU7XfYkzO4zhgtNc3jcWM=", 877 | "dependencies": [ 878 | "bifunctors", 879 | "const", 880 | "control", 881 | "either", 882 | "functors", 883 | "identity", 884 | "maybe", 885 | "newtype", 886 | "orders", 887 | "prelude", 888 | "tuples" 889 | ] 890 | }, 891 | "foreign-object": { 892 | "type": "registry", 893 | "version": "4.1.0", 894 | "integrity": "sha256-q24okj6mT+yGHYQ+ei/pYPj5ih6sTbu7eDv/WU56JVo=", 895 | "dependencies": [ 896 | "arrays", 897 | "foldable-traversable", 898 | "functions", 899 | "gen", 900 | "lists", 901 | "maybe", 902 | "prelude", 903 | "st", 904 | "tailrec", 905 | "tuples", 906 | "typelevel-prelude", 907 | "unfoldable" 908 | ] 909 | }, 910 | "fork": { 911 | "type": "registry", 912 | "version": "6.0.0", 913 | "integrity": "sha256-X7u0SuCvFbLbzuNEKLBNuWjmcroqMqit4xEzpQwAP7E=", 914 | "dependencies": [ 915 | "aff" 916 | ] 917 | }, 918 | "free": { 919 | "type": "registry", 920 | "version": "7.1.0", 921 | "integrity": "sha256-JAumgEsGSzJCNLD8AaFvuX7CpqS5yruCngi6yI7+V5k=", 922 | "dependencies": [ 923 | "catenable-lists", 924 | "control", 925 | "distributive", 926 | "either", 927 | "exists", 928 | "foldable-traversable", 929 | "invariant", 930 | "lazy", 931 | "maybe", 932 | "prelude", 933 | "tailrec", 934 | "transformers", 935 | "tuples", 936 | "unsafe-coerce" 937 | ] 938 | }, 939 | "functions": { 940 | "type": "registry", 941 | "version": "6.0.0", 942 | "integrity": "sha256-adMyJNEnhGde2unHHAP79gPtlNjNqzgLB8arEOn9hLI=", 943 | "dependencies": [ 944 | "prelude" 945 | ] 946 | }, 947 | "functors": { 948 | "type": "registry", 949 | "version": "5.0.0", 950 | "integrity": "sha256-zfPWWYisbD84MqwpJSZFlvM6v86McM68ob8p9s27ywU=", 951 | "dependencies": [ 952 | "bifunctors", 953 | "const", 954 | "contravariant", 955 | "control", 956 | "distributive", 957 | "either", 958 | "invariant", 959 | "maybe", 960 | "newtype", 961 | "prelude", 962 | "profunctor", 963 | "tuples", 964 | "unsafe-coerce" 965 | ] 966 | }, 967 | "gen": { 968 | "type": "registry", 969 | "version": "4.0.0", 970 | "integrity": "sha256-f7yzAXWwr+xnaqEOcvyO3ezKdoes8+WXWdXIHDBCAPI=", 971 | "dependencies": [ 972 | "either", 973 | "foldable-traversable", 974 | "identity", 975 | "maybe", 976 | "newtype", 977 | "nonempty", 978 | "prelude", 979 | "tailrec", 980 | "tuples", 981 | "unfoldable" 982 | ] 983 | }, 984 | "identity": { 985 | "type": "registry", 986 | "version": "6.0.0", 987 | "integrity": "sha256-4wY0XZbAksjY6UAg99WkuKyJlQlWAfTi2ssadH0wVMY=", 988 | "dependencies": [ 989 | "control", 990 | "invariant", 991 | "newtype", 992 | "prelude" 993 | ] 994 | }, 995 | "integers": { 996 | "type": "registry", 997 | "version": "6.0.0", 998 | "integrity": "sha256-sf+sK26R1hzwl3NhXR7WAu9zCDjQnfoXwcyGoseX158=", 999 | "dependencies": [ 1000 | "maybe", 1001 | "numbers", 1002 | "prelude" 1003 | ] 1004 | }, 1005 | "invariant": { 1006 | "type": "registry", 1007 | "version": "6.0.0", 1008 | "integrity": "sha256-RGWWyYrz0Hs1KjPDA+87Kia67ZFBhfJ5lMGOMCEFoLo=", 1009 | "dependencies": [ 1010 | "control", 1011 | "prelude" 1012 | ] 1013 | }, 1014 | "lazy": { 1015 | "type": "registry", 1016 | "version": "6.0.0", 1017 | "integrity": "sha256-lMsfFOnlqfe4KzRRiW8ot5ge6HtcU3Eyh2XkXcP5IgU=", 1018 | "dependencies": [ 1019 | "control", 1020 | "foldable-traversable", 1021 | "invariant", 1022 | "prelude" 1023 | ] 1024 | }, 1025 | "lists": { 1026 | "type": "registry", 1027 | "version": "7.0.0", 1028 | "integrity": "sha256-EKF15qYqucuXP2lT/xPxhqy58f0FFT6KHdIB/yBOayI=", 1029 | "dependencies": [ 1030 | "bifunctors", 1031 | "control", 1032 | "foldable-traversable", 1033 | "lazy", 1034 | "maybe", 1035 | "newtype", 1036 | "nonempty", 1037 | "partial", 1038 | "prelude", 1039 | "tailrec", 1040 | "tuples", 1041 | "unfoldable" 1042 | ] 1043 | }, 1044 | "maybe": { 1045 | "type": "registry", 1046 | "version": "6.0.0", 1047 | "integrity": "sha256-5cCIb0wPwbat2PRkQhUeZO0jcAmf8jCt2qE0wbC3v2Q=", 1048 | "dependencies": [ 1049 | "control", 1050 | "invariant", 1051 | "newtype", 1052 | "prelude" 1053 | ] 1054 | }, 1055 | "mmorph": { 1056 | "type": "registry", 1057 | "version": "7.0.0", 1058 | "integrity": "sha256-urZlZNNqGeQFe5D/ClHlR8QgGBNHTMFPtJ5S5IpflTQ=", 1059 | "dependencies": [ 1060 | "free", 1061 | "functors", 1062 | "transformers" 1063 | ] 1064 | }, 1065 | "newtype": { 1066 | "type": "registry", 1067 | "version": "5.0.0", 1068 | "integrity": "sha256-gdrQu8oGe9eZE6L3wOI8ql/igOg+zEGB5ITh2g+uttw=", 1069 | "dependencies": [ 1070 | "prelude", 1071 | "safe-coerce" 1072 | ] 1073 | }, 1074 | "nonempty": { 1075 | "type": "registry", 1076 | "version": "7.0.0", 1077 | "integrity": "sha256-54ablJZUHGvvlTJzi3oXyPCuvY6zsrWJuH/dMJ/MFLs=", 1078 | "dependencies": [ 1079 | "control", 1080 | "foldable-traversable", 1081 | "maybe", 1082 | "prelude", 1083 | "tuples", 1084 | "unfoldable" 1085 | ] 1086 | }, 1087 | "now": { 1088 | "type": "registry", 1089 | "version": "6.0.0", 1090 | "integrity": "sha256-xZ7x37ZMREfs6GCDw/h+FaKHV/3sPWmtqBZRGTxybQY=", 1091 | "dependencies": [ 1092 | "datetime", 1093 | "effect" 1094 | ] 1095 | }, 1096 | "numbers": { 1097 | "type": "registry", 1098 | "version": "9.0.1", 1099 | "integrity": "sha256-/9M6aeMDBdB4cwYDeJvLFprAHZ49EbtKQLIJsneXLIk=", 1100 | "dependencies": [ 1101 | "functions", 1102 | "maybe" 1103 | ] 1104 | }, 1105 | "ordered-collections": { 1106 | "type": "registry", 1107 | "version": "3.2.0", 1108 | "integrity": "sha256-o9jqsj5rpJmMdoe/zyufWHFjYYFTTsJpgcuCnqCO6PM=", 1109 | "dependencies": [ 1110 | "arrays", 1111 | "foldable-traversable", 1112 | "gen", 1113 | "lists", 1114 | "maybe", 1115 | "partial", 1116 | "prelude", 1117 | "st", 1118 | "tailrec", 1119 | "tuples", 1120 | "unfoldable" 1121 | ] 1122 | }, 1123 | "orders": { 1124 | "type": "registry", 1125 | "version": "6.0.0", 1126 | "integrity": "sha256-nBA0g3/ai0euH8q9pSbGqk53W2q6agm/dECZTHcoink=", 1127 | "dependencies": [ 1128 | "newtype", 1129 | "prelude" 1130 | ] 1131 | }, 1132 | "parallel": { 1133 | "type": "registry", 1134 | "version": "7.0.0", 1135 | "integrity": "sha256-gUC9i4Txnx9K9RcMLsjujbwZz6BB1bnE2MLvw4GIw5o=", 1136 | "dependencies": [ 1137 | "control", 1138 | "effect", 1139 | "either", 1140 | "foldable-traversable", 1141 | "functors", 1142 | "maybe", 1143 | "newtype", 1144 | "prelude", 1145 | "profunctor", 1146 | "refs", 1147 | "transformers" 1148 | ] 1149 | }, 1150 | "partial": { 1151 | "type": "registry", 1152 | "version": "4.0.0", 1153 | "integrity": "sha256-fwXerld6Xw1VkReh8yeQsdtLVrjfGiVuC5bA1Wyo/J4=", 1154 | "dependencies": [] 1155 | }, 1156 | "pipes": { 1157 | "type": "registry", 1158 | "version": "8.0.0", 1159 | "integrity": "sha256-kvfqGM4cPA/wCcBHbp5psouFw5dZGvku2462x7ZBwSY=", 1160 | "dependencies": [ 1161 | "aff", 1162 | "lists", 1163 | "mmorph", 1164 | "prelude", 1165 | "tailrec", 1166 | "transformers", 1167 | "tuples" 1168 | ] 1169 | }, 1170 | "prelude": { 1171 | "type": "registry", 1172 | "version": "6.0.1", 1173 | "integrity": "sha256-o8p6SLYmVPqzXZhQFd2hGAWEwBoXl1swxLG/scpJ0V0=", 1174 | "dependencies": [] 1175 | }, 1176 | "profunctor": { 1177 | "type": "registry", 1178 | "version": "6.0.1", 1179 | "integrity": "sha256-E58hSYdJvF2Qjf9dnWLPlJKh2Z2fLfFLkQoYi16vsFk=", 1180 | "dependencies": [ 1181 | "control", 1182 | "distributive", 1183 | "either", 1184 | "exists", 1185 | "invariant", 1186 | "newtype", 1187 | "prelude", 1188 | "tuples" 1189 | ] 1190 | }, 1191 | "profunctor-lenses": { 1192 | "type": "registry", 1193 | "version": "8.0.0", 1194 | "integrity": "sha256-K7f29rHRHgVSb2Y/PaSKtfYPriP6n87BJNO7EhsZHas=", 1195 | "dependencies": [ 1196 | "arrays", 1197 | "bifunctors", 1198 | "const", 1199 | "control", 1200 | "distributive", 1201 | "either", 1202 | "foldable-traversable", 1203 | "foreign-object", 1204 | "functors", 1205 | "identity", 1206 | "lists", 1207 | "maybe", 1208 | "newtype", 1209 | "ordered-collections", 1210 | "partial", 1211 | "prelude", 1212 | "profunctor", 1213 | "record", 1214 | "transformers", 1215 | "tuples" 1216 | ] 1217 | }, 1218 | "record": { 1219 | "type": "registry", 1220 | "version": "4.0.0", 1221 | "integrity": "sha256-Za5U85bTRJEfGK5Sk4hM41oXy84YQI0I8TL3WUn1Qzg=", 1222 | "dependencies": [ 1223 | "functions", 1224 | "prelude", 1225 | "unsafe-coerce" 1226 | ] 1227 | }, 1228 | "refs": { 1229 | "type": "registry", 1230 | "version": "6.0.0", 1231 | "integrity": "sha256-Vgwne7jIbD3ZMoLNNETLT8Litw6lIYo3MfYNdtYWj9s=", 1232 | "dependencies": [ 1233 | "effect", 1234 | "prelude" 1235 | ] 1236 | }, 1237 | "safe-coerce": { 1238 | "type": "registry", 1239 | "version": "2.0.0", 1240 | "integrity": "sha256-a1ibQkiUcbODbLE/WAq7Ttbbh9ex+x33VCQ7GngKudU=", 1241 | "dependencies": [ 1242 | "unsafe-coerce" 1243 | ] 1244 | }, 1245 | "spec": { 1246 | "type": "registry", 1247 | "version": "8.1.1", 1248 | "integrity": "sha256-EM7UfQIaSgiw13LJ4ZASkfYmmRDKIlec3nYbGKFqGhk=", 1249 | "dependencies": [ 1250 | "aff", 1251 | "ansi", 1252 | "arrays", 1253 | "avar", 1254 | "bifunctors", 1255 | "control", 1256 | "datetime", 1257 | "effect", 1258 | "either", 1259 | "exceptions", 1260 | "foldable-traversable", 1261 | "fork", 1262 | "identity", 1263 | "integers", 1264 | "lists", 1265 | "maybe", 1266 | "newtype", 1267 | "now", 1268 | "ordered-collections", 1269 | "parallel", 1270 | "pipes", 1271 | "prelude", 1272 | "refs", 1273 | "strings", 1274 | "tailrec", 1275 | "transformers", 1276 | "tuples" 1277 | ] 1278 | }, 1279 | "st": { 1280 | "type": "registry", 1281 | "version": "6.2.0", 1282 | "integrity": "sha256-z9X0WsOUlPwNx9GlCC+YccCyz8MejC8Wb0C4+9fiBRY=", 1283 | "dependencies": [ 1284 | "partial", 1285 | "prelude", 1286 | "tailrec", 1287 | "unsafe-coerce" 1288 | ] 1289 | }, 1290 | "strings": { 1291 | "type": "registry", 1292 | "version": "6.0.1", 1293 | "integrity": "sha256-WssD3DbX4OPzxSdjvRMX0yvc9+pS7n5gyPv5I2Trb7k=", 1294 | "dependencies": [ 1295 | "arrays", 1296 | "control", 1297 | "either", 1298 | "enums", 1299 | "foldable-traversable", 1300 | "gen", 1301 | "integers", 1302 | "maybe", 1303 | "newtype", 1304 | "nonempty", 1305 | "partial", 1306 | "prelude", 1307 | "tailrec", 1308 | "tuples", 1309 | "unfoldable", 1310 | "unsafe-coerce" 1311 | ] 1312 | }, 1313 | "tailrec": { 1314 | "type": "registry", 1315 | "version": "6.1.0", 1316 | "integrity": "sha256-Xx19ECVDRrDWpz9D2GxQHHV89vd61dnXxQm0IcYQHGk=", 1317 | "dependencies": [ 1318 | "bifunctors", 1319 | "effect", 1320 | "either", 1321 | "identity", 1322 | "maybe", 1323 | "partial", 1324 | "prelude", 1325 | "refs" 1326 | ] 1327 | }, 1328 | "transformers": { 1329 | "type": "registry", 1330 | "version": "6.1.0", 1331 | "integrity": "sha256-3Bm+Z6tsC/paG888XkywDngJ2JMos+JfOhRlkVfb7gI=", 1332 | "dependencies": [ 1333 | "control", 1334 | "distributive", 1335 | "effect", 1336 | "either", 1337 | "exceptions", 1338 | "foldable-traversable", 1339 | "identity", 1340 | "lazy", 1341 | "maybe", 1342 | "newtype", 1343 | "prelude", 1344 | "st", 1345 | "tailrec", 1346 | "tuples", 1347 | "unfoldable" 1348 | ] 1349 | }, 1350 | "tuples": { 1351 | "type": "registry", 1352 | "version": "7.0.0", 1353 | "integrity": "sha256-1rXgTomes9105BjgXqIw0FL6Fz1lqqUTLWOumhWec1M=", 1354 | "dependencies": [ 1355 | "control", 1356 | "invariant", 1357 | "prelude" 1358 | ] 1359 | }, 1360 | "type-equality": { 1361 | "type": "registry", 1362 | "version": "4.0.1", 1363 | "integrity": "sha256-Hs9D6Y71zFi/b+qu5NSbuadUQXe5iv5iWx0226vOHUw=", 1364 | "dependencies": [] 1365 | }, 1366 | "typelevel-prelude": { 1367 | "type": "registry", 1368 | "version": "7.0.0", 1369 | "integrity": "sha256-uFF2ph+vHcQpfPuPf2a3ukJDFmLhApmkpTMviHIWgJM=", 1370 | "dependencies": [ 1371 | "prelude", 1372 | "type-equality" 1373 | ] 1374 | }, 1375 | "unfoldable": { 1376 | "type": "registry", 1377 | "version": "6.0.0", 1378 | "integrity": "sha256-JtikvJdktRap7vr/K4ITlxUX1QexpnqBq0G/InLr6eg=", 1379 | "dependencies": [ 1380 | "foldable-traversable", 1381 | "maybe", 1382 | "partial", 1383 | "prelude", 1384 | "tuples" 1385 | ] 1386 | }, 1387 | "unsafe-coerce": { 1388 | "type": "registry", 1389 | "version": "6.0.0", 1390 | "integrity": "sha256-IqIYW4Vkevn8sI+6aUwRGvd87tVL36BBeOr0cGAE7t0=", 1391 | "dependencies": [] 1392 | }, 1393 | "unsafe-reference": { 1394 | "type": "registry", 1395 | "version": "5.0.0", 1396 | "integrity": "sha256-zU7BhfJU14nXQRZG9iADsp0mSiKhz07OcKyjRB2YT+Y=", 1397 | "dependencies": [ 1398 | "prelude" 1399 | ] 1400 | } 1401 | } 1402 | } 1403 | -------------------------------------------------------------------------------- /spago.yaml: -------------------------------------------------------------------------------- 1 | package: 2 | name: concur-core 3 | dependencies: 4 | - arrays 5 | - control 6 | - effect 7 | - either 8 | - foldable-traversable 9 | - identity 10 | - maybe 11 | - newtype 12 | - prelude 13 | - profunctor-lenses 14 | - refs 15 | - tailrec 16 | - transformers 17 | - tuples 18 | - unsafe-reference 19 | test: 20 | main: Test.Main 21 | dependencies: 22 | - console 23 | - spec 24 | workspace: 25 | packageSet: 26 | registry: 61.3.1 27 | extraPackages: {} 28 | -------------------------------------------------------------------------------- /src/Concur/Core.purs: -------------------------------------------------------------------------------- 1 | module Concur.Core 2 | ( module Concur.Core.Types 3 | , module Concur.Core 4 | , module Concur.Core.LiftWidget 5 | ) where 6 | 7 | import Concur.Core.LiftWidget (class LiftWidget, liftWidget) 8 | import Concur.Core.Types (Widget(..), mkWidget, runWidget, unWid, Result(..)) 9 | import Data.Monoid (mempty) 10 | import Effect (Effect) 11 | import Prelude (Unit, discard, pure, ($)) 12 | 13 | -- | Construct a widget, by wrapping an existing widget in a view event 14 | mkNodeWidget 15 | :: forall a v 16 | . ((a -> Effect Unit) -> v -> v) 17 | -> Widget v a 18 | -> Widget v a 19 | mkNodeWidget mkView w = mkWidget \cb -> 20 | runWidget w $ case _ of 21 | View v -> cb (View $ mkView (\a -> cb (Completed a)) v) 22 | Completed a -> cb (Completed a) 23 | 24 | -- | Construct a widget with just props 25 | mkLeafWidget 26 | :: forall a v 27 | . ((a -> Effect Unit) -> v) 28 | -> Widget v a 29 | mkLeafWidget mkView = mkWidget \cb -> do 30 | cb $ View $ v cb 31 | pure mempty 32 | where 33 | v cb = mkView (\a -> cb (Completed a)) 34 | 35 | -------------------------------------------------------------------------------- /src/Concur/Core/DOM.purs: -------------------------------------------------------------------------------- 1 | module Concur.Core.DOM where 2 | 3 | import Concur.Core (mkLeafWidget, mkNodeWidget) 4 | import Concur.Core.LiftWidget (class LiftWidget, liftWidget) 5 | import Concur.Core.Types (Widget) 6 | import Control.MultiAlternative (class MultiAlternative, orr) 7 | import Control.ShiftMap (class ShiftMap, shiftMap) 8 | import Data.Function (($), (<<<)) 9 | import Data.Functor (class Functor, map) 10 | import Data.Unit (Unit) 11 | import Effect (Effect) 12 | 13 | viewAdapter 14 | :: forall ps vs res 15 | . (ps -> vs -> res) 16 | -> (ps -> vs -> Array res) 17 | viewAdapter f = \ps vs -> [ f ps vs ] 18 | 19 | -- | Wrap a single widget with a node that can have eventHandlers attached 20 | el 21 | :: forall f p v m a 22 | . ShiftMap (Widget v) m 23 | => Functor f 24 | => Functor p 25 | => (f (p (Effect Unit)) -> v -> v) 26 | -> f (p a) 27 | -> m a 28 | -> m a 29 | el e props = shiftMap (\f w -> mkNodeWidget (\h v -> (e (map (map (h <<< f)) props) v)) w) 30 | 31 | -- | el for array views 32 | elArr 33 | :: forall f p v m a 34 | . ShiftMap (Widget (Array v)) m 35 | => Functor f 36 | => Functor p 37 | => (f (p (Effect Unit)) -> Array v -> v) 38 | -> f (p a) 39 | -> m a 40 | -> m a 41 | elArr e props = shiftMap (\f w -> mkNodeWidget (\h v -> (viewAdapter e (map (map (h <<< f)) props) v)) w) 42 | 43 | -- | Promote a leaf node to a widget 44 | elLeaf 45 | :: forall f p v m a 46 | . LiftWidget v m 47 | => Functor f 48 | => Functor p 49 | => (f (p (Effect Unit)) -> v) 50 | -> f (p a) 51 | -> m a 52 | elLeaf e props = liftWidget $ mkLeafWidget \h -> e (map (map h) props) 53 | 54 | -- | elLeaf for array views 55 | elLeafArr 56 | :: forall f p v m a 57 | . LiftWidget (Array v) m 58 | => Functor f 59 | => Functor p 60 | => (f (p (Effect Unit)) -> v) 61 | -> f (p a) 62 | -> m a 63 | elLeafArr e props = liftWidget $ mkLeafWidget \h -> [ e (map (map h) props) ] 64 | 65 | -- | Wrap some widgets with a node that can have eventHandlers attached 66 | el' 67 | :: forall f p v m a 68 | . ShiftMap (Widget v) m 69 | => MultiAlternative m 70 | => Functor f 71 | => Functor p 72 | => (f (p (Effect Unit)) -> v -> v) 73 | -> f (p a) 74 | -> Array (m a) 75 | -> m a 76 | el' e props = el e props <<< orr 77 | 78 | -- | el' for array views 79 | elArr' 80 | :: forall f p v m a 81 | . ShiftMap (Widget (Array v)) m 82 | => MultiAlternative m 83 | => Functor f 84 | => Functor p 85 | => (f (p (Effect Unit)) -> Array v -> v) 86 | -> f (p a) 87 | -> Array (m a) 88 | -> m a 89 | elArr' e props = el (viewAdapter e) props <<< orr 90 | 91 | -------------------------------------------------------------------------------- /src/Concur/Core/LiftWidget.purs: -------------------------------------------------------------------------------- 1 | module Concur.Core.LiftWidget where 2 | 3 | import Concur.Core.Types (Widget) 4 | import Control.Monad (class Monad) 5 | import Control.Monad.Trans.Class (class MonadTrans, lift) 6 | import Data.Function (identity, (<<<)) 7 | 8 | class LiftWidget v m where 9 | liftWidget :: forall a. Widget v a -> m a 10 | 11 | instance LiftWidget v (Widget v) where 12 | liftWidget = identity 13 | else instance (Monad m, MonadTrans t, LiftWidget v m) => LiftWidget v (t m) where 14 | liftWidget = lift <<< liftWidget 15 | 16 | -------------------------------------------------------------------------------- /src/Concur/Core/Patterns.purs: -------------------------------------------------------------------------------- 1 | module Concur.Core.Patterns where 2 | 3 | import Concur.Core (Result(..), Widget, mkWidget) 4 | import Control.Alt (class Alt, (<|>)) 5 | import Control.Applicative (pure) 6 | import Control.Bind (bind, discard, (>>=)) 7 | import Control.Monad (class Monad) 8 | import Control.Plus (class Plus) 9 | import Data.Array as Array 10 | import Data.Either (Either(..), either) 11 | import Data.Function (flip, ($), (<<<), (>>>)) 12 | import Data.Functor ((<$>)) 13 | import Data.Lens (Lens') 14 | import Data.Lens as L 15 | import Data.Monoid (class Monoid) 16 | import Data.Newtype (class Newtype, un) 17 | import Data.Semigroup ((<>)) 18 | import Data.Traversable (traverse_) 19 | import Data.Unit (Unit, unit) 20 | import Effect (Effect) 21 | import Effect.Class (class MonadEffect, liftEffect) 22 | import Effect.Ref as Ref 23 | import Unsafe.Reference (unsafeRefEq) 24 | 25 | -- | A very useful combinator for widgets with localised state 26 | loopState :: forall m a s. Monad m => s -> (s -> m (Either s a)) -> m a 27 | loopState s f = f s >>= case _ of 28 | Left s' -> loopState s' f 29 | Right a -> pure a 30 | 31 | -- | Repeat a computation until the value satisfies a predicate 32 | retryUntil :: forall m a. Monad m => (a -> Boolean) -> m a -> m a 33 | retryUntil p w = w >>= \a -> if p a then pure a else retryUntil p w 34 | 35 | -- | Repeat a computation until the value satisfies a predicate, looping in the previous value 36 | retryUntilLoop :: forall m a. Monad m => (a -> Boolean) -> (a -> m a) -> a -> m a 37 | retryUntilLoop p w a = w a >>= \a' -> if p a' then pure a' else retryUntilLoop p w a' 38 | 39 | -- | The Elm Architecture 40 | tea 41 | :: forall a s m x 42 | . Monad m 43 | => s 44 | -> (s -> m a) 45 | -> (a -> s -> s) 46 | -> m x 47 | tea s render update = go s 48 | where 49 | go st = render st >>= (flip update st >>> go) 50 | 51 | type RemoteInterface v a = 52 | { yield :: Widget v a 53 | , render :: Widget v Unit 54 | } 55 | 56 | -- | Separate the UI from the widget result 57 | remoteWidget 58 | :: forall m v a 59 | . Monoid v 60 | => MonadEffect m 61 | => Widget v a 62 | -> m (RemoteInterface v a) 63 | remoteWidget axn = do 64 | remoteCb <- liftEffect $ Ref.new [] 65 | pure { yield: yield remoteCb, render: render remoteCb } 66 | where 67 | yield remoteCb = mkWidget \cb -> do 68 | Ref.modify_ (_ <> [ cb ]) remoteCb 69 | pure do 70 | Ref.modify_ (Array.deleteBy unsafeRefEq cb) remoteCb 71 | render remoteCb = do 72 | val <- axn 73 | liftEffect do 74 | Ref.read remoteCb >>= traverse_ \cb -> cb (Completed val) 75 | 76 | -- | Internalise state 77 | -- The resulting widget can be rescheduled multiple 78 | -- times and will retain its state internally 79 | internalise 80 | :: forall m v a b 81 | . Monoid v 82 | => MonadEffect m 83 | => (a -> Widget v a) 84 | -> a 85 | -> m (Widget v b) 86 | internalise axn val = do 87 | ref <- liftEffect $ Ref.new val 88 | pure (render ref) 89 | where 90 | render ref = liftEffect (Ref.read ref) >>= go 91 | where 92 | go v = do 93 | v' <- axn v 94 | liftEffect do Ref.write v' ref 95 | go v' 96 | 97 | -- WORKING WITH LOCAL ENVIRONMENTS 98 | 99 | -- | A wire can send values up into a local environment 100 | newtype Wire m a = Wire 101 | { value :: Effect a 102 | , send :: a -> Effect Unit 103 | , receive :: m a 104 | } 105 | 106 | derive instance newtypeWire :: Newtype (Wire m a) _ 107 | 108 | -- | Map a Lens over a Wire 109 | mapWire :: forall m s a. Alt m => MonadEffect m => Plus m => Lens' s a -> Wire m s -> Wire m a 110 | mapWire lens wire = 111 | let 112 | wirerec = un Wire wire 113 | in 114 | Wire 115 | { value: L.view lens <$> wirerec.value 116 | , send: \a -> wirerec.value >>= (wirerec.send <<< L.set lens a) 117 | , receive: L.view lens <$> wirerec.receive 118 | } 119 | 120 | -- | Setup a local environment with a wire 121 | local :: forall v r a. Monoid v => a -> (Wire (Widget v) a -> Widget v r) -> Widget v r 122 | local ainit f = do 123 | currentVal <- liftEffect $ Ref.new ainit 124 | remoteCb <- liftEffect $ Ref.new $ pure $ case _ of 125 | Completed a -> Ref.write a currentVal 126 | _ -> pure unit 127 | let 128 | wire = Wire 129 | { value: Ref.read currentVal 130 | , send: \a -> do 131 | Ref.read remoteCb >>= traverse_ \cb -> cb (Completed a) 132 | , receive: mkWidget \cb -> do 133 | Ref.modify_ (_ <> [ cb ]) remoteCb 134 | pure do 135 | Ref.modify_ (Array.deleteBy unsafeRefEq cb) remoteCb 136 | } 137 | f wire 138 | 139 | send :: forall m a. MonadEffect m => Plus m => Wire m a -> a -> m Unit 140 | send w = liftEffect <<< (un Wire w).send 141 | 142 | receive :: forall v a. Wire (Widget v) a -> Widget v a 143 | receive w = (un Wire w).receive 144 | 145 | with :: forall v r a. Monoid v => Wire (Widget v) a -> (a -> Widget v r) -> Widget v r 146 | with wire f = do 147 | val <- liftEffect $ (un Wire wire).value 148 | go val 149 | where 150 | go a = do 151 | res <- (Left <$> f a) <|> (Right <$> receive wire) 152 | either pure go res 153 | 154 | -------------------------------------------------------------------------------- /src/Concur/Core/Types.purs: -------------------------------------------------------------------------------- 1 | module Concur.Core.Types where 2 | 3 | import Control.Alternative (class Alternative) 4 | import Control.Applicative (class Applicative, pure, (*>)) 5 | import Control.Apply (class Apply) 6 | import Control.Bind (class Bind, bind, discard, (>>=)) 7 | import Control.Monad (class Monad, ap, join) 8 | import Control.Monad.Rec.Class (class MonadRec, Step(..), tailRecM) 9 | import Control.MultiAlternative (class MultiAlternative, orr) 10 | import Control.Plus (class Alt, class Plus, empty) 11 | import Control.ShiftMap (class ShiftMap) 12 | import Data.Array as A 13 | import Data.Either (Either(..)) 14 | import Data.Foldable (fold) 15 | import Data.Function (identity, ($), (<<<)) 16 | import Data.Functor (class Functor, void, ($>), map) 17 | import Data.Maybe (Maybe(..)) 18 | import Data.Monoid (class Monoid, mempty) 19 | import Data.Newtype (class Newtype) 20 | import Data.Semigroup (class Semigroup, append) 21 | import Data.TraversableWithIndex (forWithIndex) 22 | import Data.Unit (Unit, unit) 23 | import Effect (Effect) 24 | import Effect.Class (class MonadEffect) 25 | import Effect.Ref as Ref 26 | 27 | newtype Callback a = Callback (Callback' a) 28 | 29 | derive instance Newtype (Callback a) _ 30 | 31 | type Callback' a = (a -> Effect Unit) -> Effect Canceler 32 | type Canceler = Effect Unit 33 | 34 | data Result v a = View v | Completed a 35 | 36 | result :: forall v a r. (v -> r) -> (a -> r) -> Result v a -> r 37 | result f g = case _ of 38 | View v -> f v 39 | Completed a -> g a 40 | 41 | instance Functor (Result v) where 42 | map _ (View v) = View v 43 | map f (Completed a) = Completed (f a) 44 | 45 | mapViewResult :: forall u v a. (u -> v) -> Result u a -> Result v a 46 | mapViewResult f = case _ of 47 | View u -> View (f u) 48 | Completed a -> Completed a 49 | 50 | mkCallback :: forall a. Callback' a -> Callback a 51 | mkCallback = Callback 52 | 53 | runCallback :: forall a. Callback a -> Callback' a 54 | runCallback (Callback f) = f 55 | 56 | instance Functor Callback where 57 | map f c = mkCallback \cb -> runCallback c (cb <<< f) 58 | 59 | -- | A callback that will never be resolved 60 | never :: forall a. Callback a 61 | never = mkCallback mempty 62 | 63 | -- NOTE: We currently have no monadic instance for callbacks 64 | -- Remember: The monadic instance *must* agree with the applicative instance 65 | 66 | instance ShiftMap (Widget v) (Widget v) where 67 | shiftMap f = f identity 68 | 69 | -- A Widget is basically a callback that returns a view or a return value 70 | newtype Widget v a = Widget (Callback (Result v a)) 71 | 72 | derive instance Functor (Widget v) 73 | 74 | derive instance Newtype (Widget v a) _ 75 | 76 | unWid :: forall v a. Widget v a -> Callback (Result v a) 77 | unWid (Widget w) = w 78 | 79 | runWidget :: forall v a. Widget v a -> Callback' (Result v a) 80 | runWidget (Widget (Callback e)) = e 81 | 82 | mkWidget :: forall v a. Callback' (Result v a) -> Widget v a 83 | mkWidget e = Widget (Callback e) 84 | 85 | mapView :: forall u v a. (u -> v) -> Widget u a -> Widget v a 86 | mapView f (Widget w) = Widget (map (mapViewResult f) w) 87 | 88 | instance Apply (Widget v) where 89 | apply = ap 90 | 91 | instance Monad (Widget v) 92 | 93 | instance Applicative (Widget v) where 94 | pure a = mkWidget \cb -> cb (Completed a) $> pure mempty 95 | 96 | instance MonadRec (Widget v) where 97 | tailRecM k a = k a >>= case _ of 98 | Loop x -> tailRecM k x 99 | Done y -> pure y 100 | 101 | instance Bind (Widget v) where 102 | bind m f = mkWidget \cb -> do 103 | -- CancelerRef starts out as a canceler for A, then becomes canceler for B 104 | cancelerRef <- Ref.new mempty 105 | let runCancelers = join (Ref.read cancelerRef) 106 | cancelerA <- runWidget m \res -> do 107 | case res of 108 | View v -> cb (View v) 109 | Completed a -> do 110 | runCancelers 111 | cancelerB <- runWidget (f a) cb 112 | Ref.write cancelerB cancelerRef 113 | Ref.write cancelerA cancelerRef 114 | 115 | pure runCancelers 116 | 117 | display :: forall a v. v -> Widget v a 118 | display v = mkWidget \cb -> do 119 | cb (View v) 120 | pure mempty 121 | 122 | -- Ignore all callbacks on a widget 123 | silence :: forall a v. Widget v a -> Widget v a 124 | silence w = mkWidget \_cb -> do 125 | runWidget w \_res -> void $ pure never 126 | 127 | -- Util 128 | flipEither :: forall a b. Either a b -> Either b a 129 | flipEither (Left a) = Right a 130 | flipEither (Right b) = Left b 131 | 132 | data InitialisingRenderState 133 | = Initialising 134 | | Aborted 135 | | Initialised 136 | 137 | initialised :: InitialisingRenderState -> InitialisingRenderState 138 | initialised = case _ of 139 | Initialising -> Initialised 140 | a -> a 141 | 142 | instance Monoid v => MultiAlternative (Widget v) where 143 | orr :: forall a. Array (Widget v a) -> Widget v a 144 | orr widgets = mkWidget \cb -> do 145 | viewsRef <- Ref.new (A.replicate (A.length widgets) mempty) 146 | cancelerRef <- Ref.new mempty 147 | renderStateRef <- Ref.new Initialising 148 | let runCancelers = join (Ref.read cancelerRef) 149 | _ <- forWithIndex widgets \i w -> do 150 | c <- runWidget w \res -> case res of 151 | View v -> do 152 | views <- Ref.read viewsRef 153 | case A.updateAt i v views of 154 | Nothing -> pure unit 155 | Just views' -> do 156 | Ref.write views' viewsRef 157 | renderState <- Ref.read renderStateRef 158 | case renderState of 159 | Initialised -> cb (View (fold views')) 160 | _ -> pure unit 161 | Completed a -> do 162 | Ref.write Aborted renderStateRef 163 | runCancelers 164 | cb (Completed a) 165 | Ref.modify (_ *> c) cancelerRef 166 | Ref.modify_ initialised renderStateRef 167 | views <- Ref.read viewsRef 168 | cb (View (fold views)) 169 | pure runCancelers 170 | 171 | instance (Monoid v) => Semigroup (Widget v a) where 172 | append w1 w2 = orr [ w1, w2 ] 173 | 174 | instance (Monoid v) => Monoid (Widget v a) where 175 | mempty = empty 176 | 177 | instance (Monoid v) => Alt (Widget v) where 178 | alt = append 179 | 180 | instance (Monoid v) => Plus (Widget v) where 181 | empty = display mempty 182 | 183 | instance (Monoid v) => Alternative (Widget v) 184 | 185 | instance (Monoid v) => MonadEffect (Widget v) where 186 | liftEffect eff = mkWidget \cb -> do 187 | a <- eff 188 | cb (Completed a) 189 | pure mempty 190 | -------------------------------------------------------------------------------- /src/Control/MonadFix.js: -------------------------------------------------------------------------------- 1 | /* global exports, require */ 2 | "use strict"; 3 | 4 | ////////////////////////////////////////////////////////////////// 5 | // ATTRIBUTION 6 | // monad-fix package is not on pursuit, so copied this file from - 7 | // https://github.com/zrho/purescript-monad-fix/ 8 | ////////////////////////////////////////////////////////////////// 9 | 10 | // module Control.MonadFix 11 | 12 | var message = "Control.MonadFix: Premature access to result of fixpoint computation." 13 | 14 | // fixEffect :: forall eff a. ((Unit -> a) -> Eff eff a) -> Eff eff a 15 | export const fixEffect = function(f) { 16 | return function() { 17 | var result = null; 18 | var ready = false; 19 | 20 | result = f(function(u) { 21 | if (!ready) throw new Error(message); 22 | return result; 23 | })(); 24 | 25 | ready = true; 26 | return result; 27 | } 28 | } 29 | 30 | // fixPure :: forall a. ((Unit -> a) -> a) -> a 31 | export const fixPure = function(f) { 32 | return exports.fixEffect(function(a) { return function () { return f(a); }})(); 33 | } 34 | -------------------------------------------------------------------------------- /src/Control/MonadFix.purs: -------------------------------------------------------------------------------- 1 | module Control.MonadFix where 2 | 3 | ------------------------------------------------------------------ 4 | -- ATTRIBUTION 5 | -- monad-fix package is not on pursuit, so copied this file from - 6 | -- https://github.com/zrho/purescript-monad-fix/ 7 | ------------------------------------------------------------------ 8 | 9 | import Prelude 10 | 11 | import Control.Monad.RWS.Trans (RWST(..), RWSResult(..), runRWST) 12 | import Control.Monad.Reader.Trans (ReaderT(..), runReaderT) 13 | import Control.Monad.State.Trans (StateT(..), runStateT) 14 | import Control.Monad.Writer.Trans (WriterT(..), runWriterT) 15 | import Data.Identity (Identity(..)) 16 | import Data.Newtype (unwrap) 17 | import Data.Tuple (fst) 18 | import Effect (Effect) 19 | 20 | foreign import fixEffect :: forall a. ((Unit -> a) -> Effect a) -> Effect a 21 | foreign import fixPure :: forall a. ((Unit -> a) -> a) -> a 22 | 23 | -- | Type class for monads that support fixpoints. 24 | -- | 25 | -- | `mfix f` runs `f` once with the eventual result of `f` as input. Make sure 26 | -- | not to apply the supplied function until the computation returned; else 27 | -- | a dynamic error will be thrown. 28 | class (Monad m) <= MonadFix m where 29 | mfix :: forall a. ((Unit -> a) -> m a) -> m a 30 | 31 | instance monadFixRWST :: (Monoid w, MonadFix m) => MonadFix (RWST r w s m) where 32 | mfix f = RWST \r s -> mfix \t -> runRWST (f \u -> case t u of RWSResult _ a _ -> a) r s 33 | 34 | instance monadFixIdentity :: MonadFix Identity where 35 | mfix = Identity <<< fixPure <<< (unwrap <<< _) 36 | 37 | instance monadFixEff :: MonadFix Effect where 38 | mfix = fixEffect 39 | 40 | instance monadFixFunction :: MonadFix (Function r) where 41 | mfix f r = fixPure (flip f r) 42 | 43 | instance monadFixReaderT :: (MonadFix m) => MonadFix (ReaderT r m) where 44 | mfix f = ReaderT \r -> mfix (flip runReaderT r <<< f) 45 | 46 | instance monadFixStateT :: (MonadFix m) => MonadFix (StateT s m) where 47 | mfix f = StateT \s -> mfix (flip runStateT s <<< f <<< (fst <<< _)) 48 | 49 | instance monadFixWriterT :: (MonadFix m, Monoid w) => MonadFix (WriterT w m) where 50 | mfix f = WriterT $ mfix (runWriterT <<< f <<< (fst <<< _)) 51 | -------------------------------------------------------------------------------- /src/Control/MultiAlternative.purs: -------------------------------------------------------------------------------- 1 | module Control.MultiAlternative where 2 | 3 | import Prelude 4 | 5 | import Control.Monad.Except.Trans (ExceptT) 6 | import Control.Monad.RWS.Trans (RWST(..)) 7 | import Control.Monad.Reader.Trans (ReaderT(..)) 8 | import Control.Monad.State.Trans (StateT(..)) 9 | import Control.Monad.Writer.Trans (WriterT(..)) 10 | import Control.Plus (class Plus, empty, alt) 11 | import Data.Foldable (foldl) 12 | import Data.Newtype (unwrap) 13 | 14 | class Plus m <= MultiAlternative m where 15 | orr :: forall a. Array (m a) -> m a 16 | 17 | -- Use this if there isn't a more efficient implementation 18 | defaultOrr 19 | :: forall a m 20 | . Plus m 21 | => Array (m a) 22 | -> m a 23 | defaultOrr xs = foldl alt empty xs 24 | 25 | -- TODO: Define a fallback instance for all monad transformers 26 | -- instance multiAlternativeMonadTrans :: (Plus (t m), MonadTrans t) => MultiAlternative (t m) where 27 | -- orr = defaultOrr 28 | 29 | -- Instances for common transformers 30 | instance exceptMultiAlternative :: 31 | ( Monoid e 32 | , MultiAlternative m 33 | , Monad m 34 | ) => 35 | MultiAlternative (ExceptT e m) where 36 | -- `Alt` instance for ExceptT executes actions one at a time (as it should), 37 | -- Hence there is no way (or need) to use the efficient `orr` from the underlying monad 38 | -- So we can use the default implementation 39 | orr = defaultOrr 40 | 41 | instance rwsMultiAlternative :: 42 | ( MultiAlternative m 43 | ) => 44 | MultiAlternative (RWST r w s m) where 45 | orr rs = RWST \r s -> orr (map (\m -> unwrap m r s) rs) 46 | 47 | instance readerMultiAlternative :: 48 | ( MultiAlternative m 49 | ) => 50 | MultiAlternative (ReaderT r m) where 51 | orr rs = ReaderT \r -> orr (map (\m -> unwrap m r) rs) 52 | 53 | instance stateMultiAlternative :: 54 | ( MultiAlternative m 55 | , Monad m 56 | ) => 57 | MultiAlternative (StateT s m) where 58 | orr rs = StateT \s -> orr (map (\m -> unwrap m s) rs) 59 | 60 | instance writerMultiAlternative :: 61 | ( MultiAlternative m 62 | ) => 63 | MultiAlternative (WriterT s m) where 64 | orr rs = WriterT $ orr $ map unwrap rs 65 | -------------------------------------------------------------------------------- /src/Control/ShiftMap.purs: -------------------------------------------------------------------------------- 1 | module Control.ShiftMap where 2 | 3 | import Prelude 4 | 5 | import Control.Monad.Except.Trans (ExceptT(..)) 6 | import Control.Monad.RWS.Trans (RWSResult(..), RWST(..)) 7 | import Control.Monad.Reader.Trans (ReaderT(..)) 8 | import Control.Monad.State.Trans (StateT(..)) 9 | import Control.Monad.Writer.Trans (WriterT(..)) 10 | import Data.Either (Either(..)) 11 | import Data.Tuple (Tuple(..)) 12 | 13 | -- | Avoiding monad-control for as long as possible 14 | -- | (convert functions on widgets to functions on transformer stacks 15 | -- | wrapping widgets). 16 | class ShiftMap s t where 17 | shiftMap :: forall a. (forall b. (a -> b) -> s b -> s b) -> t a -> t a 18 | 19 | -- Instances for common transformers 20 | -- It's not possible to use the `map*` functions anymore 21 | 22 | instance ShiftMap m (ExceptT e m) where 23 | shiftMap f (ExceptT m) = ExceptT do f Right m 24 | 25 | instance Monoid w => ShiftMap m (RWST r w s m) where 26 | shiftMap f (RWST g) = RWST \r s -> f (\a -> RWSResult s a mempty) (g r s) 27 | 28 | instance ShiftMap m (ReaderT r m) where 29 | shiftMap f (ReaderT m) = ReaderT \r -> f identity (m r) 30 | 31 | instance Monad m => ShiftMap m (StateT s m) where 32 | shiftMap f (StateT g) = StateT \s -> f (\a -> Tuple a s) (g s) 33 | 34 | instance Monoid w => ShiftMap m (WriterT w m) where 35 | shiftMap f (WriterT m) = WriterT do f (\a -> Tuple a mempty) m 36 | 37 | -------------------------------------------------------------------------------- /test/Test/Main.purs: -------------------------------------------------------------------------------- 1 | module Test.Main where 2 | 3 | import Prelude 4 | 5 | import Effect (Effect) 6 | import Effect.Console (log) 7 | 8 | main :: Effect Unit 9 | main = log "You should add some tests" 10 | --------------------------------------------------------------------------------