2022-12-07 00:04:59 +0100 | waleee | (~waleee@h-176-10-137-138.NA.cust.bahnhof.se) (Ping timeout: 264 seconds) |
2022-12-07 00:05:00 +0100 | christiansen | (~christian@83-95-137-75-dynamic.dk.customer.tdc.net) (Ping timeout: 256 seconds) |
2022-12-07 00:07:41 +0100 | crazazy` | (~user@130.89.173.127) |
2022-12-07 00:09:39 +0100 | crazazy | (~user@mobiela8a1593778d7.roaming.utwente.nl) (Ping timeout: 260 seconds) |
2022-12-07 00:09:45 +0100 | crazazy` | (~user@130.89.173.127) (Remote host closed the connection) |
2022-12-07 00:17:38 +0100 | <iqubic> | tomsmeding: What ae you trying to do? |
2022-12-07 00:18:53 +0100 | beteigeuze | (~Thunderbi@bl14-81-220.dsl.telepac.pt) |
2022-12-07 00:19:35 +0100 | Tuplanolla | (~Tuplanoll@91-159-68-152.elisa-laajakaista.fi) (Quit: Leaving.) |
2022-12-07 00:21:02 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 268 seconds) |
2022-12-07 00:25:31 +0100 | gurkenglas | (~gurkengla@p548ac72e.dip0.t-ipconnect.de) |
2022-12-07 00:26:08 +0100 | <iqubic> | s/ae/are/ |
2022-12-07 00:28:06 +0100 | waleee | (~waleee@h-176-10-137-138.NA.cust.bahnhof.se) |
2022-12-07 00:31:01 +0100 | king_gs | (~Thunderbi@187.201.204.122) |
2022-12-07 00:32:24 +0100 | raehik | (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net) |
2022-12-07 00:32:32 +0100 | <dsal> | ær |
2022-12-07 00:32:32 +0100 | masterbuilder | (~master@user/masterbuilder) |
2022-12-07 00:33:01 +0100 | kenaryn | (~aurele@cre71-h03-89-88-44-27.dsl.sta.abo.bbox.fr) (Quit: leaving) |
2022-12-07 00:34:26 +0100 | stiell | (~stiell@gateway/tor-sasl/stiell) (Remote host closed the connection) |
2022-12-07 00:35:50 +0100 | king_gs | (~Thunderbi@187.201.204.122) (Ping timeout: 268 seconds) |
2022-12-07 00:36:39 +0100 | stiell | (~stiell@gateway/tor-sasl/stiell) |
2022-12-07 00:45:25 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) |
2022-12-07 00:45:40 +0100 | hippoid | (~idris@user/hippoid) (Quit: WeeChat 3.5) |
2022-12-07 00:46:07 +0100 | mestre | (~mestre@191.177.185.178) (Quit: Lost terminal) |
2022-12-07 00:46:30 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) |
2022-12-07 00:46:43 +0100 | hippoid | (~idris@user/hippoid) |
2022-12-07 00:49:33 +0100 | aliosablack | (~chomwitt@2a02:587:7a0c:6a00:1ac0:4dff:fedb:a3f1) (Ping timeout: 260 seconds) |
2022-12-07 00:49:36 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection) |
2022-12-07 00:49:46 +0100 | acidjnk_new | (~acidjnk@p200300d6e7137a665d3a2af2e35b2922.dip0.t-ipconnect.de) (Ping timeout: 256 seconds) |
2022-12-07 00:50:44 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) |
2022-12-07 00:51:25 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 260 seconds) |
2022-12-07 00:59:33 +0100 | opticblast | (~Thunderbi@secure-165.caltech.edu) |
2022-12-07 01:12:11 +0100 | opticblast | (~Thunderbi@secure-165.caltech.edu) (Ping timeout: 264 seconds) |
2022-12-07 01:13:30 +0100 | king_gs | (~Thunderbi@187.201.204.122) |
2022-12-07 01:17:54 +0100 | king_gs | (~Thunderbi@187.201.204.122) (Ping timeout: 260 seconds) |
2022-12-07 01:21:07 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) |
2022-12-07 01:24:37 +0100 | king_gs | (~Thunderbi@187.201.204.122) |
2022-12-07 01:28:55 +0100 | king_gs | (~Thunderbi@187.201.204.122) (Ping timeout: 252 seconds) |
2022-12-07 01:35:39 +0100 | bjourne2 | (~bjorn@94.191.136.201.mobile.tre.se) (Read error: Connection reset by peer) |
2022-12-07 01:41:22 +0100 | Erutuon | (~Erutuon@user/erutuon) |
2022-12-07 01:42:56 +0100 | king_gs | (~Thunderbi@187.201.204.122) |
2022-12-07 01:47:34 +0100 | king_gs | (~Thunderbi@187.201.204.122) (Ping timeout: 256 seconds) |
2022-12-07 01:50:04 +0100 | use-value | (~Thunderbi@2a00:23c6:8a03:2f01:2d36:9da8:a662:60e2) (Remote host closed the connection) |
2022-12-07 01:50:22 +0100 | use-value | (~Thunderbi@2a00:23c6:8a03:2f01:2d36:9da8:a662:60e2) |
2022-12-07 01:51:32 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 256 seconds) |
2022-12-07 02:02:10 +0100 | Kaiepi | (~Kaiepi@108.175.84.104) (Ping timeout: 268 seconds) |
2022-12-07 02:06:08 +0100 | <Axman6> | Anyone else ever wanted pattern predicates? like, partitrion (\is Head{}; Body{}; Div{class = ""}) Writing (\case Head{} -> True; Body{} -> True; Div{class = ""} -> True; _ False) is so tedious |
2022-12-07 02:06:15 +0100 | <Axman6> | partition* |
2022-12-07 02:07:58 +0100 | <dsal> | lens probably has something for that. |
2022-12-07 02:08:31 +0100 | use-value1 | (~Thunderbi@2a00:23c6:8a03:2f01:69a2:269b:4e3d:1c6) |
2022-12-07 02:08:59 +0100 | <Axman6> | yeah you can do something like has (_Head <> _Body <> _Div) I think - not sure how you'd do the field check too, but it's also not relevant fo what I'm doing |
2022-12-07 02:10:17 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:111a:339b:4372:c307) |
2022-12-07 02:10:17 +0100 | albet70 | (~xxx@2400:8902::f03c:92ff:fe60:98d8) (Remote host closed the connection) |
2022-12-07 02:10:23 +0100 | use-value | (~Thunderbi@2a00:23c6:8a03:2f01:2d36:9da8:a662:60e2) (Ping timeout: 264 seconds) |
2022-12-07 02:10:23 +0100 | use-value1 | use-value |
2022-12-07 02:14:42 +0100 | xff0x | (~xff0x@2405:6580:b080:900:f990:42a1:d746:59a8) (Ping timeout: 252 seconds) |
2022-12-07 02:14:50 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:111a:339b:4372:c307) (Ping timeout: 260 seconds) |
2022-12-07 02:14:56 +0100 | king_gs | (~Thunderbi@187.201.204.122) |
2022-12-07 02:15:35 +0100 | king_gs | (~Thunderbi@187.201.204.122) (Client Quit) |
2022-12-07 02:15:53 +0100 | king_gs | (~Thunderbi@187.201.204.122) |
2022-12-07 02:16:24 +0100 | albet70 | (~xxx@2400:8902::f03c:92ff:fe60:98d8) |
2022-12-07 02:17:25 +0100 | AWizzArd | (~code@gehrels.uberspace.de) (Ping timeout: 256 seconds) |
2022-12-07 02:17:31 +0100 | noctux | (~noctux@user/noctux) (Ping timeout: 248 seconds) |
2022-12-07 02:17:31 +0100 | AWizzArd | (~code@gehrels.uberspace.de) |
2022-12-07 02:17:51 +0100 | mjacob | (~mjacob@adrastea.uberspace.de) (Ping timeout: 260 seconds) |
2022-12-07 02:17:56 +0100 | noctux | (~noctux@user/noctux) |
2022-12-07 02:18:32 +0100 | wroathe | (~wroathe@207-153-38-140.fttp.usinternet.com) |
2022-12-07 02:18:32 +0100 | wroathe | (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host) |
2022-12-07 02:18:32 +0100 | wroathe | (~wroathe@user/wroathe) |
2022-12-07 02:19:28 +0100 | <zzz> | h |
2022-12-07 02:19:30 +0100 | mjacob | (~mjacob@adrastea.uberspace.de) |
2022-12-07 02:26:26 +0100 | Lumia | (~Lumia@user/Lumia) |
2022-12-07 02:26:30 +0100 | raehik | (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net) (Quit: WeeChat 3.7.1) |
2022-12-07 02:27:27 +0100 | raehik | (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net) |
2022-12-07 02:27:38 +0100 | <[Leary]> | gurkenglas: I thought this last time you asked this question, but maybe you're looking for one of the `improve`s? E.g. https://hackage.haskell.org/package/kan-extensions-5.2.5/docs/Control-Monad-Codensity.html#v:improve |
2022-12-07 02:34:37 +0100 | troydm | (~troydm@host-176-37-124-197.b025.la.net.ua) (Ping timeout: 252 seconds) |
2022-12-07 02:37:41 +0100 | razetime | (~quassel@49.207.203.213) |
2022-12-07 02:42:47 +0100 | zant | (~zant@62.214.20.26) (Ping timeout: 264 seconds) |
2022-12-07 02:43:04 +0100 | raehik | (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net) (Ping timeout: 260 seconds) |
2022-12-07 02:50:04 +0100 | tomokojun | (~tomokojun@static-198-54-130-102.cust.tzulo.com) (Ping timeout: 260 seconds) |
2022-12-07 02:50:39 +0100 | gurkenglas | (~gurkengla@p548ac72e.dip0.t-ipconnect.de) (Ping timeout: 260 seconds) |
2022-12-07 02:50:42 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) |
2022-12-07 02:55:02 +0100 | king_gs1 | (~Thunderbi@2806:103e:29:94a4:81e0:429b:22ec:cf13) |
2022-12-07 02:55:03 +0100 | king_gs | (~Thunderbi@187.201.204.122) (Read error: Connection reset by peer) |
2022-12-07 02:55:03 +0100 | king_gs1 | king_gs |
2022-12-07 02:59:58 +0100 | sagax | (~sagax_nb@user/sagax) |
2022-12-07 03:02:54 +0100 | xff0x | (~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp) |
2022-12-07 03:05:07 +0100 | Lumia | (~Lumia@user/Lumia) (Quit: ,-) |
2022-12-07 03:07:01 +0100 | bontaq | (~user@ool-45779fe5.dyn.optonline.net) |
2022-12-07 03:09:56 +0100 | jao | (~jao@cpc103048-sgyl39-2-0-cust502.18-2.cable.virginm.net) (Ping timeout: 248 seconds) |
2022-12-07 03:16:52 +0100 | Chai-T-Rex | (~ChaiTRex@user/chaitrex) (Remote host closed the connection) |
2022-12-07 03:16:52 +0100 | chexum | (~quassel@gateway/tor-sasl/chexum) (Remote host closed the connection) |
2022-12-07 03:16:52 +0100 | califax | (~califax@user/califx) (Remote host closed the connection) |
2022-12-07 03:16:55 +0100 | FinnElija | (~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection) |
2022-12-07 03:16:55 +0100 | ec_ | (~ec@gateway/tor-sasl/ec) (Remote host closed the connection) |
2022-12-07 03:16:55 +0100 | azimut | (~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection) |
2022-12-07 03:16:55 +0100 | jpds1 | (~jpds@gateway/tor-sasl/jpds) (Remote host closed the connection) |
2022-12-07 03:17:21 +0100 | jpds1 | (~jpds@gateway/tor-sasl/jpds) |
2022-12-07 03:17:33 +0100 | chexum | (~quassel@gateway/tor-sasl/chexum) |
2022-12-07 03:17:36 +0100 | ec_ | (~ec@gateway/tor-sasl/ec) |
2022-12-07 03:17:57 +0100 | FinnElija | (~finn_elij@user/finn-elija/x-0085643) |
2022-12-07 03:17:58 +0100 | azimut | (~azimut@gateway/tor-sasl/azimut) |
2022-12-07 03:18:08 +0100 | Chai-T-Rex | (~ChaiTRex@user/chaitrex) |
2022-12-07 03:20:54 +0100 | califax | (~califax@user/califx) |
2022-12-07 03:21:58 +0100 | zant | (~zant@62.214.20.26) |
2022-12-07 03:22:23 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 264 seconds) |
2022-12-07 03:26:28 +0100 | zant | (~zant@62.214.20.26) (Ping timeout: 248 seconds) |
2022-12-07 03:28:29 +0100 | chexum | (~quassel@gateway/tor-sasl/chexum) (Remote host closed the connection) |
2022-12-07 03:28:50 +0100 | chexum | (~quassel@gateway/tor-sasl/chexum) |
2022-12-07 03:33:11 +0100 | gimmeanickel | (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0) |
2022-12-07 03:38:27 +0100 | ddellacosta | (~ddellacos@static-198-44-136-91.cust.tzulo.com) (Ping timeout: 256 seconds) |
2022-12-07 03:40:31 +0100 | ddellacosta | (~ddellacos@static-198-44-136-134.cust.tzulo.com) |
2022-12-07 03:42:04 +0100 | Erutuon | (~Erutuon@user/erutuon) (Ping timeout: 268 seconds) |
2022-12-07 03:42:47 +0100 | beteigeuze | (~Thunderbi@bl14-81-220.dsl.telepac.pt) (Ping timeout: 264 seconds) |
2022-12-07 03:50:07 +0100 | Unicorn_Princess | (~Unicorn_P@user/Unicorn-Princess/x-3540542) (Remote host closed the connection) |
2022-12-07 03:50:58 +0100 | money_ | (~money@user/polo) (Quit: money_) |
2022-12-07 03:51:44 +0100 | <Chai-T-Rex> | How can I install the `split` package for the generic `ghci` command? |
2022-12-07 03:53:24 +0100 | <Chai-T-Rex> | Or, alternatively, how can I install it so that I can use some command line options to GHCi? |
2022-12-07 03:53:51 +0100 | <c_wraith> | are you comfortable using something like `cabal repl -b split` instead? |
2022-12-07 03:54:22 +0100 | <Chai-T-Rex> | As long as it reads `.ghc/ghci.conf`. |
2022-12-07 03:54:48 +0100 | Lumia | (~Lumia@user/Lumia) |
2022-12-07 03:56:28 +0100 | <Chai-T-Rex> | When I do that, it can't find the `array` package included with GHC. |
2022-12-07 03:58:04 +0100 | <Chai-T-Rex> | It also seems to delete some functions I'd defined in GHCi.conf. |
2022-12-07 04:01:08 +0100 | <Chai-T-Rex> | I found out that the unrecommended `cabal install --reinstall -O2 --lib split` works. |
2022-12-07 04:01:22 +0100 | jero98772 | (~jero98772@2800:484:1d80:d8ce:efcc:cbb3:7f2a:6dff) (Remote host closed the connection) |
2022-12-07 04:08:08 +0100 | <sm> | chatgpt, compose me a command line to do haskell thing I want |
2022-12-07 04:09:22 +0100 | <sm> | heh. It says: ghci -package split -ghci-script ~/.ghc/ghci.conf |
2022-12-07 04:10:38 +0100 | use-value | (~Thunderbi@2a00:23c6:8a03:2f01:69a2:269b:4e3d:1c6) (Remote host closed the connection) |
2022-12-07 04:10:57 +0100 | use-value | (~Thunderbi@2a00:23c6:8a03:2f01:69a2:269b:4e3d:1c6) |
2022-12-07 04:11:43 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:111a:339b:4372:c307) |
2022-12-07 04:13:23 +0100 | mmhat | (~mmh@p200300f1c73b5136ee086bfffe095315.dip0.t-ipconnect.de) (Quit: WeeChat 3.7.1) |
2022-12-07 04:13:48 +0100 | Topsi | (~Topsi@dyndsl-095-033-034-215.ewe-ip-backbone.de) (Read error: Connection reset by peer) |
2022-12-07 04:15:51 +0100 | bobbingbob | (~dfadsva@2604:3d09:207f:f650::7b3a) (Ping timeout: 256 seconds) |
2022-12-07 04:16:10 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:111a:339b:4372:c307) (Ping timeout: 260 seconds) |
2022-12-07 04:16:56 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection) |
2022-12-07 04:17:38 +0100 | causal | (~user@50.35.85.7) (Quit: WeeChat 3.7.1) |
2022-12-07 04:18:10 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) |
2022-12-07 04:18:42 +0100 | gimmeanickel | (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0) (Remote host closed the connection) |
2022-12-07 04:22:37 +0100 | gimmeanickel | (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0) |
2022-12-07 04:27:56 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 255 seconds) |
2022-12-07 04:28:45 +0100 | DigitalKiwi | (~kiwi@2604:a880:400:d0::1ca0:e001) (Quit: quite.) |
2022-12-07 04:29:32 +0100 | DigitalKiwi | (~kiwi@2604:a880:400:d0::1ca0:e001) |
2022-12-07 04:30:47 +0100 | machinedgod | (~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 268 seconds) |
2022-12-07 04:30:59 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) |
2022-12-07 04:36:54 +0100 | troydm | (~troydm@host-176-37-124-197.b025.la.net.ua) |
2022-12-07 04:43:26 +0100 | instantaphex | (~jb@c-73-171-252-84.hsd1.fl.comcast.net) |
2022-12-07 04:45:20 +0100 | td_ | (~td@83.135.9.33) (Ping timeout: 260 seconds) |
2022-12-07 04:45:30 +0100 | Lumia | (~Lumia@user/Lumia) (Ping timeout: 256 seconds) |
2022-12-07 04:46:42 +0100 | td_ | (~td@83.135.9.15) |
2022-12-07 04:46:43 +0100 | gentauro | (~gentauro@user/gentauro) (Read error: Connection reset by peer) |
2022-12-07 04:47:21 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) |
2022-12-07 04:47:35 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:111a:339b:4372:c307) |
2022-12-07 04:52:20 +0100 | sloorush | (~sloorush@52.187.184.81) (Ping timeout: 248 seconds) |
2022-12-07 04:52:27 +0100 | gentauro | (~gentauro@user/gentauro) |
2022-12-07 04:52:52 +0100 | sloorush | (~sloorush@52.187.184.81) |
2022-12-07 04:55:04 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection) |
2022-12-07 04:55:04 +0100 | chexum | (~quassel@gateway/tor-sasl/chexum) (Remote host closed the connection) |
2022-12-07 04:55:04 +0100 | ec_ | (~ec@gateway/tor-sasl/ec) (Remote host closed the connection) |
2022-12-07 04:55:04 +0100 | FinnElija | (~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection) |
2022-12-07 04:55:53 +0100 | chexum | (~quassel@gateway/tor-sasl/chexum) |
2022-12-07 04:56:11 +0100 | FinnElija | (~finn_elij@user/finn-elija/x-0085643) |
2022-12-07 04:56:17 +0100 | ec_ | (~ec@gateway/tor-sasl/ec) |
2022-12-07 04:57:30 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) |
2022-12-07 05:02:59 +0100 | euandreh | (~Thunderbi@179.214.113.107) |
2022-12-07 05:04:51 +0100 | lisbeths | (uid135845@id-135845.lymington.irccloud.com) |
2022-12-07 05:05:45 +0100 | euandreh | (~Thunderbi@179.214.113.107) (Remote host closed the connection) |
2022-12-07 05:06:26 +0100 | 048AAH6AD | (~Thunderbi@179.214.113.107) |
2022-12-07 05:16:13 +0100 | <albet70> | write a module, where the module file should be for import? is there an environment variable for the module path? |
2022-12-07 05:16:43 +0100 | <albet70> | what's the path 'import' will seek? |
2022-12-07 05:17:45 +0100 | <sclv> | without any additional flags to ghc or any cabal file it uses the cwd as the base |
2022-12-07 05:18:05 +0100 | Lumia | (~Lumia@user/Lumia) |
2022-12-07 05:19:39 +0100 | <albet70> | where cwd point? |
2022-12-07 05:19:46 +0100 | wroathe | (~wroathe@user/wroathe) (Quit: leaving) |
2022-12-07 05:22:05 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 260 seconds) |
2022-12-07 05:22:27 +0100 | <albet70> | why it wouldn't import those custom modules where are on the same path with the caller? |
2022-12-07 05:23:40 +0100 | <sm> | @where paste, albet70 |
2022-12-07 05:23:40 +0100 | <lambdabot> | I know nothing about paste,. |
2022-12-07 05:23:50 +0100 | motherfsck | (~motherfsc@user/motherfsck) (Ping timeout: 260 seconds) |
2022-12-07 05:24:44 +0100 | <sm> | @where paste |
2022-12-07 05:24:44 +0100 | <lambdabot> | Help us help you: please paste full code, input and/or output at e.g. https://paste.tomsmeding.com |
2022-12-07 05:25:57 +0100 | <albet70> | sm https://paste.tomsmeding.com/nusGwMZC |
2022-12-07 05:26:29 +0100 | mbuf | (~Shakthi@49.204.118.69) |
2022-12-07 05:29:05 +0100 | freeside_ | (~mengwong@103.252.202.193) (Ping timeout: 260 seconds) |
2022-12-07 05:29:08 +0100 | freeside | (~mengwong@103.252.202.193) (Ping timeout: 248 seconds) |
2022-12-07 05:30:33 +0100 | shriekingnoise_ | (~shrieking@186.137.167.202) (Quit: Quit) |
2022-12-07 05:32:50 +0100 | <dsal> | albet70: Custom.hs |
2022-12-07 05:33:05 +0100 | <dsal> | Doing this without a project is kind of hard mode, though. |
2022-12-07 05:33:07 +0100 | <dsal> | Same for Chai-T-Rex |
2022-12-07 05:36:41 +0100 | <EvanR> | imagine if you needed a project to run a bash script |
2022-12-07 05:37:06 +0100 | <EvanR> | actually maybe that's a workable discriminator for "scripting" |
2022-12-07 05:37:27 +0100 | Lumia | (~Lumia@user/Lumia) (Ping timeout: 256 seconds) |
2022-12-07 05:39:08 +0100 | motherfsck | (~motherfsc@user/motherfsck) |
2022-12-07 05:39:29 +0100 | <dsal> | Also, you quite often *do*. |
2022-12-07 05:40:02 +0100 | <dsal> | Usually that project is shell.nix for me, but before nix it was "make sure you have whatever your operating system calls these packages before you try to run this script" |
2022-12-07 05:40:34 +0100 | <EvanR> | ok that's a dependency, not a build system or dependency management system |
2022-12-07 05:40:45 +0100 | <EvanR> | with additional files you have to have |
2022-12-07 05:41:07 +0100 | <EvanR> | to configure it |
2022-12-07 05:41:19 +0100 | <dsal> | Sure, these are also dependencies. People are wanting packages that aren't stock. |
2022-12-07 05:41:59 +0100 | werneta | (~werneta@70-142-214-115.lightspeed.irvnca.sbcglobal.net) (Ping timeout: 256 seconds) |
2022-12-07 05:42:11 +0100 | king_gs | (~Thunderbi@2806:103e:29:94a4:81e0:429b:22ec:cf13) (Ping timeout: 264 seconds) |
2022-12-07 05:42:19 +0100 | <dsal> | python has like, three different ways they've solved this problem so like, we're on par, I guess. |
2022-12-07 05:42:21 +0100 | <EvanR> | yeah, if you have the dependencies, then you still can't just compile the haskell code |
2022-12-07 05:42:39 +0100 | <dsal> | Similar with python virtualenv. |
2022-12-07 05:42:51 +0100 | <EvanR> | yeah so python isn't "scripting" anymore xD |
2022-12-07 05:42:54 +0100 | <dsal> | heh |
2022-12-07 05:43:00 +0100 | <dsal> | I've got python scripts I can't run anymore. :( |
2022-12-07 05:43:07 +0100 | <dsal> | Also, :) I don't like working in python |
2022-12-07 05:44:02 +0100 | <sm> | albet70: custom.hs should be Custom.hs |
2022-12-07 05:45:16 +0100 | <albet70> | ok |
2022-12-07 05:45:45 +0100 | jpds2 | (~jpds@gateway/tor-sasl/jpds) |
2022-12-07 05:46:14 +0100 | jpds1 | (~jpds@gateway/tor-sasl/jpds) (Ping timeout: 255 seconds) |
2022-12-07 05:51:07 +0100 | <albet70> | if my cabal project is with 'executable' not as 'library', do I need to 'exposed-modules' for my own modules? |
2022-12-07 05:53:54 +0100 | poljar | (~poljar@93-139-83-160.adsl.net.t-com.hr) |
2022-12-07 05:54:25 +0100 | <sm> | I don't think so... |
2022-12-07 05:54:26 +0100 | <sm> | does it build ? |
2022-12-07 05:55:16 +0100 | poljar1 | (~poljar@93-139-1-236.adsl.net.t-com.hr) (Ping timeout: 248 seconds) |
2022-12-07 05:57:19 +0100 | waleee | (~waleee@h-176-10-137-138.NA.cust.bahnhof.se) (Ping timeout: 260 seconds) |
2022-12-07 06:02:45 +0100 | johnw | (~johnw@2600:1700:cf00:db0:ccd8:6dba:13b3:7200) (Quit: ZNC - http://znc.in) |
2022-12-07 06:05:25 +0100 | gimmeanickel | (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0) (Remote host closed the connection) |
2022-12-07 06:05:43 +0100 | gimmeanickel | (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0) |
2022-12-07 06:07:10 +0100 | gimmeanickel | (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0) (Remote host closed the connection) |
2022-12-07 06:07:11 +0100 | Vajb | (~Vajb@2001:999:504:3ad6:52a4:a3b5:32d8:e74d) (Read error: Connection reset by peer) |
2022-12-07 06:07:40 +0100 | Vajb | (~Vajb@hag-jnsbng11-58c3a5-27.dhcp.inet.fi) |
2022-12-07 06:08:51 +0100 | <chreekat> | It'll build regardless,I think |
2022-12-07 06:10:09 +0100 | jpds2 | (~jpds@gateway/tor-sasl/jpds) (Remote host closed the connection) |
2022-12-07 06:10:31 +0100 | jpds2 | (~jpds@gateway/tor-sasl/jpds) |
2022-12-07 06:12:03 +0100 | Lumia | (~Lumia@user/Lumia) |
2022-12-07 06:13:59 +0100 | money_ | (~money@user/polo) |
2022-12-07 06:14:05 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Read error: Connection reset by peer) |
2022-12-07 06:14:11 +0100 | sammelweis_ | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) |
2022-12-07 06:20:55 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) |
2022-12-07 06:21:42 +0100 | Erutuon | (~Erutuon@user/erutuon) |
2022-12-07 06:23:12 +0100 | <albet70> | sm , no nedd for exposed-modules, it build |
2022-12-07 06:24:34 +0100 | <jackdk> | Where would the modules be exposed to? You can't depend on an executable from another library, ferexample. |
2022-12-07 06:26:48 +0100 | Vajb | (~Vajb@hag-jnsbng11-58c3a5-27.dhcp.inet.fi) (Read error: Connection reset by peer) |
2022-12-07 06:27:26 +0100 | Vajb | (~Vajb@2001:999:504:3ad6:52a4:a3b5:32d8:e74d) |
2022-12-07 06:30:55 +0100 | Lumia | (~Lumia@user/Lumia) (Ping timeout: 260 seconds) |
2022-12-07 06:33:33 +0100 | <albet70> | it should be listed in 'other-modules' |
2022-12-07 06:44:33 +0100 | <dibblego> | @src words |
2022-12-07 06:44:33 +0100 | <lambdabot> | words s = case dropWhile isSpace s of |
2022-12-07 06:44:33 +0100 | <lambdabot> | "" -> [] |
2022-12-07 06:44:33 +0100 | <lambdabot> | s' -> w : words s'' where (w, s'') = break isSpace s' |
2022-12-07 06:52:26 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 256 seconds) |
2022-12-07 06:52:29 +0100 | np | (~nerdypepp@user/nerdypepper) (Quit: bye) |
2022-12-07 06:52:31 +0100 | werneta | (~werneta@70-142-214-115.lightspeed.irvnca.sbcglobal.net) |
2022-12-07 06:53:47 +0100 | nerdypepper | (~nerdypepp@user/nerdypepper) |
2022-12-07 06:53:49 +0100 | tabaqui | (~root@88.231.62.215) (Quit: WeeChat 3.7.1) |
2022-12-07 06:54:27 +0100 | tabaqui | (~root@88.231.62.215) |
2022-12-07 07:01:11 +0100 | stiell | (~stiell@gateway/tor-sasl/stiell) (Remote host closed the connection) |
2022-12-07 07:02:26 +0100 | freeside | (~mengwong@103.252.202.193) |
2022-12-07 07:04:03 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection) |
2022-12-07 07:04:04 +0100 | califax | (~califax@user/califx) (Write error: Connection reset by peer) |
2022-12-07 07:04:04 +0100 | jpds2 | (~jpds@gateway/tor-sasl/jpds) (Write error: Connection reset by peer) |
2022-12-07 07:04:04 +0100 | Chai-T-Rex | (~ChaiTRex@user/chaitrex) (Read error: Connection reset by peer) |
2022-12-07 07:05:09 +0100 | califax | (~califax@user/califx) |
2022-12-07 07:05:23 +0100 | gimmeanickel | (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0) |
2022-12-07 07:05:25 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) |
2022-12-07 07:06:25 +0100 | Chai-T-Rex | (~ChaiTRex@user/chaitrex) |
2022-12-07 07:07:05 +0100 | stiell | (~stiell@gateway/tor-sasl/stiell) |
2022-12-07 07:07:19 +0100 | instantaphex | (~jb@c-73-171-252-84.hsd1.fl.comcast.net) (Ping timeout: 260 seconds) |
2022-12-07 07:07:26 +0100 | jpds2 | (~jpds@gateway/tor-sasl/jpds) |
2022-12-07 07:08:52 +0100 | freeside | (~mengwong@103.252.202.193) (Ping timeout: 248 seconds) |
2022-12-07 07:12:59 +0100 | freeside | (~mengwong@103.252.202.193) |
2022-12-07 07:17:22 +0100 | takuan | (~takuan@178-116-218-225.access.telenet.be) |
2022-12-07 07:17:35 +0100 | freeside | (~mengwong@103.252.202.193) (Ping timeout: 264 seconds) |
2022-12-07 07:28:00 +0100 | <iqubic> | I'm looking to write a megaparsec parser of the type "Parser String" which parses any string at all until a white space char is hit, and I don't want to consume the whitespace. |
2022-12-07 07:30:53 +0100 | trev | (~trev@user/trev) |
2022-12-07 07:32:54 +0100 | <glguy> | iqubic: look up : satisfy |
2022-12-07 07:38:11 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
2022-12-07 07:41:23 +0100 | gimmeanickel | (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0) (Ping timeout: 260 seconds) |
2022-12-07 07:42:53 +0100 | kenran | (~user@user/kenran) |
2022-12-07 07:43:39 +0100 | lisbeths | (uid135845@id-135845.lymington.irccloud.com) (Quit: Connection closed for inactivity) |
2022-12-07 07:44:34 +0100 | kenran | (~user@user/kenran) (Remote host closed the connection) |
2022-12-07 07:45:56 +0100 | jpds2 | (~jpds@gateway/tor-sasl/jpds) (Ping timeout: 255 seconds) |
2022-12-07 07:48:21 +0100 | jpds2 | (~jpds@gateway/tor-sasl/jpds) |
2022-12-07 07:48:25 +0100 | Chai-T-Rex | (~ChaiTRex@user/chaitrex) (Remote host closed the connection) |
2022-12-07 07:49:39 +0100 | Chai-T-Rex | (~ChaiTRex@user/chaitrex) |
2022-12-07 07:50:48 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
2022-12-07 07:51:23 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) |
2022-12-07 07:59:43 +0100 | Unicorn_Princess | (~Unicorn_P@user/Unicorn-Princess/x-3540542) |
2022-12-07 08:03:16 +0100 | Erutuon | (~Erutuon@user/erutuon) (Ping timeout: 256 seconds) |
2022-12-07 08:04:50 +0100 | incertia | (~incertia@209.122.71.127) (Ping timeout: 260 seconds) |
2022-12-07 08:11:21 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection) |
2022-12-07 08:12:51 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) |
2022-12-07 08:15:40 +0100 | bgs | (~bgs@212-85-160-171.dynamic.telemach.net) (Remote host closed the connection) |
2022-12-07 08:18:04 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
2022-12-07 08:20:40 +0100 | akegalj | (~akegalj@78-3-45-50.adsl.net.t-com.hr) |
2022-12-07 08:22:59 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 265 seconds) |
2022-12-07 08:24:05 +0100 | L29Ah | (~L29Ah@wikipedia/L29Ah) (Ping timeout: 260 seconds) |
2022-12-07 08:26:12 +0100 | lortabac | (~lortabac@2a01:e0a:541:b8f0:1b9f:5d8:d1e3:a25a) |
2022-12-07 08:31:50 +0100 | Chai-T-Rex | (~ChaiTRex@user/chaitrex) (Ping timeout: 255 seconds) |
2022-12-07 08:33:49 +0100 | Chai-T-Rex | (~ChaiTRex@user/chaitrex) |
2022-12-07 08:34:11 +0100 | gimmeanickel | (~gimmeanic@2405:9800:b640:c2eb:95ed:d852:31e3:4446) |
2022-12-07 08:34:18 +0100 | gimmeanickel | (~gimmeanic@2405:9800:b640:c2eb:95ed:d852:31e3:4446) (Remote host closed the connection) |
2022-12-07 08:35:30 +0100 | jinsun | (~jinsun@user/jinsun) () |
2022-12-07 08:41:17 +0100 | bontaq | (~user@ool-45779fe5.dyn.optonline.net) (Ping timeout: 252 seconds) |
2022-12-07 08:47:03 +0100 | razetime | (~quassel@49.207.203.213) (Read error: Connection reset by peer) |
2022-12-07 08:47:16 +0100 | razetime | (~quassel@49.207.203.213) |
2022-12-07 08:48:36 +0100 | michalz | (~michalz@185.246.204.75) |
2022-12-07 08:50:40 +0100 | lisbeths | (uid135845@id-135845.lymington.irccloud.com) |
2022-12-07 08:52:43 +0100 | incertia | (~incertia@209.122.71.127) |
2022-12-07 08:53:14 +0100 | Kaiepi | (~Kaiepi@108.175.84.104) |
2022-12-07 09:03:37 +0100 | zant | (~zant@62.214.20.26) |
2022-12-07 09:03:50 +0100 | jakalx | (~jakalx@base.jakalx.net) () |
2022-12-07 09:06:24 +0100 | freeside | (~mengwong@103.252.202.193) |
2022-12-07 09:07:21 +0100 | freeside_ | (~mengwong@103.252.202.193) |
2022-12-07 09:11:40 +0100 | mncheck | (~mncheck@193.224.205.254) |
2022-12-07 09:14:10 +0100 | use-value | (~Thunderbi@2a00:23c6:8a03:2f01:69a2:269b:4e3d:1c6) (Remote host closed the connection) |
2022-12-07 09:14:29 +0100 | use-value | (~Thunderbi@2a00:23c6:8a03:2f01:69a2:269b:4e3d:1c6) |
2022-12-07 09:17:38 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) |
2022-12-07 09:18:31 +0100 | coot | (~coot@213.134.171.3) |
2022-12-07 09:19:52 +0100 | bjourne2 | (~bjorn@94.191.136.236.mobile.tre.se) |
2022-12-07 09:21:10 +0100 | bjourne2 | (~bjorn@94.191.136.236.mobile.tre.se) (Client Quit) |
2022-12-07 09:22:43 +0100 | gmg | (~user@user/gehmehgeh) |
2022-12-07 09:24:36 +0100 | kazaf | (~kazaf@37.112.34.29) |
2022-12-07 09:25:25 +0100 | zeenk | (~zeenk@2a02:2f04:a30d:4300::7fe) |
2022-12-07 09:26:02 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:111a:339b:4372:c307) (Remote host closed the connection) |
2022-12-07 09:28:58 +0100 | fserucas__ | (~fserucas@laubervilliers-657-1-66-228.w90-63.abo.wanadoo.fr) |
2022-12-07 09:32:52 +0100 | Scraeling | (~Scraeling@user/scraeling) |
2022-12-07 09:36:07 +0100 | sammelweis_ | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Quit: No Ping reply in 180 seconds.) |
2022-12-07 09:36:14 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) |
2022-12-07 09:36:41 +0100 | avicenzi | (~avicenzi@2a00:ca8:a1f:b004::c32) |
2022-12-07 09:36:55 +0100 | MajorBiscuit | (~MajorBisc@2a02-a461-129d-1-193d-75d8-745d-e91e.fixed6.kpn.net) |
2022-12-07 09:36:57 +0100 | phma | (phma@2001:5b0:2144:44d8:212c:2869:b063:882b) (Read error: Connection reset by peer) |
2022-12-07 09:37:38 +0100 | phma | (~phma@host-67-44-208-200.hnremote.net) |
2022-12-07 09:42:15 +0100 | MajorBiscuit | (~MajorBisc@2a02-a461-129d-1-193d-75d8-745d-e91e.fixed6.kpn.net) (Ping timeout: 260 seconds) |
2022-12-07 09:43:11 +0100 | MajorBiscuit | (~MajorBisc@c-001-003-046.client.tudelft.eduvpn.nl) |
2022-12-07 09:45:49 +0100 | Sgeo | (~Sgeo@user/sgeo) (Read error: Connection reset by peer) |
2022-12-07 09:48:48 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Read error: Connection reset by peer) |
2022-12-07 09:49:54 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) |
2022-12-07 09:53:16 +0100 | machinedgod | (~machinedg@d198-53-218-113.abhsia.telus.net) |
2022-12-07 09:53:40 +0100 | use-value1 | (~Thunderbi@2a00:23c6:8a03:2f01:556e:28e8:6695:53e8) |
2022-12-07 09:55:47 +0100 | use-value | (~Thunderbi@2a00:23c6:8a03:2f01:69a2:269b:4e3d:1c6) (Ping timeout: 265 seconds) |
2022-12-07 09:55:47 +0100 | use-value1 | use-value |
2022-12-07 09:56:30 +0100 | acidjnk_new | (~acidjnk@p200300d6e7137a66c53ce5ddc06be1e3.dip0.t-ipconnect.de) |
2022-12-07 09:56:58 +0100 | fserucas__ | (~fserucas@laubervilliers-657-1-66-228.w90-63.abo.wanadoo.fr) (Quit: Leaving) |
2022-12-07 09:57:09 +0100 | fserucas | (~fserucas@laubervilliers-657-1-66-228.w90-63.abo.wanadoo.fr) |
2022-12-07 09:59:13 +0100 | functional | (~functiona@119.8.243.19) |
2022-12-07 10:09:08 +0100 | ft | (~ft@p508dbd59.dip0.t-ipconnect.de) (Quit: leaving) |
2022-12-07 10:14:14 +0100 | functional | (~functiona@119.8.243.19) (Quit: Client closed) |
2022-12-07 10:14:19 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
2022-12-07 10:16:09 +0100 | kimiamania | (~65804703@user/kimiamania) |
2022-12-07 10:23:54 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection) |
2022-12-07 10:25:40 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) |
2022-12-07 10:26:31 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43) |
2022-12-07 10:28:23 +0100 | gmg | (~user@user/gehmehgeh) (Ping timeout: 255 seconds) |
2022-12-07 10:28:23 +0100 | stiell | (~stiell@gateway/tor-sasl/stiell) (Ping timeout: 255 seconds) |
2022-12-07 10:28:36 +0100 | jakalx | (~jakalx@base.jakalx.net) |
2022-12-07 10:29:41 +0100 | stiell | (~stiell@gateway/tor-sasl/stiell) |
2022-12-07 10:30:17 +0100 | gmg | (~user@user/gehmehgeh) |
2022-12-07 10:30:53 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43) (Ping timeout: 246 seconds) |
2022-12-07 10:31:57 +0100 | alexiscott | (~user@4.red-83-36-45.dynamicip.rima-tde.net) |
2022-12-07 10:34:14 +0100 | CiaoSen | (~Jura@p200300c95747e0002a3a4dfffe84dbd5.dip0.t-ipconnect.de) |
2022-12-07 10:42:36 +0100 | zeenk | (~zeenk@2a02:2f04:a30d:4300::7fe) (Quit: Konversation terminated!) |
2022-12-07 10:45:25 +0100 | gurkenglas | (~gurkengla@p548ac72e.dip0.t-ipconnect.de) |
2022-12-07 10:46:34 +0100 | szkl | (uid110435@id-110435.uxbridge.irccloud.com) |
2022-12-07 10:47:43 +0100 | ubert1 | (~Thunderbi@2a02:8109:abc0:6434:3dae:2edc:412:e26e) |
2022-12-07 10:48:04 +0100 | chele | (~chele@user/chele) |
2022-12-07 10:51:47 +0100 | gmg | (~user@user/gehmehgeh) (Ping timeout: 255 seconds) |
2022-12-07 10:52:45 +0100 | nschoe | (~q@141.101.51.197) |
2022-12-07 10:53:48 +0100 | kalj | (~kalj@78-71-20-170-no193.tbcn.telia.com) |
2022-12-07 10:53:54 +0100 | zant | (~zant@62.214.20.26) (Ping timeout: 252 seconds) |
2022-12-07 10:57:37 +0100 | raehik | (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net) |
2022-12-07 10:59:20 +0100 | c_wraith | (~c_wraith@adjoint.us) (Ping timeout: 255 seconds) |
2022-12-07 10:59:35 +0100 | mtjm_ | (~mutantmel@2604:a880:2:d0::208b:d001) |
2022-12-07 10:59:46 +0100 | Patternmaster | (~georg@user/Patternmaster) (Ping timeout: 252 seconds) |
2022-12-07 11:00:15 +0100 | mtjm | (~mutantmel@2604:a880:2:d0::208b:d001) (Ping timeout: 255 seconds) |
2022-12-07 11:00:31 +0100 | <kalj> | What is the haskell way to take a datastructure and transform it in some minor way? I have a [(String,[String])], (string keys and list-of-strings values) and I want to do append something to the inner list where the key equals something, say "banana". I could do it by mapping something like \(k,v) -> if k=="banana" then (k,v++["newelem"]) else |
2022-12-07 11:00:31 +0100 | <kalj> | (k,v), but if the data structure gets more complex, you get a lot of map's and lambda's. |
2022-12-07 11:00:34 +0100 | Patternmaster | (~georg@user/Patternmaster) |
2022-12-07 11:01:22 +0100 | <dminuoso> | kalj: Difficult to answer in a general manner. |
2022-12-07 11:01:32 +0100 | c_wraith | (~c_wraith@adjoint.us) |
2022-12-07 11:02:23 +0100 | <dminuoso> | To describe nested access and mutation, `lens` or `optics` are common solutions. |
2022-12-07 11:02:54 +0100 | <kalj> | dminuoso Thanks, I will have a look. |
2022-12-07 11:03:02 +0100 | <dminuoso> | So the access you described would be formulated as: |
2022-12-07 11:04:27 +0100 | mtjm_ | mtjm |
2022-12-07 11:05:18 +0100 | <dminuoso> | kalj: data & at "banana" %~ (++ ["newelem"]) |
2022-12-07 11:05:40 +0100 | <dminuoso> | Which would work for `optics` at least. |
2022-12-07 11:06:05 +0100 | <dminuoso> | If you're relatively new, I would recommend you look into `optics` first, as it is better structured and documented, and has much better diagnostic. |
2022-12-07 11:06:29 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
2022-12-07 11:07:01 +0100 | <jackdk> | Does optics have an `At` instance for alists? |
2022-12-07 11:07:22 +0100 | <iqubic> | What ar alists? |
2022-12-07 11:07:25 +0100 | tzh | (~tzh@c-24-21-73-154.hsd1.wa.comcast.net) (Quit: zzz) |
2022-12-07 11:07:27 +0100 | xff0x | (~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp) (Ping timeout: 255 seconds) |
2022-12-07 11:08:21 +0100 | <dminuoso> | jackdk: Ah good point, this should be written as `data & traversed & at "banana" %~ (++ ["newelem"]) |
2022-12-07 11:08:38 +0100 | <dminuoso> | Gah. typo |
2022-12-07 11:08:44 +0100 | <dminuoso> | data & traversed % at "banana" %~ (++ ["newelem"]) |
2022-12-07 11:09:19 +0100 | <iqubic> | What are alists in this context? |
2022-12-07 11:09:20 +0100 | <iqubic> | What are alists in this context? |
2022-12-07 11:09:28 +0100 | <dminuoso> | iqubic: [(k, v)] |
2022-12-07 11:09:49 +0100 | <dminuoso> | Come to think of it, maybe at wouldnt actually work |
2022-12-07 11:10:07 +0100 | <dminuoso> | So you need to use `ix` |
2022-12-07 11:10:44 +0100 | <dminuoso> | and that wouldnt work either, a0 ~ a1 => Ixed (a0, a1) |
2022-12-07 11:10:46 +0100 | <dminuoso> | Sigh mmm |
2022-12-07 11:11:01 +0100 | <dminuoso> | Then something like |
2022-12-07 11:11:09 +0100 | <jackdk> | iqubic: https://en.wikipedia.org/wiki/Association_list |
2022-12-07 11:11:58 +0100 | acidjnk_new | (~acidjnk@p200300d6e7137a66c53ce5ddc06be1e3.dip0.t-ipconnect.de) (Ping timeout: 256 seconds) |
2022-12-07 11:12:41 +0100 | <iqubic> | jackdk: Neither Optics nor Lens provide a default for that type. |
2022-12-07 11:12:44 +0100 | <dminuoso> | Is there a kind of `eq :: s -> Getter s s`? |
2022-12-07 11:13:23 +0100 | <dminuoso> | Or no Getter is not enough. Should be Fold, perhaps |
2022-12-07 11:13:34 +0100 | <iqubic> | What are you trying to do here? |
2022-12-07 11:13:46 +0100 | <iqubic> | Fold is like Getter, but multiple targets. |
2022-12-07 11:14:19 +0100 | Lord_of_Life_ | (~Lord@user/lord-of-life/x-2819915) |
2022-12-07 11:14:36 +0100 | <dminuoso> | In optics lingo I would be looking for an AffineFold rather |
2022-12-07 11:15:00 +0100 | Lord_of_Life | (~Lord@user/lord-of-life/x-2819915) (Ping timeout: 260 seconds) |
2022-12-07 11:15:08 +0100 | <dminuoso> | The relevant difference with a getter is that the fold could fail |
2022-12-07 11:15:17 +0100 | <iqubic> | Yeah... I see |
2022-12-07 11:15:20 +0100 | <kalj> | Amazing. |
2022-12-07 11:15:32 +0100 | <dminuoso> | kalj: Im conjuring up a proper solution for what you asked for, the above is wrong. |
2022-12-07 11:15:41 +0100 | <jackdk> | we've gone into the weeds kalj. I'll have something sensible for you in a sec |
2022-12-07 11:15:49 +0100 | <jackdk> | and then I'll go back into the weeds too ^^ |
2022-12-07 11:16:07 +0100 | <dminuoso> | I guess I can use `filtered (== "foo") |
2022-12-07 11:16:37 +0100 | <iqubic> | What was Kalj's initial question? |
2022-12-07 11:16:42 +0100 | <xerox> | glguy: thanks for the idea of skipping the dirs in the listings and working with tails path it came out pretty neat that way |
2022-12-07 11:17:03 +0100 | Lord_of_Life_ | Lord_of_Life |
2022-12-07 11:17:14 +0100 | acidjnk_new | (~acidjnk@p200300d6e7137a66c53ce5ddc06be1e3.dip0.t-ipconnect.de) |
2022-12-07 11:17:33 +0100 | <jackdk> | "I have a [(String,[String])], (string keys and list-of-strings values) and I want to do append something to the inner list where the key equals something, say "banana". I could do it by mapping something like \(k,v) -> if k=="banana" then (k,v++["newelem"]) else (k,v), but if the data structure gets more complex, you get a lot of map's and lambda's." |
2022-12-07 11:18:12 +0100 | <kalj> | great. I am kind of interested in the general question, so the original question is maybe not super important. Basically, if you have non-trivial data structure, how do you do "updates" to it. Maybe I still think in a too imperative way, this is something that I can't seem to work my way around |
2022-12-07 11:18:16 +0100 | <dminuoso> | let eqing a = unsafeFiltered (== a) in data & traversed % unsafeFilteredBy (_1 % eqing "banana") % _2 %~ (++ ["newelem"]) |
2022-12-07 11:18:20 +0100 | <dminuoso> | This would work with optics. |
2022-12-07 11:18:25 +0100 | <xerox> | oh wrong channel, meant for aoc-spoilers |
2022-12-07 11:18:51 +0100 | <dminuoso> | kalj: Okay yes, for that general question `optics` or `lens` it that answer. |
2022-12-07 11:19:03 +0100 | <dminuoso> | Especially if the data can get quite nested. |
2022-12-07 11:19:13 +0100 | <dminuoso> | If its relatively shallow it may not be that useful |
2022-12-07 11:19:21 +0100 | <kalj> | @dmin Cool |
2022-12-07 11:19:21 +0100 | <lambdabot> | Not enough privileges |
2022-12-07 11:19:34 +0100 | <kalj> | :P |
2022-12-07 11:20:30 +0100 | <jackdk> | kalj: Here is a non-lensy way of attacking your problem https://www.irccloud.com/pastebin/IeHn3hi9/NotLensy.hs |
2022-12-07 11:20:43 +0100 | <dminuoso> | The above can be written in lens equivalently, you just write `filteredBy` and `filtered` instead (funnily, they are actually much unsafer, despite lacking the word `unsafe`) |
2022-12-07 11:21:33 +0100 | <jackdk> | kalj: basically, the `alistModify` function takes a "key" (here, your `String`) and a function that describes what to do with the value, if it exists, and then updates the list. |
2022-12-07 11:21:38 +0100 | <dminuoso> | Of course it should be said, that the deeper the nested access goes, the less fun writing it out will be. |
2022-12-07 11:22:36 +0100 | <dminuoso> | If the data is as shallow as you made it out, I would write it like jackdk (unless I already had optics around). With each additional data level, I would get more and more likely to use `optics` |
2022-12-07 11:22:50 +0100 | <jackdk> | kalj: the trick is in the order of arguments - by putting the data structure as the last argument, you can partially apply the function and get a function like `(Maybe v -> Maybe v) -> ([(k, v)] -> [(k, v)])`, which plays nicely with `(.)` (function composition) |
2022-12-07 11:23:04 +0100 | <jackdk> | Lemme check my misc repo, maybe I have a good example |
2022-12-07 11:23:38 +0100 | <dminuoso> | Another thing you can also do, is to use a `Map String [String]` rather than `[(String, [String])]` (assuming keys are unique), because `Map` already comes with `alter` or `alterF` |
2022-12-07 11:24:34 +0100 | <dminuoso> | take note that jackdk's function is of type: |
2022-12-07 11:24:37 +0100 | <dminuoso> | alter :: (Maybe a -> Maybe a) -> Key -> IntMap a -> IntMap a |
2022-12-07 11:24:42 +0100 | <jackdk> | kalj: https://git.sr.ht/~jack/misc/tree/master/item/codeworld-raycaster/src/State.hs#L39-43 doesn't do _nested_ updates, but is another example of the pattern |
2022-12-07 11:24:43 +0100 | <dminuoso> | 'alter :: (Maybe a -> Maybe a) -> Key -> IntMap a -> IntMap a |
2022-12-07 11:24:49 +0100 | <dminuoso> | alistModify :: Eq k => k -> (Maybe v -> Maybe v) -> [(k, v)] -> [(k, v)] |
2022-12-07 11:25:01 +0100 | <dminuoso> | alter :: Ord k => (Maybe a -> Maybe a) -> k -> Map k a -> Map k a |
2022-12-07 11:25:06 +0100 | <kalj> | I am amazed! |
2022-12-07 11:25:08 +0100 | <dminuoso> | So this directly mimics `alter` from Map. :) |
2022-12-07 11:25:16 +0100 | <kalj> | Cool stuff, I definitely have some reading up to do |
2022-12-07 11:25:31 +0100 | <kalj> | Yeah, I should definitely use a Map in this case |
2022-12-07 11:26:25 +0100 | <jackdk> | Yeah, this all looked way harder because unlike lispers, we don't use association lists very much |
2022-12-07 11:27:24 +0100 | <dminuoso> | `optics` and `lens` provide a very generalized framework for expression pretty much any type of access patterns (i.e. "go over each element in the list, left side of a tuple, inside the map key at "foo", add 1 over element in the (Int, Int, Int) tuple)), or you want to extract information, or just set it, etc.. |
2022-12-07 11:27:52 +0100 | <dminuoso> | But it's quite a large dependency to include for just a singular use case. |
2022-12-07 11:28:47 +0100 | <jackdk> | I would strongly recommend learning lens **eventually**, because it's so useful, but first learn "normal" haskell |
2022-12-07 11:29:16 +0100 | <kalj> | Anyways, another nooby question: how do you typically troubleshoot haskell code? I am noticing that stuff end up giving the wrong result, but I can't just "printf debug" like I'm used to. How would one go about trying to inspect values in the middle of a computation_ |
2022-12-07 11:29:36 +0100 | <dminuoso> | jackdk: Im wondering whether we should perhaps have a kind of `alist :: IxTraversal k (k, a) (k, b) a b` utility in lens and optics. |
2022-12-07 11:29:54 +0100 | <dminuoso> | At first glance that seems easy to write and useful |
2022-12-07 11:30:40 +0100 | troydm | (~troydm@host-176-37-124-197.b025.la.net.ua) (Ping timeout: 256 seconds) |
2022-12-07 11:31:02 +0100 | <dminuoso> | Or mmm, no actually that would have to be an IxFold to work out |
2022-12-07 11:31:02 +0100 | <jackdk> | dminuoso: I almost never use alists, so I'm not super fussed either way. I don't think you can change type though, unless you change it in every member at once? |
2022-12-07 11:31:18 +0100 | <dminuoso> | Sure, but that's how it works anyway? |
2022-12-07 11:31:50 +0100 | <jackdk> | kalj: You can fake "printf debugging" using the functions in `Debug.Trace` - I find `traceShowId` most useful - "print the thing if it can be shown, then return it" |
2022-12-07 11:31:56 +0100 | <dminuoso> | Call it `aelem :: IxFold k (k, a) (k, b) a b` -- if you compose this onto a `traversed % aelem` you can simply swap out the value side of an alist. |
2022-12-07 11:32:20 +0100 | <dminuoso> | Or gah, this wont work either. It needs IxTraversal really. |
2022-12-07 11:32:35 +0100 | lortabac | (~lortabac@2a01:e0a:541:b8f0:1b9f:5d8:d1e3:a25a) (Ping timeout: 264 seconds) |
2022-12-07 11:33:03 +0100 | <jackdk> | dminuoso: if it's a fold then you'll only get a fold when you compose with a traversal but - I think you want `assoc :: Eq k => k -> Lens' [(k, a)] (Maybe a)` |
2022-12-07 11:33:31 +0100 | <jackdk> | kalj: but more often, I test smaller and smaller parts of my code in a repl, until I've isolated the thing that is misbehaving |
2022-12-07 11:33:34 +0100 | <dminuoso> | jackdk: I think an IxTraversal is more useful. |
2022-12-07 11:34:29 +0100 | <jackdk> | kalj: because haskell is pure, you can evaluate things by hand as well - that's often a good way to see what's going wrong |
2022-12-07 11:34:49 +0100 | <dminuoso> | jackdk: You can use `trace` (and all similar trace* functions) to debug evaluation. |
2022-12-07 11:34:57 +0100 | <dminuoso> | https://hackage.haskell.org/package/base-4.17.0.0/docs/Debug-Trace.html#v:trace |
2022-12-07 11:34:59 +0100 | <jackdk> | dminuoso: I just said that |
2022-12-07 11:35:21 +0100 | <jackdk> | thanks for the haddock link though - should've posted that too |
2022-12-07 11:35:22 +0100 | <dminuoso> | jackdk: Oh, there was a weird line break in weechat, mentally I skipped what was above. |
2022-12-07 11:35:45 +0100 | <dminuoso> | Not sure why weechat does occacsionally print `- - - - - - ...` |
2022-12-07 11:36:35 +0100 | <dminuoso> | jackdk: Also, even your assoc should be an (Affine) traversal, rather than a `Lens'` onto a Maybe. |
2022-12-07 11:36:56 +0100 | <dminuoso> | Im not entirely sure why `at` uses Lens onto Maybe as well |
2022-12-07 11:37:19 +0100 | <jackdk> | dminuoso: because unlike `ix`, `at` allows you to create and delete entries. I wanted the same for `assoc`. |
2022-12-07 11:37:24 +0100 | <mauke> | xerox: what is aoc-spoilers? |
2022-12-07 11:37:25 +0100 | <dminuoso> | Ohhh |
2022-12-07 11:38:20 +0100 | <dminuoso> | Yeah that makes sense. `assoc :: Eq k => k -> IxLens k [(k, a)] (Maybe a)` it is (took the liberty of adding the Ix part to it) |
2022-12-07 11:39:12 +0100 | <kalj> | Thanks, Debug.Trace helps! |
2022-12-07 11:39:15 +0100 | <mauke> | dminuoso: did you switch tabs in between? (i.e. is it a "last position before switch" marker?) |
2022-12-07 11:39:36 +0100 | <dminuoso> | mauke: not sure |
2022-12-07 11:40:17 +0100 | <dminuoso> | (though perhaps the Ix part is completely redundant, since you already have access to the key...) |
2022-12-07 11:41:02 +0100 | <dminuoso> | jackdk: Could Wither be a thing in lens/optics world? |
2022-12-07 11:41:22 +0100 | <mauke> | (I once implemented that feature as a ChatZilla add-on) |
2022-12-07 11:41:50 +0100 | <dminuoso> | type WitherLike f s t a b = (a -> f (Maybe b)) -> s -> f t |
2022-12-07 11:41:52 +0100 | <dminuoso> | type Wither s t a b = forall f. Applicative f => WitherLike f s t a b |
2022-12-07 11:41:54 +0100 | <dminuoso> | Mmmm |
2022-12-07 11:42:21 +0100 | <dminuoso> | That's cute :) |
2022-12-07 11:42:24 +0100 | <jackdk> | dminuoso: https://old.reddit.com/r/haskell/comments/jlr1g4/blog_composable_filtering_optics_using_witherable/ in my browser history, but I don't have an opinion on it |
2022-12-07 11:51:23 +0100 | mmhat | (~mmh@p200300f1c73b5136ee086bfffe095315.dip0.t-ipconnect.de) |
2022-12-07 11:51:49 +0100 | beteigeuze | (~Thunderbi@bl14-81-220.dsl.telepac.pt) |
2022-12-07 11:53:12 +0100 | <iqubic> | Does that work with Lens? |
2022-12-07 11:56:36 +0100 | mmhat | (~mmh@p200300f1c73b5136ee086bfffe095315.dip0.t-ipconnect.de) (Quit: WeeChat 3.7.1) |
2022-12-07 11:56:47 +0100 | econo | (uid147250@user/econo) (Quit: Connection closed for inactivity) |
2022-12-07 12:00:23 +0100 | lisbeths | (uid135845@id-135845.lymington.irccloud.com) (Quit: Connection closed for inactivity) |
2022-12-07 12:02:13 +0100 | fserucas | (~fserucas@laubervilliers-657-1-66-228.w90-63.abo.wanadoo.fr) (Ping timeout: 256 seconds) |
2022-12-07 12:03:02 +0100 | bjourne | (~bjourne@2001:6b0:1:1140:42bf:ff4:f8fa:50e5) (Quit: Konversation terminated!) |
2022-12-07 12:04:22 +0100 | <xerox> | mauke: #adventofcode-spoilers |
2022-12-07 12:04:40 +0100 | jmdaemon | (~jmdaemon@user/jmdaemon) (Ping timeout: 256 seconds) |
2022-12-07 12:05:44 +0100 | xff0x | (~xff0x@ai071162.d.east.v6connect.net) |
2022-12-07 12:07:40 +0100 | <jackdk> | iqubic: It's got the same vague shape, so maybe? |
2022-12-07 12:08:23 +0100 | <iqubic> | Is Witherable ever gonna get added to the core Lens library? |
2022-12-07 12:12:24 +0100 | gurkenglas | (~gurkengla@p548ac72e.dip0.t-ipconnect.de) (Ping timeout: 260 seconds) |
2022-12-07 12:15:02 +0100 | Chai-T-Rex | (~ChaiTRex@user/chaitrex) (Ping timeout: 255 seconds) |
2022-12-07 12:15:50 +0100 | zant | (~zant@2a00:20:6017:5cfb:1db8:b3f9:e08:f0dd) |
2022-12-07 12:16:05 +0100 | Chai-T-Rex | (~ChaiTRex@user/chaitrex) |
2022-12-07 12:16:23 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 255 seconds) |
2022-12-07 12:18:52 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) |
2022-12-07 12:20:18 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Quit: No Ping reply in 180 seconds.) |
2022-12-07 12:21:36 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) |
2022-12-07 12:23:35 +0100 | ec_ | (~ec@gateway/tor-sasl/ec) (Ping timeout: 255 seconds) |
2022-12-07 12:25:59 +0100 | zant1 | (~zant@2a00:20:6017:5cfb:7889:b51c:c40a:b6bb) |
2022-12-07 12:26:04 +0100 | ec_ | (~ec@gateway/tor-sasl/ec) |
2022-12-07 12:27:05 +0100 | zant | (~zant@2a00:20:6017:5cfb:1db8:b3f9:e08:f0dd) (Ping timeout: 255 seconds) |
2022-12-07 12:31:10 +0100 | razetime | (~quassel@49.207.203.213) (Ping timeout: 268 seconds) |
2022-12-07 12:31:29 +0100 | razetime | (~quassel@49.207.203.213) |
2022-12-07 12:34:03 +0100 | amano[m] | (~amanocute@2001:470:69fc:105::2:d3f4) |
2022-12-07 12:34:53 +0100 | lortabac | (~lortabac@2a01:e0a:541:b8f0:ebf5:c68c:db4f:4f95) |
2022-12-07 12:42:36 +0100 | o1lo01ol1o | (~o1lo01ol1@2001:8a0:6a54:cb00:897b:5682:aa16:df9e) |
2022-12-07 12:42:45 +0100 | <o1lo01ol1o> | I have an hspec test in a suite that fails when run in cabal test but which passes in ghci. Are there any resources for what may be going on? |
2022-12-07 12:43:10 +0100 | DigitalKiwi | (~kiwi@2604:a880:400:d0::1ca0:e001) (Quit: quite.) |
2022-12-07 12:43:55 +0100 | DigitalKiwi | (~kiwi@137.184.156.191) |
2022-12-07 12:44:23 +0100 | zant1 | (~zant@2a00:20:6017:5cfb:7889:b51c:c40a:b6bb) (Ping timeout: 252 seconds) |
2022-12-07 12:44:54 +0100 | kazaf | (~kazaf@37.112.34.29) (Ping timeout: 256 seconds) |
2022-12-07 12:49:11 +0100 | haritz | (~hrtz@user/haritz) (Quit: ZNC 1.8.2+deb2 - https://znc.in) |
2022-12-07 12:54:41 +0100 | dextaa2 | (~DV@user/dextaa) |
2022-12-07 12:57:04 +0100 | dextaa | (~DV@user/dextaa) (Ping timeout: 268 seconds) |
2022-12-07 12:57:05 +0100 | dextaa2 | dextaa |
2022-12-07 13:00:28 +0100 | jakalx | (~jakalx@base.jakalx.net) () |
2022-12-07 13:00:37 +0100 | <albet70> | is that any run-time exceptions are IO Exceptions? |
2022-12-07 13:01:30 +0100 | <albet70> | is 1/0 an exception? |
2022-12-07 13:02:38 +0100 | <mauke> | > 1/0 |
2022-12-07 13:02:39 +0100 | <[exa]> | AFAIK there's no other reasonable way to "receive" an exception than IO (maybe ST) |
2022-12-07 13:02:39 +0100 | <lambdabot> | Infinity |
2022-12-07 13:03:03 +0100 | <dminuoso> | [exa]: ST cant have exceptions (and I finally understood why too!) |
2022-12-07 13:03:09 +0100 | <xerox> | > 1/(1/0) |
2022-12-07 13:03:10 +0100 | <lambdabot> | 0.0 |
2022-12-07 13:03:16 +0100 | <[exa]> | dminuoso: ah okay, good. :D |
2022-12-07 13:03:27 +0100 | CiaoSen | (~Jura@p200300c95747e0002a3a4dfffe84dbd5.dip0.t-ipconnect.de) (Ping timeout: 252 seconds) |
2022-12-07 13:03:51 +0100 | <merijn> | Dividing by 0 isn't an exception for Doubles |
2022-12-07 13:04:08 +0100 | <merijn> | It's just positive/negative infinity |
2022-12-07 13:04:30 +0100 | <[exa]> | > div 1 0 |
2022-12-07 13:04:31 +0100 | <dminuoso> | albet70: And no, IO exceptions are separate from pure exceptions. |
2022-12-07 13:04:31 +0100 | <lambdabot> | *Exception: divide by zero |
2022-12-07 13:04:47 +0100 | __monty__ | (~toonn@user/toonn) |
2022-12-07 13:05:02 +0100 | <dminuoso> | albet70: THere's even semantic differences between them, see https://www.microsoft.com/en-us/research/publication/a-semantics-for-imprecise-exceptions/ |
2022-12-07 13:05:06 +0100 | <[exa]> | dminuoso: btw what's the actual reason? (/me curious) |
2022-12-07 13:05:34 +0100 | <mniip> | [exa], you can catch them inside runST and now suddenly you're catching in pure code |
2022-12-07 13:05:48 +0100 | <albet70> | my real question is this https://hackage.haskell.org/package/scotty-0.12.1/docs/src/Web.Scotty.html#rescue |
2022-12-07 13:05:57 +0100 | <[exa]> | mniip: ah yes that makes sense |
2022-12-07 13:06:05 +0100 | <albet70> | I wonder how this 'rescue' handle exceptions |
2022-12-07 13:06:41 +0100 | jakalx | (~jakalx@base.jakalx.net) |
2022-12-07 13:06:52 +0100 | <mniip> | albet70, probably using IO's throw and catch as seen here https://hackage.haskell.org/package/base-4.17.0.0/docs/GHC-IO.html#v:catch |
2022-12-07 13:07:02 +0100 | <dminuoso> | albet70: It's just a pretty wrapper around https://hackage.haskell.org/package/mtl-2.3.1/docs/Control-Monad-Error-Class.html#v:catchError |
2022-12-07 13:07:04 +0100 | zant1 | (~zant@62.96.232.178) |
2022-12-07 13:07:18 +0100 | <dminuoso> | Which ends up calling `catch` like mniip pointed out |
2022-12-07 13:07:36 +0100 | <[exa]> | mniip: thanks! |
2022-12-07 13:07:56 +0100 | <mniip> | and IO's throw and catch are very thin wrappers around GHC RTS primitives (magic) |
2022-12-07 13:10:11 +0100 | fserucas | (~fserucas@laubervilliers-657-1-66-228.w90-63.abo.wanadoo.fr) |
2022-12-07 13:13:53 +0100 | <albet70> | there's a ContT r m a in that 'catch' and 'catchError' |
2022-12-07 13:15:59 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Quit: No Ping reply in 180 seconds.) |
2022-12-07 13:16:09 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) |
2022-12-07 13:17:33 +0100 | <dminuoso> | mniip: that at least makes is technically impossible as raiseIO# requires a monomorphic RealWorld parameterized state token |
2022-12-07 13:19:11 +0100 | <mniip> | dminuoso, there's some puity/referential transparency/... reason that I can't quite remember now |
2022-12-07 13:21:44 +0100 | 048AAH6AD | (~Thunderbi@179.214.113.107) (Ping timeout: 256 seconds) |
2022-12-07 13:22:14 +0100 | <dminuoso> | mniip: raiseIO# throws precise exceptions, raise# throws imprecise exceptions. If you were allowed to throwIO# in ST, they could leak outside. |
2022-12-07 13:22:23 +0100 | <dminuoso> | And that would violate some optimizations and analysis |
2022-12-07 13:22:32 +0100 | bgs | (~bgs@212-85-160-171.dynamic.telemach.net) |
2022-12-07 13:24:25 +0100 | <dminuoso> | Though Im not entirely sure about runRW# in that respect, because unsafePerformIO would have the same problems mmm |
2022-12-07 13:24:36 +0100 | euandreh | (~Thunderbi@179.214.113.107) |
2022-12-07 13:25:00 +0100 | <albet70> | dminuoso , as you said, there're two exceptions, pure exception and IO exception, is 1/0 a pure exception? that run-time exceptions are IO exception? read from file or socket is IO exception? |
2022-12-07 13:25:13 +0100 | <dminuoso> | albet70: 1/0 actually is not an exception. |
2022-12-07 13:25:19 +0100 | sammelweis_ | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) |
2022-12-07 13:25:24 +0100 | <dminuoso> | Or at least not depending on which type you instantiate this at |
2022-12-07 13:26:18 +0100 | <albet70> | what about passing an String to (+), is that an exception? |
2022-12-07 13:26:24 +0100 | <dminuoso> | A runtime exception arises from `undefined`, `error "foo"`, missing patterns, etc.. |
2022-12-07 13:26:34 +0100 | <dminuoso> | That is a type checker error. |
2022-12-07 13:26:39 +0100 | <dminuoso> | Potentially, anyway |
2022-12-07 13:26:58 +0100 | <dminuoso> | So `undefined`, `error "foo"`, missing patterns - these are examples of pure (and thus imprecise) exceptions |
2022-12-07 13:27:17 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Ping timeout: 252 seconds) |
2022-12-07 13:27:28 +0100 | <dminuoso> | These are catchable using `evaluate :: a -> IO a`, but it is very important to understand what `imprecise` here means before using `evaluate`. |
2022-12-07 13:27:28 +0100 | <albet70> | (+) print print would get an 'error ...' right? |
2022-12-07 13:27:37 +0100 | <dminuoso> | No, it would just fail to compile. |
2022-12-07 13:27:41 +0100 | <dminuoso> | % (+) print print |
2022-12-07 13:27:41 +0100 | <yahb2> | <interactive>:68:1: error: ; • No instance for (Num (() -> IO ())) arising from a use of ‘it’ ; (maybe you haven't applied a function to enough arguments?) ; • In the first argument... |
2022-12-07 13:28:42 +0100 | <dminuoso> | I tend to think of pure exceptions as a kind of landmine, that when evaluation steps into will immediately abort (either the entire program, or bubble up as an IO exception at `evaluate` -- again up to the imprecise nature of pure exceptions) |
2022-12-07 13:29:06 +0100 | <dminuoso> | In most cases it will abort. |
2022-12-07 13:29:35 +0100 | <albet70> | could you give an example of pure exception? |
2022-12-07 13:29:42 +0100 | <albet70> | common example |
2022-12-07 13:29:42 +0100 | <dminuoso> | │13:26:58 dminuoso | So `undefined`, `error "foo"`, missing patterns - these are examples of pure (and thus imprecise) exceptions |
2022-12-07 13:30:24 +0100 | <dminuoso> | % (error "thing") + 2 |
2022-12-07 13:30:24 +0100 | <yahb2> | *** Exception: thing ; CallStack (from HasCallStack): ; error, called at <interactive>:70:2 in interactive:Ghci13 |
2022-12-07 13:30:55 +0100 | <dminuoso> | % putStr "foo" >> putStr (error "no!") |
2022-12-07 13:30:55 +0100 | <yahb2> | foo*** Exception: no! ; CallStack (from HasCallStack): ; error, called at <interactive>:72:25 in interactive:Ghci13 |
2022-12-07 13:30:59 +0100 | <albet70> | but those are raised by your intension |
2022-12-07 13:31:09 +0100 | <dminuoso> | ^- note how the execution has already printed `foo` before the explosion? |
2022-12-07 13:31:23 +0100 | <albet70> | intention |
2022-12-07 13:31:37 +0100 | <dminuoso> | So there's two classes of when pure exceptions are found in Haskell code |
2022-12-07 13:32:10 +0100 | <dminuoso> | a) positioning an `error` for seemingly impossible code. in more elaborate code, it is probably better to do some terminal error management, but `error "internal error: xyz not initialized"` is a very easy way of getting the job done. |
2022-12-07 13:32:48 +0100 | <dminuoso> | b) writing unsafe code, like `head (x:xs) = x; head [] = error "head: empty list"` |
2022-12-07 13:33:12 +0100 | <dminuoso> | The latter of which is often considered bad style especially in a standard library (because misusing it will usually terminate an entire program) |
2022-12-07 13:33:16 +0100 | <dminuoso> | The worst example of this is `read` |
2022-12-07 13:33:24 +0100 | <dminuoso> | If `read` fails, it will abort with a pure exception |
2022-12-07 13:33:44 +0100 | <dminuoso> | % (read "100-1") :: Int |
2022-12-07 13:33:44 +0100 | <yahb2> | *** Exception: Prelude.read: no parse |
2022-12-07 13:34:35 +0100 | <dminuoso> | So burying a `read` inside a library is particularly awful, because it can crash your program. |
2022-12-07 13:34:44 +0100 | <dminuoso> | Or any program that relies on that library. |
2022-12-07 13:34:56 +0100 | <merijn> | We should just delete read from existing :p |
2022-12-07 13:35:03 +0100 | <dminuoso> | +1 |
2022-12-07 13:35:17 +0100 | <merijn> | Replace it with readMaybe |
2022-12-07 13:35:34 +0100 | <dminuoso> | Or better yet, proper parsing. :) |
2022-12-07 13:37:36 +0100 | aliosablack | (~chomwitt@2a02:587:7a0c:6a00:1ac0:4dff:fedb:a3f1) |
2022-12-07 13:37:40 +0100 | <mniip> | this is a question of sane defaults and there's no right answer |
2022-12-07 13:39:17 +0100 | <merijn> | eh |
2022-12-07 13:39:30 +0100 | <merijn> | readMaybe is the obvious right answer for sane default |
2022-12-07 13:39:33 +0100 | <albet70> | so there three things, 1. error before 'evaluate' like 1/0, print + print, 2. pure exception, raised by 'error' as your intention or abort like (read "a") :: Int, 3. IO exception like readFile, is this correct? |
2022-12-07 13:39:37 +0100 | <merijn> | So, hard disagree with you there :p |
2022-12-07 13:40:47 +0100 | <albet70> | merijn, without read, how to turn string to Int? |
2022-12-07 13:41:49 +0100 | <merijn> | :t readMaybe |
2022-12-07 13:41:50 +0100 | <lambdabot> | error: Variable not in scope: readMaybe |
2022-12-07 13:41:53 +0100 | <merijn> | :O |
2022-12-07 13:41:59 +0100 | <merijn> | :t Text.Read.readMaybe |
2022-12-07 13:42:00 +0100 | <lambdabot> | Read a => String -> Maybe a |
2022-12-07 13:42:44 +0100 | <dminuoso> | Or `readEither` even |
2022-12-07 13:42:55 +0100 | <merijn> | "read" is "nice" for Advent of Code and a massive liability for literally every non-trivial code. So I'd rather make people's AoC solutions slightly more verbose :p |
2022-12-07 13:43:44 +0100 | CiaoSen | (~Jura@p200300c95747e0002a3a4dfffe84dbd5.dip0.t-ipconnect.de) |
2022-12-07 13:48:30 +0100 | Topsi | (~Topsi@217.64.164.1) |
2022-12-07 13:48:49 +0100 | Topsi1 | (~Topsi@dyndsl-095-033-143-231.ewe-ip-backbone.de) |
2022-12-07 13:49:11 +0100 | <albet70> | merijn, how about remove Maybe since Either can do the exactly same thing |
2022-12-07 13:49:28 +0100 | <merijn> | readEither already exists too |
2022-12-07 13:49:52 +0100 | <albet70> | :t maybe |
2022-12-07 13:49:53 +0100 | <lambdabot> | b -> (a -> b) -> Maybe a -> b |
2022-12-07 13:50:58 +0100 | akegalj | (~akegalj@78-3-45-50.adsl.net.t-com.hr) (Quit: leaving) |
2022-12-07 13:52:11 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
2022-12-07 13:53:37 +0100 | bontaq | (~user@ool-45779fe5.dyn.optonline.net) |
2022-12-07 13:57:41 +0100 | johnw | (~johnw@2600:1700:cf00:db0:1da8:bc45:1742:a938) |
2022-12-07 14:01:00 +0100 | <albet70> | when b~IO b, maybe can turn a Maybe a to IO b, this is amazing I think |
2022-12-07 14:04:52 +0100 | sammelweis_ | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Quit: No Ping reply in 180 seconds.) |
2022-12-07 14:05:08 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) (Quit: = "") |
2022-12-07 14:05:11 +0100 | Scraeling | (~Scraeling@user/scraeling) (Remote host closed the connection) |
2022-12-07 14:05:58 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) |
2022-12-07 14:06:23 +0100 | o1lo01ol1o | (~o1lo01ol1@2001:8a0:6a54:cb00:897b:5682:aa16:df9e) (Ping timeout: 260 seconds) |
2022-12-07 14:08:09 +0100 | <albet70> | IIRC there is module, I forget the name, replace Either with Exception? |
2022-12-07 14:08:59 +0100 | <merijn> | Sounds like a great way to get lynched by colleagues |
2022-12-07 14:11:52 +0100 | <freeside_> | halp. i can haz quadratic runtime due to a memory leak. i have spent two days on AOC 2019 day 16. It really is as hard as people say it is :-( |
2022-12-07 14:12:12 +0100 | <freeside_> | https://github.com/mengwong/adventofcode/blob/2022/apps/aoc2019-day16.hs#L64-L79 |
2022-12-07 14:12:47 +0100 | <kuribas> | albet70: either (const $ throw myException) pure |
2022-12-07 14:12:56 +0100 | <trev> | how do you give a type hint to a function? i want to play on the repl with `read` but it doesn't know what type to read into |
2022-12-07 14:13:12 +0100 | <freeside_> | my runtimes are growing by 1, 2, 3, 4, 5, 6 seconds for the same size input |
2022-12-07 14:13:15 +0100 | <kuribas> | :t (id :: Int -> Int) --trev |
2022-12-07 14:13:16 +0100 | <lambdabot> | Int -> Int |
2022-12-07 14:13:58 +0100 | dora | (~dora@kwlan4.uoks.uj.edu.pl) |
2022-12-07 14:14:33 +0100 | freeside | (~mengwong@103.252.202.193) (Quit: re-nick) |
2022-12-07 14:14:43 +0100 | freeside_ | freeside |
2022-12-07 14:16:52 +0100 | <trev> | kuribas i don't get it |
2022-12-07 14:17:06 +0100 | <freeside> | so, it appears that an individual run of my `go` function takes a constant 0.01x seconds, but the infrastructure around it (nTimesM) is somehow adding runtime in a way that looks exactly like a memory leak. my process is now up to 24GB :( |
2022-12-07 14:17:10 +0100 | <trev> | how would the identify function work if i don't explicity give it the type? |
2022-12-07 14:17:16 +0100 | <kuribas> | :t (read :: String -> Int) |
2022-12-07 14:17:17 +0100 | <lambdabot> | String -> Int |
2022-12-07 14:17:41 +0100 | <kuribas> | trev: then it determines the type from the context. |
2022-12-07 14:17:54 +0100 | <freeside> | trev: if you want to be explicit about it, see https://github.com/mengwong/adventofcode/blob/0eaef98a90ee886b3ce9fe9ce2eb33336032deeb/apps/aoc202… |
2022-12-07 14:18:25 +0100 | <trev> | i think it works if i just put `:: [Int] ` at the end |
2022-12-07 14:18:53 +0100 | <freeside> | that works too, you can say what the type is of the desired output, and haskell will do type inference to see what the type of read has to be to give you that |
2022-12-07 14:19:03 +0100 | <trev> | :t (map read <$> lines) "1\n2" :: Int |
2022-12-07 14:19:04 +0100 | <lambdabot> | error: |
2022-12-07 14:19:04 +0100 | <lambdabot> | • Couldn't match type ‘[b0]’ with ‘Int’ |
2022-12-07 14:19:04 +0100 | <lambdabot> | Expected type: [Char] -> Int |
2022-12-07 14:19:47 +0100 | <trev> | :t (map read <$> lines) "1\n2" :: [Int] |
2022-12-07 14:19:48 +0100 | <lambdabot> | [Int] |
2022-12-07 14:20:10 +0100 | <trev> | lol how do i get it to evaluate here? |
2022-12-07 14:20:51 +0100 | <trev> | % (map read <$> lines) "1\n2" :: [Int] |
2022-12-07 14:20:51 +0100 | <yahb2> | [1,2] |
2022-12-07 14:21:03 +0100 | <trev> | i should've scrolled up cause someone else just did this |
2022-12-07 14:23:40 +0100 | causal | (~user@50.35.85.7) |
2022-12-07 14:25:42 +0100 | notzmv | (~zmv@user/notzmv) |
2022-12-07 14:26:20 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Ping timeout: 260 seconds) |
2022-12-07 14:27:01 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) |
2022-12-07 14:27:52 +0100 | zeenk | (~zeenk@2a02:2f04:a30d:4300::7fe) |
2022-12-07 14:29:32 +0100 | <merijn> | freeside: Is this inside ghci? |
2022-12-07 14:30:24 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43) |
2022-12-07 14:31:22 +0100 | <merijn> | because while that is not efficient code, it should not blow up to 24GB |
2022-12-07 14:32:06 +0100 | <kuribas> | trev: but as merijn says, better never to use read. |
2022-12-07 14:33:23 +0100 | <merijn> | oh, wait I was looking at the wrong code for the blowup |
2022-12-07 14:34:10 +0100 | <merijn> | freeside: I see at least one memory blow up in your code |
2022-12-07 14:34:37 +0100 | <merijn> | Well, potential one, anyway |
2022-12-07 14:35:05 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43) (Ping timeout: 260 seconds) |
2022-12-07 14:36:36 +0100 | <merijn> | ah, actually no. But I do see a good optimisation opportunity, this is horrible: https://github.com/mengwong/adventofcode/blob/2022/apps/aoc2019-day16.hs#L44-L48 |
2022-12-07 14:36:43 +0100 | <merijn> | V.fromList is gonna kill you |
2022-12-07 14:37:33 +0100 | <merijn> | freeside: What you want instead of that fromList is to use generate |
2022-12-07 14:37:35 +0100 | <merijn> | https://hackage.haskell.org/package/vector-0.13.0.0/docs/Data-Vector.html#v:generate |
2022-12-07 14:37:55 +0100 | <kuribas> | freeside: those strictness annotations don't look very useful. |
2022-12-07 14:38:12 +0100 | <merijn> | Since you have a fixed vector size and each element is directly generated from the index |
2022-12-07 14:38:24 +0100 | Erutuon | (~Erutuon@user/erutuon) |
2022-12-07 14:38:51 +0100 | shriekingnoise | (~shrieking@186.137.167.202) |
2022-12-07 14:39:06 +0100 | <kuribas> | freeside: also, if you want performance, don't use "(Monad m) => ..." |
2022-12-07 14:40:10 +0100 | <kuribas> | freeside: IO is already strict |
2022-12-07 14:40:25 +0100 | <merijn> | kuribas: ?? |
2022-12-07 14:40:35 +0100 | <merijn> | Not sure if that's relevant, tbh |
2022-12-07 14:40:49 +0100 | <merijn> | and also his Monad m function should trivially specialise in code this simple |
2022-12-07 14:41:15 +0100 | <merijn> | freeside: Also, you should try running this code with "+RTS -sstderr" and see what that says |
2022-12-07 14:41:17 +0100 | azimut | (~azimut@gateway/tor-sasl/azimut) (Ping timeout: 255 seconds) |
2022-12-07 14:41:48 +0100 | <kuribas> | merijn: in this case yes |
2022-12-07 14:42:17 +0100 | <kuribas> | freeside: and if you don't need lazy vectors, use unboxed vecors. |
2022-12-07 14:42:29 +0100 | <kuribas> | freeside: they will be an order of magnitude faster. |
2022-12-07 14:42:43 +0100 | <merijn> | oh, yes |
2022-12-07 14:43:08 +0100 | <merijn> | ok, so first thing to try would be: use unboxed vector + V.generate (instead of V.fromList) |
2022-12-07 14:43:13 +0100 | <merijn> | and see how much faster that is |
2022-12-07 14:43:44 +0100 | <merijn> | oh... |
2022-12-07 14:43:45 +0100 | <merijn> | also |
2022-12-07 14:43:48 +0100 | <kuribas> | merijn: "return $! toreturn" doesn't look so useful, or was that for the timing? |
2022-12-07 14:44:04 +0100 | <merijn> | you have a ghc-options field that is a billion miles long, but no -O? |
2022-12-07 14:44:14 +0100 | money_ | (~money@user/polo) (Quit: money_) |
2022-12-07 14:44:54 +0100 | <kuribas> | maybe he needs to do toreturn `seq` getPOSIXTime instead then? |
2022-12-07 14:45:59 +0100 | acidjnk_new | (~acidjnk@p200300d6e7137a66c53ce5ddc06be1e3.dip0.t-ipconnect.de) (Ping timeout: 256 seconds) |
2022-12-07 14:46:02 +0100 | <merijn> | kuribas: my comment was mostly that "IO is strict" and "$! probably does nothing there" are completely orthogonal |
2022-12-07 14:46:22 +0100 | <kuribas> | hmm, I suppose so... |
2022-12-07 14:47:13 +0100 | <merijn> | kuribas: IO is not strict in it's return values, so the fact that $! is nothing isn't really related to IO, only to the fact that "at that point the result is probably not big" |
2022-12-07 14:47:14 +0100 | <kuribas> | in any case, toreturn with lazy vec will not be deep forced by $! |
2022-12-07 14:47:30 +0100 | <kuribas> | merijn: fair enough |
2022-12-07 14:48:15 +0100 | <merijn> | I'm not even done with my own AOC for today and I'm already nerdsniped... |
2022-12-07 14:48:19 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
2022-12-07 14:49:18 +0100 | albet70 | (~xxx@2400:8902::f03c:92ff:fe60:98d8) (Remote host closed the connection) |
2022-12-07 14:50:00 +0100 | <kuribas> | yeah, I should also do my actual job, which is some rather convoluted python code. |
2022-12-07 14:51:04 +0100 | <dminuoso> | 14:08:59 merijn | Sounds like a great way to get lynched by colleagues |
2022-12-07 14:51:17 +0100 | <dminuoso> | Not necessarily, cooking local functions `Maybe a -> IO a` is a very useful thing. |
2022-12-07 14:51:33 +0100 | <merijn> | dminuoso: I was referring to "renaming Either to Exception" |
2022-12-07 14:51:36 +0100 | <dminuoso> | Ah. |
2022-12-07 14:51:52 +0100 | <kuribas> | dminuoso: I do that, but make sure to prefix them with `unsafe`. |
2022-12-07 14:52:09 +0100 | <dminuoso> | Why unsafe? |
2022-12-07 14:52:26 +0100 | <kuribas> | because it can throw an exception. |
2022-12-07 14:52:29 +0100 | <merijn> | People keep wanting to pointlessly rename things non-standard names they are conviced are "better", disregarding that you are now inventing a custom dialect of Haskell that is different from standard Haskell that everyone has to use |
2022-12-07 14:52:35 +0100 | <dminuoso> | IO already denotes the preseence of exceptions. |
2022-12-07 14:52:52 +0100 | <dminuoso> | And in fact, almost every IO action *can* produce exceptions. |
2022-12-07 14:53:02 +0100 | <merijn> | hmmm, I was trying to get baseline performance from the 2019 example |
2022-12-07 14:53:02 +0100 | <dminuoso> | Even something mundane as `putStrLn` |
2022-12-07 14:53:10 +0100 | <kuribas> | yes, one of the biggest haskell flaws |
2022-12-07 14:53:11 +0100 | <merijn> | but I'm not patient enough to wait xD |
2022-12-07 14:53:15 +0100 | <dminuoso> | Not sure about flaw, really. |
2022-12-07 14:53:43 +0100 | <dminuoso> | IO exceptions are great, especially with the extensione hiararchy of exceptions |
2022-12-07 14:53:53 +0100 | <merijn> | dminuoso: You know what would be better? |
2022-12-07 14:53:59 +0100 | <merijn> | dminuoso: Checked IO exceptions! :p |
2022-12-07 14:54:04 +0100 | <dminuoso> | merijn: Sure. |
2022-12-07 14:54:20 +0100 | <dminuoso> | If someone had a *good* way of incorporating that into the type system, Id be game for it. |
2022-12-07 14:54:45 +0100 | <dminuoso> | And by incorporating I dont mean `just enable a bunch of extensions and encode it with type families and all kinds of shenanigans`, but some kind of first class support |
2022-12-07 14:55:06 +0100 | <merijn> | dminuoso: I'm still occasionally working on a sketch for that |
2022-12-07 14:55:14 +0100 | <merijn> | and now I no longer have my thesis distracting me :p |
2022-12-07 14:55:19 +0100 | <merijn> | Just videogames :p |
2022-12-07 14:55:21 +0100 | <freeside> | kuribas: thanks, i am trying a few of your suggestions in turn |
2022-12-07 14:55:25 +0100 | albet70 | (~xxx@2400:8902::f03c:92ff:fe60:98d8) |
2022-12-07 14:55:33 +0100 | <dminuoso> | And even without checked exceptions, IO exceptions are still great. |
2022-12-07 14:56:09 +0100 | <kuribas> | dminuoso: right, those "unsafe" functions where not in IO. |
2022-12-07 14:56:12 +0100 | <freeside> | so, i tried unboxed vectors, and it ran slower, though maybe after I try a few other things, unboxed will be faster. |
2022-12-07 14:56:20 +0100 | <merijn> | freeside: I'm trying to time and memory measure your version, so I can compare improvements, but it's too slow for my patience :p |
2022-12-07 14:56:28 +0100 | <dminuoso> | kuribas: I dont use those. I tend to drag IO very deeply through programs. |
2022-12-07 14:56:32 +0100 | __monty__ | (~toonn@user/toonn) (Quit: leaving) |
2022-12-07 14:56:38 +0100 | <dminuoso> | Because as it turns out, this is very useful for getting good diagnostics. |
2022-12-07 14:56:48 +0100 | <dminuoso> | And at that point you get nice catch control |
2022-12-07 14:57:12 +0100 | <dminuoso> | And best of all - IO exceptions let you preserve MonadUnliftIO :) |
2022-12-07 14:57:22 +0100 | <freeside> | merijn: i have smaller input sets, if you'd like; i'll check them in. |
2022-12-07 14:57:25 +0100 | <merijn> | dminuoso: People always underestimate how pleasant IO heavy Haskell is :) |
2022-12-07 14:58:04 +0100 | <kuribas> | haskell is the best imperative language :) |
2022-12-07 14:58:15 +0100 | <dminuoso> | merijn: Indeed. It was GHC that actually demonstrated to me how nice it was. |
2022-12-07 14:58:23 +0100 | <dminuoso> | Given that virtuall all of GHC runs in IO |
2022-12-07 14:58:48 +0100 | <dminuoso> | (Yes it has lots of pure code, but it has a very IO centric spine) |
2022-12-07 15:00:19 +0100 | albet70 | (~xxx@2400:8902::f03c:92ff:fe60:98d8) (Remote host closed the connection) |
2022-12-07 15:01:13 +0100 | <freeside> | so, the Vec.fromList on line 45, undesirable because, why? |
2022-12-07 15:01:20 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Ping timeout: 260 seconds) |
2022-12-07 15:01:25 +0100 | troydm | (~troydm@host-176-37-124-197.b025.la.net.ua) |
2022-12-07 15:01:32 +0100 | <merijn> | freeside: dynamically building vectors of unknown length is expensive |
2022-12-07 15:01:40 +0100 | <freeside> | I can switch it to use a generate -- the genBase function on 31 is basically that already. |
2022-12-07 15:01:40 +0100 | kalj | (~kalj@78-71-20-170-no193.tbcn.telia.com) (Quit: Client closed) |
2022-12-07 15:01:54 +0100 | <merijn> | freeside: Because you keep having to reallocate and copy each time your original vector is too small |
2022-12-07 15:01:57 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) |
2022-12-07 15:02:03 +0100 | <freeside> | and then it gets the `n` out of the input by using a simple ! then |
2022-12-07 15:02:14 +0100 | <merijn> | freeside: V.generate takes a static length so it will just allocate and initialise in place once |
2022-12-07 15:02:48 +0100 | <merijn> | Allocate once + fill is always gonna be more efficient than a dynamic approach :) |
2022-12-07 15:02:57 +0100 | <merijn> | It plays nicer with fusion too |
2022-12-07 15:03:08 +0100 | o1lo01ol1o | (~o1lo01ol1@2001:8a0:6a54:cb00:897b:5682:aa16:df9e) |
2022-12-07 15:03:25 +0100 | <dminuoso> | How does Data.Vector.fromList work then? |
2022-12-07 15:04:43 +0100 | dora | (~dora@kwlan4.uoks.uj.edu.pl) (Ping timeout: 260 seconds) |
2022-12-07 15:05:01 +0100 | <dminuoso> | And shouldnt you be able to use fromListN at least, given that the length is statically known? |
2022-12-07 15:05:15 +0100 | accord | (uid568320@id-568320.hampstead.irccloud.com) |
2022-12-07 15:05:22 +0100 | <merijn> | dminuoso: Then you still end up pointlessly creating a list and stuff |
2022-12-07 15:05:33 +0100 | swamp_ | (~zmt00@user/zmt00) |
2022-12-07 15:05:44 +0100 | <dminuoso> | Fair |
2022-12-07 15:05:44 +0100 | <merijn> | And the actual function here is trivially rewritable as a function of vector index |
2022-12-07 15:06:16 +0100 | <merijn> | (since it's just a function looped over values 1 through l) |
2022-12-07 15:06:27 +0100 | albet70 | (~xxx@2400:8902::f03c:92ff:fe60:98d8) |
2022-12-07 15:06:45 +0100 | <merijn> | So just need to offset it by 1 to work of 0 based indices |
2022-12-07 15:07:30 +0100 | <dminuoso> | Okay so it seems like fromList generates a stream of basicUnsafeWrite, presumably onto a buffer of that is hopefully large enough, otherwise the sequencing will allocate new buffers? |
2022-12-07 15:07:53 +0100 | <dminuoso> | Wouldnt it be cheaper to scan the length of the list first? |
2022-12-07 15:08:04 +0100 | <merijn> | Depends how long your list is |
2022-12-07 15:08:14 +0100 | <merijn> | Also, if your list is giant and lazy that's gonna blow up |
2022-12-07 15:08:19 +0100 | <freeside> | my list has 6.5 million elements |
2022-12-07 15:08:23 +0100 | <dminuoso> | It would blow up regardless on the allocation, no> |
2022-12-07 15:08:37 +0100 | <freeside> | i was hoping that unboxed it would take 6.5 megs in ram |
2022-12-07 15:08:49 +0100 | <dminuoso> | Or is the point that the cons cell is more expensive than potentially the element size in the vector?> |
2022-12-07 15:09:08 +0100 | zmt01 | (~zmt00@user/zmt00) (Ping timeout: 246 seconds) |
2022-12-07 15:09:19 +0100 | <merijn> | dminuoso: If your vector operations fuse into a Vector.sum, then it doesn't have to |
2022-12-07 15:09:22 +0100 | <dminuoso> | Or even that seems unlikely given that Vector has boxed elements |
2022-12-07 15:09:46 +0100 | <dminuoso> | merijn: is there RULES in place to elide the vector for that? |
2022-12-07 15:10:02 +0100 | <dminuoso> | Ah I guess there must be |
2022-12-07 15:10:08 +0100 | <dminuoso> | That explains the fusion framework then |
2022-12-07 15:10:15 +0100 | <merijn> | dminuoso: That's the entire point of vector's fusion framework, no? :p |
2022-12-07 15:10:27 +0100 | <dminuoso> | Wouldnt know honestly, never looked at vector. :() |
2022-12-07 15:10:38 +0100 | <merijn> | :O |
2022-12-07 15:10:40 +0100 | <merijn> | Vector is nice |
2022-12-07 15:11:08 +0100 | <dminuoso> | Well I mean I use it regularly for some things, but never really looked at what vector was built for or how it works |
2022-12-07 15:11:26 +0100 | <merijn> | overall this solution feels slower than it, naively, should be |
2022-12-07 15:11:39 +0100 | L29Ah | (~L29Ah@wikipedia/L29Ah) |
2022-12-07 15:12:01 +0100 | <merijn> | but also, I'm not 100% sure I follow what it's doing, so... :p |
2022-12-07 15:12:03 +0100 | <dminuoso> | Okay so things are falling into place now. |
2022-12-07 15:12:04 +0100 | shapr | (~user@68.54.166.125) (Ping timeout: 260 seconds) |
2022-12-07 15:12:15 +0100 | <dminuoso> | Data.Text.pack goes through a stream framework as well |
2022-12-07 15:12:17 +0100 | <dminuoso> | Presumably for the same reason? |
2022-12-07 15:12:28 +0100 | <freeside> | sorry, i should have also shared the original problem. https://adventofcode.com/2019/day/16 |
2022-12-07 15:12:37 +0100 | <freeside> | basically, this is a matrix multiplication problem. |
2022-12-07 15:12:42 +0100 | <dminuoso> | "TEXT length/pack -> P.length" forall t. length (pack t) = P.length t |
2022-12-07 15:12:46 +0100 | <dminuoso> | Ah-ha! |
2022-12-07 15:12:59 +0100 | <dminuoso> | Libraries are suddenly starting to make sense. :) |
2022-12-07 15:13:00 +0100 | <freeside> | however, because the matrix is 6.5M x 6.5M, fitting everything into RAM is difficult. |
2022-12-07 15:13:09 +0100 | <merijn> | oh, wait, this is FFT? |
2022-12-07 15:13:21 +0100 | <freeside> | the name of the thing is FFT, but reading the question, i don't think it's FFT. |
2022-12-07 15:13:28 +0100 | <freeside> | it's closer to a repeated block cipher |
2022-12-07 15:14:00 +0100 | <merijn> | Well, one clue is that FFT has recursive sharing between the blocks of a transform |
2022-12-07 15:14:27 +0100 | <merijn> | So I think the problem might be "spot the recursive sharing of your computation" rather than trying to make the naive computation faster |
2022-12-07 15:14:44 +0100 | <merijn> | I think last year had a similar exponential blow up puzzle |
2022-12-07 15:17:07 +0100 | <merijn> | the puzzle formulation seems to also strongly hint at recursive sharing |
2022-12-07 15:17:52 +0100 | <merijn> | I haven't done that one from 2019, but last year's day 14 had an exponential blow up puzzle too and I can show you my solution for that one, maybe it'll trigger some inspiration |
2022-12-07 15:18:52 +0100 | <freeside> | i would be grateful, thank you |
2022-12-07 15:19:09 +0100 | <merijn> | freeside: https://adventofcode.com/2021/day/14 so every iteration becomes longer and longer and the intial version (10 expansions) you can solve by simply having a fast implementation, but the puzzle 2 was 40 expansions and that just runs out of memory trying to handle the full data |
2022-12-07 15:20:07 +0100 | <merijn> | freeside: https://github.com/merijn/AdventOfCode/blob/master/2021/Day14.hs |
2022-12-07 15:21:13 +0100 | freeside | looks |
2022-12-07 15:22:21 +0100 | <merijn> | freeside: The trick for that one was that "the *actual* sequence doesn't matter for what you have to insert or score" so instead of storing the actualy sequence you could just store all possible pairs with a counter of how frequently they occur and every pair produces a (predictable) number of new pairs when you expand, so instead of a billion character sequence you have a Map of pair to count mappings |
2022-12-07 15:22:28 +0100 | <merijn> | and expansion is simply "which new pairs does each original pair expand to and compute new counts for every pair in the new string") |
2022-12-07 15:22:39 +0100 | <merijn> | I expect this day 16 puzzle has a similar trick |
2022-12-07 15:22:48 +0100 | <merijn> | You just gotta find it |
2022-12-07 15:22:51 +0100 | jakalx | (~jakalx@base.jakalx.net) (Error from remote client) |
2022-12-07 15:23:38 +0100 | <merijn> | Especially since the entire thing FFT is famous for is being fast due to clever recursive sharing tricks |
2022-12-07 15:26:38 +0100 | <freeside> | gotcha. i guess i've been banging my head against a very particular wall, which is that the runtime is growing quadratically, even though the inner "go" function is running at the same time per round. |
2022-12-07 15:27:08 +0100 | <merijn> | freeside: It took me hours of trying to make my function faster before I realised that last year too |
2022-12-07 15:27:25 +0100 | <kuribas> | freeside: garbage collection? |
2022-12-07 15:27:36 +0100 | <freeside> | i force a performGC at the top of every "go" |
2022-12-07 15:27:46 +0100 | <merijn> | I actually spend *a lot* of effort on my original solution to have a clever streaming solution which was constant space |
2022-12-07 15:27:49 +0100 | <merijn> | And it actually worked |
2022-12-07 15:28:00 +0100 | <merijn> | in that I never had memory blow up, it just took forever to compute xD |
2022-12-07 15:28:07 +0100 | <merijn> | freeside: Actually, what if you don't? |
2022-12-07 15:28:07 +0100 | <freeside> | part of what i'm trying to learn here is how to take maximum advantage of fusion, and how to set up my functions so all the laziness just works |
2022-12-07 15:28:22 +0100 | <merijn> | freeside: unnecessary GC can really fuck you over :p |
2022-12-07 15:28:34 +0100 | <freeside> | hm, ok, let me try a/b testing that next. |
2022-12-07 15:29:01 +0100 | <merijn> | freeside: If you have inputs that finish in reasonable time, try that while passing "+RTS -sstderr" |
2022-12-07 15:29:03 +0100 | <freeside> | i am so glad my M1 macbook air doesn't have a fan, because if it did, it would sound like a jet engine right about now. |
2022-12-07 15:29:19 +0100 | <merijn> | (or "-- +RTS -sstderr" if you use "cabal run", else you pass the flags to cabal :p) |
2022-12-07 15:29:23 +0100 | <money> | mine never goes on |
2022-12-07 15:29:40 +0100 | <merijn> | freeside: That will report GC info and memory usage |
2022-12-07 15:30:20 +0100 | albet70 | (~xxx@2400:8902::f03c:92ff:fe60:98d8) (Remote host closed the connection) |
2022-12-07 15:30:23 +0100 | <merijn> | If you have a big live set (you probably do) GC can waste *a lot* of time |
2022-12-07 15:30:51 +0100 | <freeside> | can i just run stack --profile to get the RTS? |
2022-12-07 15:31:00 +0100 | <merijn> | --profile is different |
2022-12-07 15:31:01 +0100 | <freeside> | i've been using stack run instead of cabal |
2022-12-07 15:31:15 +0100 | <merijn> | freeside: Presumably "-- +RTS -sstderr" works with stack too |
2022-12-07 15:31:28 +0100 | <freeside> | ok, i will incant |
2022-12-07 15:31:33 +0100 | o1lo01ol1o | (~o1lo01ol1@2001:8a0:6a54:cb00:897b:5682:aa16:df9e) (Ping timeout: 260 seconds) |
2022-12-07 15:31:54 +0100 | <merijn> | You might need to compile with -rtsopts (i.e. add -rtsopts to you ghc-options) |
2022-12-07 15:34:50 +0100 | ec_ | (~ec@gateway/tor-sasl/ec) (Ping timeout: 255 seconds) |
2022-12-07 15:34:59 +0100 | elevenkb | (~elevenkb@105.184.79.224) |
2022-12-07 15:35:27 +0100 | <merijn> | freeside: The 2 main numbers you wanna be looking at in the output are: max residency (i.e. how much peak memory usage am I having) and productivity (which is |
2022-12-07 15:35:39 +0100 | <merijn> | (which is "time not spend doing GC / total time") |
2022-12-07 15:35:57 +0100 | <merijn> | Productivity below 80% is generally a red flag |
2022-12-07 15:36:27 +0100 | albet70 | (~xxx@2400:8902::f03c:92ff:fe60:98d8) |
2022-12-07 15:36:28 +0100 | <merijn> | (which is why you wanna test the performGC stuff with the GC reporting, you wanna check it's not wrecking your productivity) |
2022-12-07 15:36:34 +0100 | acidjnk_new | (~acidjnk@p200300d6e7137a767ca9aed60fa8d1f2.dip0.t-ipconnect.de) |
2022-12-07 15:37:00 +0100 | ec_ | (~ec@gateway/tor-sasl/ec) |
2022-12-07 15:37:00 +0100 | jakalx | (~jakalx@base.jakalx.net) |
2022-12-07 15:41:24 +0100 | <freeside> | currently fighting with package.yaml to get rtsopts behaving |
2022-12-07 15:41:51 +0100 | <albet70> | is (liftIO x) >> (liftIO y) == liftIO $ x >> y? |
2022-12-07 15:42:15 +0100 | festive_kurbus | (~festive_k@user/kurbus) |
2022-12-07 15:43:19 +0100 | <c_wraith> | albet70: did you check the docs? |
2022-12-07 15:43:48 +0100 | <albet70> | not yet |
2022-12-07 15:44:05 +0100 | <c_wraith> | albet70: (yes, it is. But that's something the docs say) |
2022-12-07 15:48:45 +0100 | <trev> | why does it keep telling me that `x` is a Char instead of String? https://paste.tomsmeding.com/zfwaa9wr |
2022-12-07 15:48:51 +0100 | [itchyjunk] | (~itchyjunk@user/itchyjunk/x-7353470) |
2022-12-07 15:48:55 +0100 | <albet70> | https://hackage.haskell.org/package/conduit-1.3.4.3/docs/Conduit.html#t:MonadIO |
2022-12-07 15:49:13 +0100 | <albet70> | liftIO (m >>= f) = liftIO m >>= (liftIO . f) |
2022-12-07 15:51:14 +0100 | <albet70> | c_wraith , it is >>= not >> in the docs |
2022-12-07 15:51:25 +0100 | <c_wraith> | so use your algebra |
2022-12-07 15:51:29 +0100 | <c_wraith> | it's just a bit of rewriting |
2022-12-07 15:52:17 +0100 | <c_wraith> | m >> n === m >>= \_ -> n |
2022-12-07 15:53:33 +0100 | king_gs | (~Thunderbi@187.201.204.122) |
2022-12-07 15:53:51 +0100 | <dminuoso> | trev: Because you pattern match on [x : xs], presumably you meant (x:xs) |
2022-12-07 15:54:12 +0100 | <money> | xxx |
2022-12-07 15:54:22 +0100 | dora | (~dora@rivendell.ksi.ii.uj.edu.pl) |
2022-12-07 15:54:30 +0100 | <trev> | O___O |
2022-12-07 15:54:33 +0100 | <dminuoso> | trev: [x:xs] is a deep match, matching on a list of exactly one element, and then matching that one element to a list with at least one element, binding it to `x` and the tail to `xs` |
2022-12-07 15:54:38 +0100 | <dminuoso> | Note that `type String = [Char]` |
2022-12-07 15:54:57 +0100 | <trev> | i actually tried [x:xs] and the formatter kept fixing it LOL |
2022-12-07 15:55:01 +0100 | <dminuoso> | Which is why something like `case "foo" of x:xs -> ...` will work :) |
2022-12-07 15:55:16 +0100 | <merijn> | freeside: You should be able to just edit -rtsopts into the ghc-options in your cabal file |
2022-12-07 15:55:23 +0100 | <dminuoso> | Binding `x` to 'f' and xs to "foo" |
2022-12-07 15:55:26 +0100 | <dminuoso> | "oo" I meant. |
2022-12-07 15:55:49 +0100 | <merijn> | ah, wait you're using hpack |
2022-12-07 15:56:00 +0100 | <dminuoso> | trev: iow "foo" is just syntax sugar for 'f' : 'o' : 'o' : [] |
2022-12-07 15:56:12 +0100 | <trev> | dminuoso oh man, i missed that it was a bracket and not parens |
2022-12-07 15:56:13 +0100 | <merijn> | My biased advise would be to just ditch hpack, tbh. |
2022-12-07 15:56:20 +0100 | <trev> | i've been at the computer too long.. |
2022-12-07 15:56:35 +0100 | <trev> | dminuoso thank you |
2022-12-07 15:56:37 +0100 | <freeside> | because i am using stack, for my sins, i am trying to `lift` that instruction over hpack's package.yaml |
2022-12-07 15:56:49 +0100 | <dminuoso> | freeside: You can use stack without hpack just fine. |
2022-12-07 15:57:01 +0100 | <freeside> | i will try. |
2022-12-07 15:57:53 +0100 | <dminuoso> | Im not sure why stack defaults to it anyway |
2022-12-07 15:58:03 +0100 | <dminuoso> | The .cabal file format is pretty much fine? |
2022-12-07 15:58:20 +0100 | <dminuoso> | With hpack you need to learn both the hpack syntax *and* the corresponding cabal generated code and semantics. |
2022-12-07 15:58:26 +0100 | <dminuoso> | With cabal.. just the second part. |
2022-12-07 15:58:56 +0100 | <freeside> | yar. let me come back after i have flensed package.yaml from my setup |
2022-12-07 15:59:02 +0100 | <dminuoso> | Not to mention, that you want a .cabal file anyway for non-stack users to use your code... |
2022-12-07 15:59:11 +0100 | <merijn> | freeside: Stack does not require hpack/package.yaml, it just happens to automatically invoke hpack when needed |
2022-12-07 15:59:20 +0100 | <merijn> | dminuoso: to be fair, he has a .cabal file checked in |
2022-12-07 16:00:05 +0100 | <dminuoso> | Im just saying that hpack adds more complication since you need to keep that synchronized. |
2022-12-07 16:00:17 +0100 | shapr | (~user@68.54.166.125) |
2022-12-07 16:00:32 +0100 | <merijn> | dminuoso: Yeah, I really dislike hpack and all the people arguing for "we should do cabal in YAML/json/whatever", because inevitably they like the "simple case" and then don't realise you're effectively implementing some custom stringly based format on top of that |
2022-12-07 16:00:44 +0100 | <merijn> | If you're gonna have a custom format it might as well be first class |
2022-12-07 16:00:51 +0100 | <freeside> | oh crap, something changed and now the runtimes are a lot faster, but i'm not sure what changed. one sec while i try to do too many things at once. |
2022-12-07 16:01:06 +0100 | <dminuoso> | "Do it in YAML so you dont need to learn a new format" is one of the absurdest propositions that Ive learned from Ansible long ago. |
2022-12-07 16:01:29 +0100 | Sgeo | (~Sgeo@user/sgeo) |
2022-12-07 16:01:54 +0100 | <dminuoso> | Mostly because you still need to learn a special format, because youc ant just write arbitrary YAML and expect it to make sense.. |
2022-12-07 16:01:56 +0100 | EvanR | (~EvanR@user/evanr) (Remote host closed the connection) |
2022-12-07 16:02:18 +0100 | <dminuoso> | The only difference is that the whitespace layouting rules are clear... |
2022-12-07 16:02:22 +0100 | <dminuoso> | Or uniform. |
2022-12-07 16:02:27 +0100 | EvanR | (~EvanR@user/evanr) |
2022-12-07 16:02:41 +0100 | <merijn> | dminuoso: People are still actively arguing for it on github |
2022-12-07 16:02:42 +0100 | <dminuoso> | (But then again, the whitespace rules in YAML are quite absurd) |
2022-12-07 16:02:52 +0100 | <merijn> | So please register your displeasure for the idea >.> |
2022-12-07 16:03:04 +0100 | <dminuoso> | Where on github? |
2022-12-07 16:03:56 +0100 | <merijn> | dminuoso: https://github.com/haskell/cabal/issues/8605 https://github.com/haskell/cabal/issues/7548 |
2022-12-07 16:05:06 +0100 | akegalj | (~akegalj@180-243.dsl.iskon.hr) |
2022-12-07 16:06:11 +0100 | <merijn> | obligatory "I implemented a TOML to cabal program!" that then only uses 10% of the syntax/feature of cabal files >.> |
2022-12-07 16:07:46 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Ping timeout: 256 seconds) |
2022-12-07 16:08:38 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) |
2022-12-07 16:11:00 +0100 | kenran | (~user@user/kenran) |
2022-12-07 16:12:11 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Client Quit) |
2022-12-07 16:12:58 +0100 | kenran | (~user@user/kenran) (Remote host closed the connection) |
2022-12-07 16:13:17 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) |
2022-12-07 16:21:22 +0100 | foul_owl | (~kerry@193.29.61.77) (Ping timeout: 256 seconds) |
2022-12-07 16:21:37 +0100 | festive_kurbus | (~festive_k@user/kurbus) (Quit: Client closed) |
2022-12-07 16:25:13 +0100 | king_gs | (~Thunderbi@187.201.204.122) (Ping timeout: 260 seconds) |
2022-12-07 16:28:50 +0100 | <freeside> | woohoo! i figured out RTS, and now i have output: https://github.com/mengwong/adventofcode/commit/71d6e5a83f092c58aee8126ed31a05b600c8b80d#commitcom… |
2022-12-07 16:29:22 +0100 | <freeside> | am tempted to turn on profiling and draw the heap profile using hp2ps |
2022-12-07 16:30:34 +0100 | <freeside> | 3,097,783,264 bytes maximum residency |
2022-12-07 16:30:39 +0100 | <freeside> | Productivity 1.2% of total user, 6.7% of total elapsed |
2022-12-07 16:31:22 +0100 | <freeside> | rerunning with performGC disabled |
2022-12-07 16:32:25 +0100 | <freeside> | 3,002,958,440 bytes maximum residency |
2022-12-07 16:32:30 +0100 | <freeside> | Productivity 15.6% of total user, 11.6% of total elapsed |
2022-12-07 16:32:36 +0100 | <freeside> | we must trust the garbage collector |
2022-12-07 16:34:46 +0100 | festive_kurbus | (~festive_k@user/kurbus) |
2022-12-07 16:35:45 +0100 | <freeside> | the full-size run is still taking up too much ram, though: why does it need more than 6.5M, or even with 32-bit integers, why does it need more than 26 megs of ram? |
2022-12-07 16:35:46 +0100 | <merijn> | freeside: ok, so productivity of 15% is clearly better, but still *atrocious* |
2022-12-07 16:35:50 +0100 | foul_owl | (~kerry@157.97.134.158) |
2022-12-07 16:35:56 +0100 | <merijn> | freeside: It means 85% of your runtime is GC :p |
2022-12-07 16:37:27 +0100 | <merijn> | freeside: Is that with unboxed or just as-is? |
2022-12-07 16:37:41 +0100 | <int-e> | that's quite a lot of residency. |
2022-12-07 16:38:19 +0100 | <freeside> | this is boxed |
2022-12-07 16:38:34 +0100 | <freeside> | i feel like some of the consumed data is still lingering |
2022-12-07 16:38:38 +0100 | <merijn> | freeside: boxed is gonna add *minimum* 8 bytes per item |
2022-12-07 16:38:49 +0100 | <merijn> | (extra pointer indirection) |
2022-12-07 16:39:38 +0100 | <freeside> | i will rerun unboxed |
2022-12-07 16:40:19 +0100 | <merijn> | I'm wondering if the input string is kept alive |
2022-12-07 16:40:52 +0100 | <merijn> | but that shouldn't be that expensive |
2022-12-07 16:41:08 +0100 | <freeside> | the really weird thing now is my last run hung at "answer: ", which suggests some laziness is still being resolved |
2022-12-07 16:41:21 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Quit: No Ping reply in 180 seconds.) |
2022-12-07 16:42:13 +0100 | <freeside> | running unboxed is a lot slower, but the RAM is staying under 13MB, so that's a relief. |
2022-12-07 16:42:27 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) |
2022-12-07 16:44:52 +0100 | <merijn> | Interesting |
2022-12-07 16:45:09 +0100 | <merijn> | Are you using -O or -O2 now, btw? |
2022-12-07 16:46:01 +0100 | <freeside> | er, i don't know, possibly neither? |
2022-12-07 16:46:25 +0100 | <merijn> | ah, yeah, you're not, so that's probably another thing to do :p |
2022-12-07 16:46:51 +0100 | <merijn> | Just add -O (or -O2) to ghc-options in the cabal file |
2022-12-07 16:47:10 +0100 | <merijn> | freeside: Without that the optimiser isn't enabled and especially for numeric heavy code that can matter A LOT |
2022-12-07 16:47:28 +0100 | <freeside> | anyway, now is the time to start optimizing based on the actual features of the problem, as you suggested. there are a ton of optimizations opportunities, not least of which is that most of the computations can be reduced from a multiplication to a lookup, and on top of that, most of the computations don't even need to be repeated, because half the base matrix is 0's, in a very predictable way |
2022-12-07 16:49:33 +0100 | <c_wraith> | I though cabal defaulted to -O until you specify otherwise |
2022-12-07 16:50:14 +0100 | <merijn> | c_wraith: depends on what's in your config, I guess |
2022-12-07 16:50:18 +0100 | lortabac | (~lortabac@2a01:e0a:541:b8f0:ebf5:c68c:db4f:4f95) (Quit: WeeChat 2.8) |
2022-12-07 16:50:27 +0100 | <c_wraith> | *thought |
2022-12-07 16:50:37 +0100 | <c_wraith> | anyway, default meaning "if you don't specify" |
2022-12-07 16:55:21 +0100 | <freeside> | yeah, i'm pretty sure the Boxed computations are being thunked, even though I had LANGUAGE Strict. |
2022-12-07 16:55:32 +0100 | <int-e> | oh that problem... there's a really stupid thing about it |
2022-12-07 16:56:43 +0100 | <c_wraith> | -XStrict does not prevent thunks. |
2022-12-07 16:56:46 +0100 | <c_wraith> | that's not what it's for |
2022-12-07 16:57:04 +0100 | <c_wraith> | The ghc user guide explains pretty explicitly what it does |
2022-12-07 16:57:36 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
2022-12-07 16:59:59 +0100 | <c_wraith> | As usual, I strongly recommend learning how evaluation works and writing code that explicitly evaluates what is necessary and doesn't evaluate anything else. |
2022-12-07 17:01:20 +0100 | <merijn> | -XStrict is so overhyped |
2022-12-07 17:01:22 +0100 | <c_wraith> | I've been burned so many times by libraries breaking my code with too much strict evaluation. |
2022-12-07 17:01:31 +0100 | <merijn> | There is no way to avoid thinking about strictness |
2022-12-07 17:01:39 +0100 | dsrt^ | (~dsrt@76.145.185.103) (Remote host closed the connection) |
2022-12-07 17:01:51 +0100 | <merijn> | -XStrict is not a magical solution, it just swaps the default to an (arguably) stupider one |
2022-12-07 17:02:11 +0100 | <DigitalKiwi> | ahem i avoid it by not thinking |
2022-12-07 17:03:11 +0100 | <c_wraith> | I guess core-ish libraries stopped adding incorrect strictness in patch updates about 10 years ago now, but there was an annoying period of time in there when it was common |
2022-12-07 17:05:37 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43) |
2022-12-07 17:07:05 +0100 | acidjnk_new | (~acidjnk@p200300d6e7137a767ca9aed60fa8d1f2.dip0.t-ipconnect.de) (Ping timeout: 256 seconds) |
2022-12-07 17:09:54 +0100 | festive_kurbus | (~festive_k@user/kurbus) (Quit: Client closed) |
2022-12-07 17:10:54 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
2022-12-07 17:11:18 +0100 | dora | (~dora@rivendell.ksi.ii.uj.edu.pl) (Ping timeout: 260 seconds) |
2022-12-07 17:12:23 +0100 | beteigeuze | (~Thunderbi@bl14-81-220.dsl.telepac.pt) (Ping timeout: 246 seconds) |
2022-12-07 17:12:48 +0100 | beteigeuze | (~Thunderbi@bl14-81-220.dsl.telepac.pt) |
2022-12-07 17:12:50 +0100 | festive_kurbus | (~festive_k@user/kurbus) |
2022-12-07 17:15:09 +0100 | tomku | (~tomku@user/tomku) (Ping timeout: 260 seconds) |
2022-12-07 17:21:17 +0100 | MajorBiscuit | (~MajorBisc@c-001-003-046.client.tudelft.eduvpn.nl) (Quit: WeeChat 3.6) |
2022-12-07 17:28:40 +0100 | zeenk | (~zeenk@2a02:2f04:a30d:4300::7fe) (Quit: Konversation terminated!) |
2022-12-07 17:29:29 +0100 | <maerwald> | I work in a strict Haskell dialect, so not sure I agree |
2022-12-07 17:36:38 +0100 | tomku | (~tomku@user/tomku) |
2022-12-07 17:37:39 +0100 | alexiscott | (~user@4.red-83-36-45.dynamicip.rima-tde.net) (Ping timeout: 268 seconds) |
2022-12-07 17:37:52 +0100 | nschoe | (~q@141.101.51.197) (Ping timeout: 256 seconds) |
2022-12-07 17:39:55 +0100 | fserucas | (~fserucas@laubervilliers-657-1-66-228.w90-63.abo.wanadoo.fr) (Ping timeout: 252 seconds) |
2022-12-07 17:41:48 +0100 | bobbingbob | (~dfadsva@2604:3d09:207f:f650::7b3a) |
2022-12-07 17:43:56 +0100 | euandreh | (~Thunderbi@179.214.113.107) (Quit: euandreh) |
2022-12-07 17:47:02 +0100 | Lycurgus | (~juan@user/Lycurgus) |
2022-12-07 17:49:50 +0100 | califax | (~califax@user/califx) (Ping timeout: 255 seconds) |
2022-12-07 17:49:57 +0100 | califax_ | (~califax@user/califx) |
2022-12-07 17:51:10 +0100 | califax_ | califax |
2022-12-07 17:53:09 +0100 | Topsi | (~Topsi@217.64.164.1) (Quit: Client closed) |
2022-12-07 17:54:58 +0100 | <bobbingbob> | im interested in Data.Sum but don't really understand it. Any willing to point to or give an explanation? |
2022-12-07 17:55:30 +0100 | <bobbingbob> | i want to try it out for a extensible widget system for my gui. Does this sound like a reasonable application? |
2022-12-07 17:56:47 +0100 | Xeroine | (~Xeroine@user/xeroine) (Ping timeout: 260 seconds) |
2022-12-07 17:58:47 +0100 | Xeroine | (~Xeroine@user/xeroine) |
2022-12-07 18:02:56 +0100 | michalz | (~michalz@185.246.204.75) (Remote host closed the connection) |
2022-12-07 18:05:53 +0100 | econo | (uid147250@user/econo) |
2022-12-07 18:05:56 +0100 | CiaoSen | (~Jura@p200300c95747e0002a3a4dfffe84dbd5.dip0.t-ipconnect.de) (Ping timeout: 246 seconds) |
2022-12-07 18:06:22 +0100 | michalz | (~michalz@185.246.204.77) |
2022-12-07 18:07:04 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43) (Remote host closed the connection) |
2022-12-07 18:07:08 +0100 | <merijn> | What is Data.Sum? |
2022-12-07 18:07:44 +0100 | opticblast | (~Thunderbi@secure-165.caltech.edu) |
2022-12-07 18:08:35 +0100 | festive_kurbus | (~festive_k@user/kurbus) (Quit: Client closed) |
2022-12-07 18:08:41 +0100 | <bobbingbob> | so you know the open union type stuff in oleg's effect stuff? this is that part by itself |
2022-12-07 18:09:14 +0100 | <bobbingbob> | im wondering if it could be used for a hetergenous collection |
2022-12-07 18:09:35 +0100 | <bobbingbob> | or maybe im wildy misunderstanding things |
2022-12-07 18:09:40 +0100 | <[exa]> | bobbingbob: you meant Data.Functor.Sum ? |
2022-12-07 18:10:22 +0100 | <bobbingbob> | [exa]: i mean the package fastsum |
2022-12-07 18:10:45 +0100 | <[exa]> | ah |
2022-12-07 18:10:56 +0100 | Guest|56 | (~Guest|56@ip241-94-176-143.adsl2.static.versatel.nl) |
2022-12-07 18:11:38 +0100 | Guest|56 | (~Guest|56@ip241-94-176-143.adsl2.static.versatel.nl) (Client Quit) |
2022-12-07 18:13:20 +0100 | <bobbingbob> | i going to reread the effects paper. i vaguely understood the early portions. i think i will do my own mock implementation |
2022-12-07 18:13:43 +0100 | <[exa]> | bobbingbob: the Sum is created to make types that have a list of various properties typically with no particular order. You don't need that even remotely for doing heterogeneous collections |
2022-12-07 18:14:24 +0100 | Lycurgus | (~juan@user/Lycurgus) (Quit: Exeunt https://tinyurl.com/4m8d4kd5) |
2022-12-07 18:14:29 +0100 | <bobbingbob> | ok so i would do better with GADTs |
2022-12-07 18:14:38 +0100 | <[exa]> | re "various properties" you might think of "may satisfy many Constraints" |
2022-12-07 18:14:49 +0100 | <[exa]> | do you know how `mtl` or `transformers` work? |
2022-12-07 18:14:59 +0100 | <bobbingbob> | not in depth |
2022-12-07 18:14:59 +0100 | accord | (uid568320@id-568320.hampstead.irccloud.com) (Quit: Connection closed for inactivity) |
2022-12-07 18:15:30 +0100 | <bobbingbob> | there is a simple monad stack in repa-V4l2 that i looked at |
2022-12-07 18:15:50 +0100 | <bobbingbob> | i understand the lifting |
2022-12-07 18:16:27 +0100 | <bobbingbob> | i will look for some papers on monad transformers |
2022-12-07 18:16:34 +0100 | bgs | (~bgs@212-85-160-171.dynamic.telemach.net) (Remote host closed the connection) |
2022-12-07 18:16:36 +0100 | <[exa]> | one use of this is (VERY ROUGLY) to write something like `MagicEffectMonad [HasState x, HasReader y, HasIO, ...] a` instead of `StateT x (ReaderT y (.... IO )) a` |
2022-12-07 18:18:27 +0100 | <[exa]> | a typical problem with monad transformers is that they unwrap (are interpreted) by layers which may be impractical, interpretation of this kind of extensible effects is ... impractical differently. :D |
2022-12-07 18:19:58 +0100 | <Hecate> | bgamari: you should show Andres Löh this, he would love it for his workshops: https://social.treehouse.systems/@armael/109473361778060633 |
2022-12-07 18:21:03 +0100 | <Hecate> | ah silly me, he's kosmikus |
2022-12-07 18:22:06 +0100 | <bgamari[m]> | Hecate: indeed |
2022-12-07 18:22:56 +0100 | <bgamari[m]> | Hecate: do you know about https://hackage.haskell.org/package/ghc-heap-view |
2022-12-07 18:23:12 +0100 | phill96 | (~phill@2600:8807:8100:1e:fddd:78c0:9f78:c96f) |
2022-12-07 18:23:22 +0100 | Tuplanolla | (~Tuplanoll@91-159-68-152.elisa-laajakaista.fi) |
2022-12-07 18:23:22 +0100 | phill96 | ph_l |
2022-12-07 18:24:20 +0100 | ubert1 | (~Thunderbi@2a02:8109:abc0:6434:3dae:2edc:412:e26e) (Ping timeout: 256 seconds) |
2022-12-07 18:24:24 +0100 | festive_kurbus | (~festive_k@user/kurbus) |
2022-12-07 18:29:19 +0100 | razetime | (~quassel@49.207.203.213) (Quit: https://quassel-irc.org - Chat comfortably. Anywhere.) |
2022-12-07 18:29:51 +0100 | razetime | (~quassel@49.207.203.213) |
2022-12-07 18:33:51 +0100 | mestre | (~mestre@191.177.185.178) |
2022-12-07 18:34:59 +0100 | <fendor[m]> | can data families only be used with fully saturated type constructors? I want to have `data family Scope f`, where the kind of `f` is `Type -> Type -> Type` |
2022-12-07 18:35:14 +0100 | <fendor[m]> | actually just `Type -> Type`, but same thing |
2022-12-07 18:37:56 +0100 | <fendor[m]> | ah, that seems to require an explicit kind signature |
2022-12-07 18:38:49 +0100 | <fendor[m]> | a stand alone kind signature to be precise. |
2022-12-07 18:45:12 +0100 | festive_kurbus | (~festive_k@user/kurbus) (Quit: Client closed) |
2022-12-07 18:46:15 +0100 | festive_kurbus | (~festive_k@user/kurbus) |
2022-12-07 18:48:23 +0100 | razetime | (~quassel@49.207.203.213) (Quit: https://quassel-irc.org - Chat comfortably. Anywhere.) |
2022-12-07 18:49:52 +0100 | notzmv | (~zmv@user/notzmv) (Ping timeout: 265 seconds) |
2022-12-07 18:50:42 +0100 | kuribas | (~user@ptr-17d51eo0qm84xeejuqw.18120a2.ip6.access.telenet.be) (Quit: ERC (IRC client for Emacs 27.1)) |
2022-12-07 18:50:47 +0100 | son0p | (~ff@2604:3d08:5b7f:5540::a58f) (Ping timeout: 256 seconds) |
2022-12-07 18:51:35 +0100 | jakalx | (~jakalx@base.jakalx.net) (Error from remote client) |
2022-12-07 18:52:02 +0100 | wootehfoot | (~wootehfoo@user/wootehfoot) |
2022-12-07 18:52:27 +0100 | <merijn> | man...megaparsec used to be so easy, why did the docs become such a mess :\ |
2022-12-07 18:53:20 +0100 | <merijn> | Can't even find out how to parse a word |
2022-12-07 18:58:18 +0100 | azimut | (~azimut@gateway/tor-sasl/azimut) |
2022-12-07 18:58:34 +0100 | jakalx | (~jakalx@base.jakalx.net) |
2022-12-07 19:05:15 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43) |
2022-12-07 19:09:08 +0100 | ph_l | (~phill@2600:8807:8100:1e:fddd:78c0:9f78:c96f) (Ping timeout: 260 seconds) |
2022-12-07 19:11:10 +0100 | mbuf | (~Shakthi@49.204.118.69) (Quit: Leaving) |
2022-12-07 19:13:17 +0100 | <sm> | merijn: I think it's when it outsourced generic combinators to another package |
2022-12-07 19:13:41 +0100 | <merijn> | sm: That's not a generic combinator, though |
2022-12-07 19:14:01 +0100 | <merijn> | But it turns out takeWhileP is what I wanted, but couldn't find |
2022-12-07 19:15:46 +0100 | manwithluck | (~manwithlu@194.177.28.176) (Remote host closed the connection) |
2022-12-07 19:15:47 +0100 | stiell | (~stiell@gateway/tor-sasl/stiell) (Ping timeout: 255 seconds) |
2022-12-07 19:16:21 +0100 | chele | (~chele@user/chele) (Quit: Leaving) |
2022-12-07 19:16:29 +0100 | <sm> | megaparsec's docs are above average, but there's always room for improvement I guess |
2022-12-07 19:17:41 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43) (Remote host closed the connection) |
2022-12-07 19:17:54 +0100 | <sm> | would some letterChar have worked ? |
2022-12-07 19:18:23 +0100 | akegalj | (~akegalj@180-243.dsl.iskon.hr) (Ping timeout: 246 seconds) |
2022-12-07 19:18:46 +0100 | stiell | (~stiell@gateway/tor-sasl/stiell) |
2022-12-07 19:19:48 +0100 | elevenkb | (~elevenkb@105.184.79.224) (Quit: Client closed) |
2022-12-07 19:22:15 +0100 | <tomsmeding> | 11:35 <dminuoso> Not sure why weechat does occacsionally print `- - - - - - ...` |
2022-12-07 19:22:43 +0100 | <tomsmeding> | that's definitely the last-position-before-switch marker, i.e. you've "seen" the messages until there before you switched away from the buffer |
2022-12-07 19:23:03 +0100 | <tomsmeding> | not sure how this mechanic works if you have multiple buffers on screen, but with one full-screen buffer it's very predictable |
2022-12-07 19:25:00 +0100 | pavonia | (~user@user/siracusa) (Quit: Bye!) |
2022-12-07 19:29:32 +0100 | o1lo01ol1o | (~o1lo01ol1@2001:8a0:6a54:cb00:4d39:d844:8601:6cb2) |
2022-12-07 19:29:38 +0100 | <o1lo01ol1o> | I have an hspec test in a suite that fails when run in cabal test but which passes in ghci. Are there any resources for what may be going on? |
2022-12-07 19:29:53 +0100 | festive_kurbus | (~festive_k@user/kurbus) (Quit: Client closed) |
2022-12-07 19:30:20 +0100 | coot | (~coot@213.134.171.3) (Quit: coot) |
2022-12-07 19:30:51 +0100 | <o1lo01ol1o> | what's wierd is that it doesn't provide an error, it looks like a forked process died. But i'm not running in parallel and the test is pure, so i don't know why that would be. |
2022-12-07 19:33:57 +0100 | <Chai-T-Rex> | Are there any recommended VS Code extensions for programming in Haskell? |
2022-12-07 19:34:51 +0100 | <sm> | Haskell |
2022-12-07 19:35:35 +0100 | beteigeuze | (~Thunderbi@bl14-81-220.dsl.telepac.pt) (Ping timeout: 264 seconds) |
2022-12-07 19:36:48 +0100 | <sm> | o1lo01ol1o: ghci runs in a different mode than compiled code. Are there threads involved, eg ? |
2022-12-07 19:37:21 +0100 | <o1lo01ol1o> | sm: there are no threads involved. it's a JSON round-trip test |
2022-12-07 19:37:55 +0100 | <sm> | is it pure haskell, or calling out to a C lib ? |
2022-12-07 19:38:00 +0100 | <o1lo01ol1o> | pure haskell |
2022-12-07 19:38:31 +0100 | <o1lo01ol1o> | it's literally serializing a recurisve datatype using Aeson and deserializing it again |
2022-12-07 19:38:48 +0100 | <sm> | mystery.. remove bits until it works I guess |
2022-12-07 19:39:28 +0100 | <o1lo01ol1o> | but it's already fairly minimal, the current test has like 15 terms. |
2022-12-07 19:39:45 +0100 | <o1lo01ol1o> | it works without a hitch in ghci |
2022-12-07 19:40:24 +0100 | eggplantade | (~Eggplanta@104-55-37-220.lightspeed.sntcca.sbcglobal.net) |
2022-12-07 19:40:55 +0100 | <sm> | nevertheless.. my Excellent Debugging Technique Of Success is guaranteed! |
2022-12-07 19:41:11 +0100 | son0p | (~ff@s0106f88b37df247a.vn.shawcable.net) |
2022-12-07 19:41:18 +0100 | <o1lo01ol1o> | sm: :plus 1" |
2022-12-07 19:41:37 +0100 | <mauke> | strace -f |
2022-12-07 19:42:02 +0100 | sm | sucks in breath sharply... a challenger! |
2022-12-07 19:42:12 +0100 | <sm> | it is powerful! |
2022-12-07 19:43:19 +0100 | <sm> | and I guess the same package versions are being used in both cases |
2022-12-07 19:43:56 +0100 | <o1lo01ol1o> | sm: it's in nix, everything is pinned |
2022-12-07 19:44:36 +0100 | haritz | (~hrtz@82-69-11-11.dsl.in-addr.zen.co.uk) |
2022-12-07 19:44:37 +0100 | haritz | (~hrtz@82-69-11-11.dsl.in-addr.zen.co.uk) (Changing host) |
2022-12-07 19:44:37 +0100 | haritz | (~hrtz@user/haritz) |
2022-12-07 19:44:38 +0100 | <sm> | sure, but... are you running ghci via cabal repl ? |
2022-12-07 19:44:44 +0100 | <o1lo01ol1o> | yes |
2022-12-07 19:45:09 +0100 | <sm> | cool, cool |
2022-12-07 19:47:30 +0100 | gurkenglas | (~gurkengla@p548ac72e.dip0.t-ipconnect.de) |
2022-12-07 19:48:17 +0100 | beteigeuze | (~Thunderbi@bl14-81-220.dsl.telepac.pt) |
2022-12-07 19:48:37 +0100 | jle`` | (~jusle@user/jle/x-3894663) (Quit: WeeChat 3.6) |
2022-12-07 19:50:24 +0100 | manwithluck | (~manwithlu@194.177.28.176) |
2022-12-07 19:52:44 +0100 | beteigeuze | (~Thunderbi@bl14-81-220.dsl.telepac.pt) (Ping timeout: 256 seconds) |
2022-12-07 19:54:41 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
2022-12-07 19:55:13 +0100 | festive_kurbus | (~festive_k@user/kurbus) |
2022-12-07 19:59:52 +0100 | raehik | (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net) (Ping timeout: 252 seconds) |
2022-12-07 20:01:24 +0100 | zant1 | (~zant@62.96.232.178) (Ping timeout: 260 seconds) |
2022-12-07 20:03:24 +0100 | tomokojun | (~tomokojun@static-198-54-134-86.cust.tzulo.com) |
2022-12-07 20:03:40 +0100 | tzh | (~tzh@c-24-21-73-154.hsd1.or.comcast.net) |
2022-12-07 20:03:56 +0100 | king_gs | (~Thunderbi@187.201.204.122) |
2022-12-07 20:05:43 +0100 | o1lo01ol1o | (~o1lo01ol1@2001:8a0:6a54:cb00:4d39:d844:8601:6cb2) (Ping timeout: 260 seconds) |
2022-12-07 20:08:25 +0100 | <Chai-T-Rex> | sm: Thanks. |
2022-12-07 20:12:30 +0100 | Guest75 | (Guest75@2a01:7e01::f03c:92ff:fe5d:7b18) |
2022-12-07 20:13:41 +0100 | <Guest75> | Hello! I have my home machine (where it works ok), but on the server where I build the project this: https://github.com/andrewboltachev/pyparts/blob/master/app/Main.hs#L42 |
2022-12-07 20:13:55 +0100 | <Guest75> | is giving "Perhaps this statement should be within a 'do' block?" error |
2022-12-07 20:13:59 +0100 | <gurkenglas> | [Leary]: nope! but it's close in spirit |
2022-12-07 20:14:11 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
2022-12-07 20:14:17 +0100 | <Guest75> | what versions (ghci etc) or whitespace settings should I check in order for it to work? |
2022-12-07 20:15:44 +0100 | acidjnk_new | (~acidjnk@p200300d6e7137a767ca9aed60fa8d1f2.dip0.t-ipconnect.de) |
2022-12-07 20:18:28 +0100 | <Guest75> | UPD: sorry, "stack build" command doesn't work on local machine either |
2022-12-07 20:19:51 +0100 | <dminuoso> | tomsmeding: Things you learn. Mmm |
2022-12-07 20:19:52 +0100 | <Guest75> | fixed ws and it works. |
2022-12-07 20:20:28 +0100 | <dminuoso> | Guest75: By the way, the marked line has some very quirky parenthesis style. |
2022-12-07 20:20:49 +0100 | <dminuoso> | Consider writing `(m2e "JSON root element must be a map") $ asKeyMap b` as: m2e "JSON root element must be a map" (asKeyMap b) |
2022-12-07 20:21:47 +0100 | <Guest75> | yes, such caveats are what I'm always afraid of |
2022-12-07 20:22:11 +0100 | king_gs | (~Thunderbi@187.201.204.122) (Ping timeout: 265 seconds) |
2022-12-07 20:22:48 +0100 | <dminuoso> | There's a great way to avoid many of the quirky ways: Just avoid using $ entirely. The few commonly agreed upon legit uses have disappeared with -XBlockArguments, the others are situational and probably better done with parenthesis and/or function composition instead. |
2022-12-07 20:23:28 +0100 | Guest75 | (Guest75@2a01:7e01::f03c:92ff:fe5d:7b18) (Quit: Client closed) |
2022-12-07 20:24:10 +0100 | Guest75 | (~Guest75@192.46.237.51) |
2022-12-07 20:24:13 +0100 | <Guest75> | Will <$> and <*> also disappear? |
2022-12-07 20:24:42 +0100 | doyougnu | (~doyougnu@cpe-74-69-132-225.stny.res.rr.com) |
2022-12-07 20:24:50 +0100 | <Guest75> | Not sure if <*> has prefix version though |
2022-12-07 20:24:56 +0100 | <dsal> | Someone at work has being using `do` in place of `$` and it just looks irrationally offensive to me. |
2022-12-07 20:25:04 +0100 | <dsal> | :t ap |
2022-12-07 20:25:05 +0100 | <lambdabot> | Monad m => m (a -> b) -> m a -> m b |
2022-12-07 20:25:19 +0100 | crazazy | (~user@130.89.171.62) |
2022-12-07 20:26:06 +0100 | [exa] | foresees -XBlockDollar |
2022-12-07 20:26:10 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 256 seconds) |
2022-12-07 20:26:19 +0100 | <Guest75> | ah yes, ap |
2022-12-07 20:26:20 +0100 | <Guest75> | lol |
2022-12-07 20:26:43 +0100 | <dsal> | Hopefully we can still use ¢ |
2022-12-07 20:30:46 +0100 | <romes[m]> | I was reading on custom memory allocators and was now wondering whether GHC's RTS could benefit from them |
2022-12-07 20:31:17 +0100 | <romes[m]> | As in "malloc and free are very slow operations so we should create our own custom memory allocator" :) |
2022-12-07 20:31:27 +0100 | <romes[m]> | Wondering if anyone's thought about those things |
2022-12-07 20:31:33 +0100 | <c_wraith> | dminuoso: don't make me use lambdas instead of right sections of $ |
2022-12-07 20:31:46 +0100 | troydm | (~troydm@host-176-37-124-197.b025.la.net.ua) (Ping timeout: 252 seconds) |
2022-12-07 20:32:05 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Ping timeout: 260 seconds) |
2022-12-07 20:32:21 +0100 | <romes[m]> | > "Keep heap allocations to a minimum, and never allocate from the heap within a tight loop." |
2022-12-07 20:32:23 +0100 | <lambdabot> | "Keep heap allocations to a minimum, and never allocate from the heap within... |
2022-12-07 20:32:23 +0100 | <c_wraith> | romes[m]: why do you think GHC uses malloc and free? |
2022-12-07 20:33:24 +0100 | <dsal> | Functional programming languages are garbage producers. |
2022-12-07 20:33:36 +0100 | <romes[m]> | c_wraith: I was grepping for it. From what I got, all memory allocations are done through stgMalloc with the exception of some three uses in fs.c |
2022-12-07 20:33:41 +0100 | <romes[m]> | stgMalloc wraps malloc |
2022-12-07 20:33:46 +0100 | <festive_kurbus> | dsal: they're not gonna like that one |
2022-12-07 20:33:51 +0100 | <geekosaur> | you got wrong |
2022-12-07 20:34:32 +0100 | <mauke> | all memory allocations are done through malloc if you grep -i malloc |
2022-12-07 20:34:40 +0100 | <dminuoso> | c_wraith: Heh. |
2022-12-07 20:34:49 +0100 | irrgit__ | (~irrgit@86.106.90.226) (Read error: Connection reset by peer) |
2022-12-07 20:35:08 +0100 | <romes[m]> | maybe I'm searching in the wrong place (rts/) |
2022-12-07 20:35:14 +0100 | son0p | (~ff@s0106f88b37df247a.vn.shawcable.net) (Ping timeout: 256 seconds) |
2022-12-07 20:35:45 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
2022-12-07 20:36:17 +0100 | <geekosaur> | since ghc7ish ghc has been using a 2-stage page-based allocator on 64 bit platforms |
2022-12-07 20:36:54 +0100 | <romes[m]> | Cool! |
2022-12-07 20:36:57 +0100 | <romes[m]> | (note: I was really just asking if it's been thought of, not affirming it's not) |
2022-12-07 20:37:30 +0100 | <dminuoso> | https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/rts/storage |
2022-12-07 20:37:32 +0100 | <dminuoso> | https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/rts/storage/block-alloc |
2022-12-07 20:37:38 +0100 | <dminuoso> | These may be of interest to you |
2022-12-07 20:37:48 +0100 | <romes[m]> | Reading... Thanks! |
2022-12-07 20:38:23 +0100 | <dsal> | dtrace and similar are pretty good for answering these kinds of questions. You can observe all the calls to malloc when deciding how much it will improve things. |
2022-12-07 20:38:47 +0100 | <gurkenglas> | Control.Exception uses its isDoesNotExistError example two times, but doesn't actually export isDoesNotExistError? :( |
2022-12-07 20:39:06 +0100 | festive_kurbus | (~festive_k@user/kurbus) (Quit: Client closed) |
2022-12-07 20:39:09 +0100 | <dminuoso> | tomsmeding: Take note that the wiki articles, the ones linked in particular, contain links to relevant source files at the top. |
2022-12-07 20:39:16 +0100 | <mauke> | :t isDoesNotExistError |
2022-12-07 20:39:17 +0100 | <lambdabot> | error: |
2022-12-07 20:39:17 +0100 | <lambdabot> | Variable not in scope: isDoesNotExistError |
2022-12-07 20:39:43 +0100 | <gurkenglas> | mauke, I regret to inform you that this identifier |
2022-12-07 20:39:46 +0100 | <gurkenglas> | doesn't exist |
2022-12-07 20:39:57 +0100 | <dminuoso> | gurkenglas: It's from System.IO.Error |
2022-12-07 20:40:02 +0100 | <mauke> | YEEAAAAHHH |
2022-12-07 20:40:32 +0100 | <gurkenglas> | oh, silly of me |
2022-12-07 20:42:10 +0100 | <dminuoso> | Control.Exception is just the generic exception interface, with System.IO.Error defining IOError and relating utilities. |
2022-12-07 20:42:53 +0100 | <gurkenglas> | typecheck: "Perhaps you want to add ‘SomeException’ to the import list in the import of ‘Control.Exception’" |
2022-12-07 20:42:55 +0100 | Erutuon | (~Erutuon@user/erutuon) (Ping timeout: 260 seconds) |
2022-12-07 20:42:56 +0100 | irrgit_ | (~irrgit@176.113.74.74) |
2022-12-07 20:42:57 +0100 | <gurkenglas> | hls: "No quick fixes available" |
2022-12-07 20:44:21 +0100 | festive_kurbus | (~festive_k@user/kurbus) |
2022-12-07 20:44:23 +0100 | sammelweis | (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) |
2022-12-07 20:45:09 +0100 | <gurkenglas> | how come doesNotExistError is identified at runtime instead of on the type level :( |
2022-12-07 20:45:50 +0100 | <festive_kurbus> | because skill issue |
2022-12-07 20:46:14 +0100 | <dminuoso> | You could in principle do it with catch, but that would require extending the hierarchy |
2022-12-07 20:46:31 +0100 | <geekosaur[m]> | Because sane people write type level programs in Idris, not Haskell |
2022-12-07 20:47:24 +0100 | Erutuon | (~Erutuon@user/erutuon) |
2022-12-07 20:47:32 +0100 | <mauke> | inb4 type-level catch |
2022-12-07 20:47:35 +0100 | <dminuoso> | gurkenglas: Besides, IOException is a conceptual mapping to the standard errno error codes. |
2022-12-07 20:47:51 +0100 | <dminuoso> | (Or the errno interface in general) |
2022-12-07 20:48:01 +0100 | avicenzi | (~avicenzi@2a00:ca8:a1f:b004::c32) (Ping timeout: 252 seconds) |
2022-12-07 20:48:02 +0100 | <dminuoso> | It's very low level and simple, probably for historic reasons. |
2022-12-07 20:48:18 +0100 | <gurkenglas> | dminuoso: the problem with moving the "there are n values per type" to "there are n types with one value each" is something to do with Haskell's superclass system? |
2022-12-07 20:48:43 +0100 | <dminuoso> | gurkenglas: well we can do the latter in exceptions actually |
2022-12-07 20:48:46 +0100 | <dminuoso> | with full subtyping. |
2022-12-07 20:48:54 +0100 | <dminuoso> | but it doesnt work with superclasses |
2022-12-07 20:49:05 +0100 | <dminuoso> | https://simonmar.github.io/bib/papers/ext-exceptions.pdf |
2022-12-07 20:49:25 +0100 | <dminuoso> | It's a wonderful mechanism that GHC uses to some extend, but is widely underappreciated. |
2022-12-07 20:49:41 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
2022-12-07 20:50:02 +0100 | <dminuoso> | Think of it as java-style exceptions, with being able to catch a parent or child exception type (except they are not checked) |
2022-12-07 20:51:39 +0100 | <dminuoso> | It's just that for one reason or another the IOException sub-exceptions do not use this mechanism. |
2022-12-07 20:52:08 +0100 | coot | (~coot@2a02:a310:e241:1b00:ec1a:e9df:79ac:66ba) |
2022-12-07 20:52:15 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) |
2022-12-07 20:52:38 +0100 | <gurkenglas> | How do I make goto definition work on definitions imported from libraries in hls? |
2022-12-07 20:52:48 +0100 | <dminuoso> | You could easily just make `DoesNotExistError`, `AlreadyInUseError`, etc and tie them into the hierarchy, such that catching `IOException` will still get them all, but you can directly just catch IOException (without having to use a predicate like isDoesNotExistError and rethrowing) |
2022-12-07 20:53:18 +0100 | mestre | (~mestre@191.177.185.178) (Quit: Lost terminal) |
2022-12-07 20:54:37 +0100 | <dminuoso> | The main difficulty would be just migrating codebases that directly build an IOException from hand, which probably happens outside GHC/base/haskell libraries as well. |
2022-12-07 20:55:05 +0100 | mauke | discovers BlockArguments, falls in love |
2022-12-07 20:55:37 +0100 | <gurkenglas> | are there plans to let any such API changes come with a codebase migrator? |
2022-12-07 20:56:14 +0100 | doyougnu | (~doyougnu@cpe-74-69-132-225.stny.res.rr.com) (Ping timeout: 260 seconds) |
2022-12-07 20:56:16 +0100 | <dminuoso> | No. Mostly its just some written notes in the gitlab wiki, and deprecation warnings (that people barely read because nobody enables -Wcompat) |
2022-12-07 20:56:33 +0100 | beteigeuze | (~Thunderbi@a79-169-109-107.cpe.netcabo.pt) |
2022-12-07 20:56:38 +0100 | <dminuoso> | Things will then break after the long grace periods that we grant, frustrating users... |
2022-12-07 20:57:32 +0100 | beteigeuze | (~Thunderbi@a79-169-109-107.cpe.netcabo.pt) (Client Quit) |
2022-12-07 20:58:00 +0100 | <gurkenglas> | I guess that'll come with the automated coder revolution one of these years, then |
2022-12-07 20:58:25 +0100 | shapr | (~user@68.54.166.125) (Remote host closed the connection) |
2022-12-07 21:09:17 +0100 | jmdaemon | (~jmdaemon@user/jmdaemon) |
2022-12-07 21:11:33 +0100 | son0p | (~ff@S0106f88b37df247a.vn.shawcable.net) |
2022-12-07 21:12:20 +0100 | stiell | (~stiell@gateway/tor-sasl/stiell) (Ping timeout: 255 seconds) |
2022-12-07 21:12:46 +0100 | trev | (~trev@user/trev) (Remote host closed the connection) |
2022-12-07 21:12:49 +0100 | <monochrom> | IOError got its isFooError predicates from Haskell 98 long long before we thought up the Control.Exception idea. Kind of "the ship has sailed" by then, too late to change. |
2022-12-07 21:15:34 +0100 | tremon | (~tremon@83-84-18-241.cable.dynamic.v4.ziggo.nl) |
2022-12-07 21:16:50 +0100 | <gurkenglas> | In hls, when I mouseover "else" I get a type annotation. How do I get a type annotation for an arbitrary term I selected? Mousing over it gets me an annotation for whichever word I'm hovering over. |
2022-12-07 21:17:19 +0100 | <dminuoso> | That depends on your editor and its lsp integration. |
2022-12-07 21:17:31 +0100 | <dminuoso> | hls will respond to whatever the lsp client will ask it |
2022-12-07 21:17:53 +0100 | <dminuoso> | though `else` is not a valid expression |
2022-12-07 21:18:01 +0100 | <dminuoso> | So that's definitely a curious example |
2022-12-07 21:18:14 +0100 | <dminuoso> | (Perhaps HLS has some kind of heuristic for this?) |
2022-12-07 21:18:26 +0100 | <gurkenglas> | else was my example because it's not a valid expression so hls knows to give a type for the entire if-then-else block |
2022-12-07 21:19:41 +0100 | <monochrom> | The most obvious thing to try is drag-selecting a subexpression. |
2022-12-07 21:19:45 +0100 | <dminuoso> | Im guessing HLS will go up in the CST until it finds a full expression? |
2022-12-07 21:20:17 +0100 | <dminuoso> | Which if you do what monochrom suggested wouldnt happen, since the selected region would already be an expression |
2022-12-07 21:20:22 +0100 | <monochrom> | But if that doesn't do it, then it's also pretty obvious that either there is no way or there is a way but it's so obscure you won't want to know. |
2022-12-07 21:20:36 +0100 | <gurkenglas> | tried drag-selecting. it's vscode |
2022-12-07 21:21:37 +0100 | <monochrom> | I'm a defeatist and I enjoy the bliss of not using hls at all so I won't have to worry about expecting perfection and getting disappointed. |
2022-12-07 21:22:28 +0100 | <festive_kurbus> | moom #haskell devolved into nihilism again |
2022-12-07 21:22:49 +0100 | <monochrom> | A very humble emacs haskell-mode already does (with help from ghci integration) drag-select subexpr for type. dante does too. |
2022-12-07 21:23:26 +0100 | <dminuoso> | "with help from ghci integration", the standard haskell-mode does not do that. |
2022-12-07 21:23:33 +0100 | <dminuoso> | What are you using? |
2022-12-07 21:23:52 +0100 | <monochrom> | OK, drag-select plus a hotkey, and the hotkey is not bound by default, I had to add one clause in my .emacs, but the feature exists. |
2022-12-07 21:23:54 +0100 | <gurkenglas> | https://marketplace.visualstudio.com/items?itemName=haskell.haskell |
2022-12-07 21:24:07 +0100 | <monochrom> | The standard haskell-mode. It does. |
2022-12-07 21:24:56 +0100 | <dminuoso> | Oh it does?> |
2022-12-07 21:25:40 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 252 seconds) |
2022-12-07 21:25:45 +0100 | <monochrom> | ghci has a "what's the type of the thing from line x column y to line z column t" command. Unusable for humans but machine has no problem. haskell-mode has function/command haskell-mode-show-type-at to call up ghci's command. I bound it to a hotkey. |
2022-12-07 21:26:32 +0100 | jmdaemon | (~jmdaemon@user/jmdaemon) (Quit: ZNC 1.8.2 - https://znc.in) |
2022-12-07 21:26:50 +0100 | <monochrom> | Very unknown feature because by the time ghci added it and haskell-mode and dante added it, everyone was already hyping about ghc-mod and HLS and etc |
2022-12-07 21:27:03 +0100 | kenran | (~user@user/kenran) |
2022-12-07 21:27:23 +0100 | <monochrom> | So everyone simply inferred, from the hype, that there is no other way. |
2022-12-07 21:27:57 +0100 | <monochrom> | or s/other/low-tech/ |
2022-12-07 21:28:14 +0100 | stiell | (~stiell@gateway/tor-sasl/stiell) |
2022-12-07 21:28:16 +0100 | <geekosaur> | nobody wants low-tech ways |
2022-12-07 21:28:17 +0100 | <monochrom> | This is how advertisements work psychologically in general. |
2022-12-07 21:28:27 +0100 | dminuoso | wants physical buttons in his car |
2022-12-07 21:28:39 +0100 | <Rembane> | +1 |
2022-12-07 21:29:29 +0100 | <monochrom> | A TV ad that says "with Benilyn your cold symptoms will be gone in 2 weeks" is truthful but mislead you to wrongly believe that without medication your cold symptoms would not be gone in 14 days. |
2022-12-07 21:30:17 +0100 | <Rembane> | Withouth Benilyn they are gone in ten days! |
2022-12-07 21:30:29 +0100 | <gurkenglas> | intero had it way before ghci, right? |
2022-12-07 21:31:59 +0100 | <monochrom> | I also read that IRL there was a politician whose election platform was like "if you elect me, I'll make your foo tax rate to be bar percent!", bar being a pretty nice low number. The catch is that before the election the foo tax rate was already at bar percent. |
2022-12-07 21:32:11 +0100 | seriously_guest | (~seriously@2001:1c06:2715:c200:1a82:76d8:bd30:82fc) |
2022-12-07 21:32:28 +0100 | money_ | (~money@user/polo) |
2022-12-07 21:33:53 +0100 | <EvanR> | we all got a letter from the assessor sayings vote to limit the property tax increase to 10% this year. Elsewhere there was a report saying it would default to 2% |
2022-12-07 21:34:05 +0100 | <dolio> | I don't think so. Wasn't intero using the same mechanism as dante, except it only worked with stack? |
2022-12-07 21:35:07 +0100 | <geekosaur> | dante used ghci, intero involved a modified stack-only ghci iirc |
2022-12-07 21:35:22 +0100 | <monochrom> | I heard people asking about why stack rebuilt intero repeatedly. I assume that it implies that intero uses GHC API like ghc-mod did. |
2022-12-07 21:35:34 +0100 | <monochrom> | Oh modified ghci, haha that's epic. |
2022-12-07 21:35:43 +0100 | <monochrom> | worst of both worlds haha |
2022-12-07 21:35:56 +0100 | <geekosaur> | well, anything using ghc-api in a general fashion is just a reworked ghci |
2022-12-07 21:36:09 +0100 | <monochrom> | OK fair. |
2022-12-07 21:36:12 +0100 | <geekosaur> | I don't know exact details but ghci is a thin wrapper over ghc-api |
2022-12-07 21:36:37 +0100 | <geekosaur> | (exact details re intero that os) |
2022-12-07 21:36:39 +0100 | <geekosaur> | *is |
2022-12-07 21:37:25 +0100 | <gurkenglas> | *looks at ListT* *looks at ListT done right* neither of these are what I want, I think O_o. I want IO [a] |
2022-12-07 21:37:47 +0100 | <monochrom> | IO [a] would be the former ListT. |
2022-12-07 21:37:49 +0100 | <gurkenglas> | am i... about to reach for acme-iot |
2022-12-07 21:38:08 +0100 | festive_kurbus | (~festive_k@user/kurbus) (Quit: Client closed) |
2022-12-07 21:38:30 +0100 | <monochrom> | OK, unless the former ListT's >>= is not to your liking. |
2022-12-07 21:38:55 +0100 | <gurkenglas> | oh, i failed to look at the former ListT instead of two different search results for the done right one |
2022-12-07 21:39:21 +0100 | <gurkenglas> | and thought the difference between them must be some technicality i didnt see at first glance |
2022-12-07 21:40:11 +0100 | kenran | (~user@user/kenran) (Remote host closed the connection) |
2022-12-07 21:40:14 +0100 | <gurkenglas> | the >>= logic should be... everything in line 118 happens before everything in line 119 |
2022-12-07 21:41:06 +0100 | <seriously_guest> | hey ... Im having some trouble understanding the motivation section of applicative functors in CIS 194... Why would we write a function (Name -> String -> Employee) -> (Maybe Name -> Maybe String -> Maybe Employee); when we could just have a (Maybe Name -> Maybe String -> Employee) |
2022-12-07 21:41:29 +0100 | <gurkenglas> | (logic perhaps not being the right phrase, instead of "IO sequencing") |
2022-12-07 21:42:01 +0100 | <monochrom> | I don't understand the question. |
2022-12-07 21:42:25 +0100 | <geekosaur> | seriously_guest, what does your function produce if either Name or String is Nothing? |
2022-12-07 21:42:57 +0100 | <seriously_guest> | geekosaur Employee (Nothing) (Nothing) |
2022-12-07 21:43:12 +0100 | <monochrom> | Does Employee allow that? |
2022-12-07 21:43:17 +0100 | <seriously_guest> | or Employee (Just "Frank") (Nothing) |
2022-12-07 21:44:18 +0100 | <seriously_guest> | Employee by the examples defition does not monochrom |
2022-12-07 21:44:29 +0100 | <geekosaur> | then you have the point |
2022-12-07 21:44:51 +0100 | <monochrom> | I'm too lazy to search. Which URL has the definition of Employee? |
2022-12-07 21:44:53 +0100 | <seriously_guest> | But thats why im suggeesting just create a data Employee = Employee (Maybe Name) (Maybe String) |
2022-12-07 21:44:54 +0100 | festive_kurbus | (~festive_k@user/kurbus) |
2022-12-07 21:45:00 +0100 | <seriously_guest> | https://www.cis.upenn.edu/~cis1940/spring13/lectures/10-applicative.html |
2022-12-07 21:45:15 +0100 | <monochrom> | Well then Employee doesn't allow Nothing. |
2022-12-07 21:45:18 +0100 | <dsal> | Do you want an employee whose name you don't know? |
2022-12-07 21:45:44 +0100 | <dsal> | An Employee Has No Name |
2022-12-07 21:45:54 +0100 | <monochrom> | If one day you have a webapp in which "data Employee = Employee (Maybe Name) (Maybe String)" is totally legit, good for you. |
2022-12-07 21:46:00 +0100 | <seriously_guest> | haha... no |
2022-12-07 21:46:04 +0100 | <geekosaur> | right, what if your business logic doesn't allow anemployee without a name? do you have to drag around a Just that shouldn't ever be needed? |
2022-12-07 21:46:07 +0100 | eggplantade | (~Eggplanta@104-55-37-220.lightspeed.sntcca.sbcglobal.net) (Remote host closed the connection) |
2022-12-07 21:46:11 +0100 | <monochrom> | For now, my webapp says that it should make no sense and it should be disallowed. |
2022-12-07 21:46:38 +0100 | <monochrom> | Then I really legit only have either Just (Employee foo bar) or Nothing, i.e., Maybe Employee. |
2022-12-07 21:46:42 +0100 | <dsal> | It's a good idea to make illegal states unrepresentable. |
2022-12-07 21:46:58 +0100 | <dminuoso> | Now whether a missing name is illegal state, that's for you to decide. |
2022-12-07 21:47:11 +0100 | <seriously_guest> | I see |
2022-12-07 21:47:45 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) |
2022-12-07 21:48:29 +0100 | huskle | (~huskle@250.79-105-213.static.virginmediabusiness.co.uk) |
2022-12-07 21:48:39 +0100 | <huskle> | hi, i just installed haskell on ubuntu |
2022-12-07 21:48:45 +0100 | <huskle> | having just installed ubuntu |
2022-12-07 21:48:52 +0100 | <huskle> | when i do cabal v2-install random |
2022-12-07 21:48:54 +0100 | <huskle> | it fails! |
2022-12-07 21:49:15 +0100 | Inoperable | (~PLAYER_1@fancydata.science) (Ping timeout: 268 seconds) |
2022-12-07 21:49:18 +0100 | <Rembane> | huskle: How does it fail? |
2022-12-07 21:49:21 +0100 | <huskle> | i installed ghcup using curl as it says to |
2022-12-07 21:49:34 +0100 | <huskle> | Rembrane: /usr/bin/ld.gold: error: cannot find -lgmp |
2022-12-07 21:50:08 +0100 | <huskle> | is this a dependency that ghcup should have installed? |
2022-12-07 21:50:20 +0100 | <dolio> | You probably need to install it with apt. |
2022-12-07 21:50:20 +0100 | <Rembane> | huskle: Have you tried sudo apt-get install build-essential |
2022-12-07 21:50:24 +0100 | <monochrom> | sudo apt install libgmp-dev |
2022-12-07 21:50:38 +0100 | <monochrom> | build-essential doesn't have it. |
2022-12-07 21:50:59 +0100 | <geekosaur> | but you'll probably need build-essential anyway |
2022-12-07 21:51:07 +0100 | <huskle> | Rembrane: says they are there already |
2022-12-07 21:51:09 +0100 | <monochrom> | Yeah, build-essential is for gcc. |
2022-12-07 21:51:49 +0100 | ft | (~ft@p508dbd59.dip0.t-ipconnect.de) |
2022-12-07 21:51:57 +0100 | <huskle> | yay! now it works |
2022-12-07 21:52:13 +0100 | <huskle> | libgmp-dev seems to have been missing |
2022-12-07 21:52:24 +0100 | <huskle> | so why does ghcup not install this? |
2022-12-07 21:52:57 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 268 seconds) |
2022-12-07 21:53:04 +0100 | <monochrom> | ghcup does not know that it is not "pacman foobar libgmp-dev"? |
2022-12-07 21:53:25 +0100 | <mauke> | I don't think you need the -dev package; libgmp10 might have been sufficient |
2022-12-07 21:53:30 +0100 | <dolio> | Yeah, does ghcup interact at all with the system package manager? |
2022-12-07 21:53:35 +0100 | <monochrom> | Alternatively but equivalently, "patches welcome". |
2022-12-07 21:53:57 +0100 | <monochrom> | Although, ghcup absolutely avoids sudo. |
2022-12-07 21:54:10 +0100 | <huskle> | beyond me |
2022-12-07 21:54:17 +0100 | <monochrom> | libgmp10 is positively verified to be insufficient. |
2022-12-07 21:54:26 +0100 | <mauke> | oh, neat |
2022-12-07 21:54:50 +0100 | <huskle> | sounds like an issue encountered before! |
2022-12-07 21:54:54 +0100 | waleee | (~waleee@2001:9b0:213:7200:cc36:a556:b1e8:b340) |
2022-12-07 21:55:38 +0100 | <huskle> | im making some differentialble random number sequences if anyones interested |
2022-12-07 21:55:49 +0100 | <huskle> | its for machine learning |
2022-12-07 21:55:56 +0100 | haritz | (~hrtz@user/haritz) (Quit: ZNC 1.8.2+deb2 - https://znc.in) |
2022-12-07 21:56:13 +0100 | <monochrom> | An ubuntu libfoo-dev package contains *.h files and a symlink from libfoo.so to libfoo.so.x.y.z. libfoo.so.x.y.z being already in the libfoo package. |
2022-12-07 21:56:31 +0100 | <monochrom> | GHC just needs the libfoo.so symlink. |
2022-12-07 21:56:49 +0100 | <monochrom> | You could argue that you don't need libfoo-dev for that, you could make the symlink yourself. |
2022-12-07 21:57:12 +0100 | <huskle> | (!?) |
2022-12-07 21:57:14 +0100 | <monochrom> | Explaining that takes 100 times more effort than instructing "sudo apt install libfoo-dev". |
2022-12-07 21:57:19 +0100 | <mauke> | that strikes me as slightly weird. why is the .so link part of the dev package? |
2022-12-07 21:57:35 +0100 | <monochrom> | Ideology? |
2022-12-07 21:57:54 +0100 | <monochrom> | Every linux distro makes ideological, irrational decisions. |
2022-12-07 21:58:02 +0100 | <monochrom> | Just look at archlinux. :) |
2022-12-07 21:58:22 +0100 | <mauke> | I'm not sure "irrational" has semantics |
2022-12-07 21:58:32 +0100 | <huskle> | well, better than windows installing updates that ensure the bloatawre cannot be disabled |
2022-12-07 21:59:05 +0100 | <huskle> | that also use so much resources as to prevent taskmanager from being opened to stop other processes |
2022-12-07 21:59:34 +0100 | <monochrom> | Oh speaking of bloatware on Windows. I learned yesterday that Chinese bloatware installers are like "In the following don't deselect the packages you don't want". |
2022-12-07 21:59:38 +0100 | <huskle> | i want the last year of my life back |
2022-12-07 22:00:35 +0100 | <huskle> | anyway, with linux, i can now open a text editor and a directory browser in less than a minute! |
2022-12-07 22:00:45 +0100 | <EvanR> | yes irrational = not rational is terribly negative. What's the positive version |
2022-12-07 22:00:49 +0100 | <monochrom> | For the semantics of "irrational", you can start with your own "slightly weird, why did they do it?" |
2022-12-07 22:00:50 +0100 | <huskle> | i used to use wordpad, because it took *less* time than eclipseIDE to start |
2022-12-07 22:01:23 +0100 | <seriously_guest> | Can someone help me write an implementation of this type (continuing my previoius train of thought): (Name -> String -> Employee) -> |
2022-12-07 22:01:23 +0100 | <seriously_guest> | (Maybe Name -> Maybe String -> Maybe Employee) |
2022-12-07 22:01:43 +0100 | <mauke> | \_ _ _ -> Nothing |
2022-12-07 22:01:48 +0100 | <huskle> | lol |
2022-12-07 22:02:07 +0100 | <monochrom> | You can do pattern matching on two Maybe parameters. |
2022-12-07 22:02:08 +0100 | <huskle> | can they have no name or string or do they have to have a name or a string? |
2022-12-07 22:02:31 +0100 | <seriously_guest> | Have to have a name and a string |
2022-12-07 22:02:34 +0100 | <monochrom> | You can first call it 4 cases. Later you can merge 3 of them. |
2022-12-07 22:02:50 +0100 | <huskle> | not name *and* ... |
2022-12-07 22:03:00 +0100 | <mauke> | @djinn (Name -> String -> Employee) -> (Maybe Name -> Maybe String -> Maybe Employee) |
2022-12-07 22:03:00 +0100 | <lambdabot> | Error: Undefined type Name |
2022-12-07 22:03:06 +0100 | <dolio> | EvanR: Has a continued fraction representation with specified, finite gaps between non-zero coefficients. |
2022-12-07 22:03:25 +0100 | <huskle> | so its more like (Maybe (Name,String)) -> Maybe Employee? |
2022-12-07 22:03:30 +0100 | <huskle> | because then you can use fmap |
2022-12-07 22:03:44 +0100 | <huskle> | % :t fmap @Maybe |
2022-12-07 22:03:44 +0100 | <yahb2> | fmap @Maybe :: (a -> b) -> Maybe a -> Maybe b |
2022-12-07 22:03:52 +0100 | king_gs | (~Thunderbi@187.201.204.122) |
2022-12-07 22:03:55 +0100 | <seriously_guest> | Sorry huskle I believe you joined after I explained that this is in regards to cis 194 assignment 10 |
2022-12-07 22:04:09 +0100 | <monochrom> | No, totally unlike (Maybe (Name,String)) -> Maybe Employee |
2022-12-07 22:04:10 +0100 | <huskle> | ok |
2022-12-07 22:04:15 +0100 | <mauke> | @djinn (name -> string -> employee) -> (Maybe name -> Maybe string -> Maybe employee) |
2022-12-07 22:04:15 +0100 | <lambdabot> | f a b c = |
2022-12-07 22:04:15 +0100 | <lambdabot> | case b of |
2022-12-07 22:04:15 +0100 | <lambdabot> | Nothing -> Nothing |
2022-12-07 22:04:15 +0100 | <lambdabot> | Just d -> case c of |
2022-12-07 22:04:15 +0100 | <lambdabot> | Nothing -> Nothing |
2022-12-07 22:04:17 +0100 | <lambdabot> | Just e -> Just (a d e) |
2022-12-07 22:04:36 +0100 | <mauke> | well, that's not very elegant |
2022-12-07 22:06:07 +0100 | <seriously_guest> | What would the types of a, b, and c be ? |
2022-12-07 22:06:07 +0100 | festive_kurbus | (~festive_k@user/kurbus) (Quit: Client closed) |
2022-12-07 22:06:16 +0100 | <mauke> | wtf |
2022-12-07 22:06:31 +0100 | <mauke> | it's your type signature |
2022-12-07 22:06:57 +0100 | <mauke> | I gave it to the bot; it generated code; why are you now asking for the type of the code we started from? |
2022-12-07 22:07:19 +0100 | <seriously_guest> | why are you even assuming i know what this bot is doing? |
2022-12-07 22:08:15 +0100 | <monochrom> | Why is no one caring about my advice? |
2022-12-07 22:08:16 +0100 | <mauke> | hmm |
2022-12-07 22:08:48 +0100 | <mauke> | it's not so much that; what I'm assuming is that you can read/understand basic haskell code |
2022-12-07 22:08:53 +0100 | <iqubic> | Just use liftA3 |
2022-12-07 22:09:17 +0100 | <dsal> | liftA2 |
2022-12-07 22:09:26 +0100 | <iqubic> | Oh yeah |
2022-12-07 22:09:38 +0100 | <seriously_guest> | im learning haskell... let me write out my question in a more understandable format for you. If you have a function f with the type (Name -> String -> Employee) -> (Maybe Name -> Maybe String -> Maybe Employee), if you write a funcion definition using the pattern matching structure of f a b c = ...; what is the type of a, b, and c? |
2022-12-07 22:09:44 +0100 | <dsal> | Off by one lift |
2022-12-07 22:09:52 +0100 | <gurkenglas> | What's the current way to make hls add imports for me? |
2022-12-07 22:09:57 +0100 | <mauke> | seriously_guest: ooh, you're stuck on currying! |
2022-12-07 22:10:32 +0100 | <mauke> | seriously_guest: f a b c = ... is syntactic sugar for f = \a -> \b -> \c -> ... |
2022-12-07 22:10:35 +0100 | <huskle> | seriously_guest: thats wrong |
2022-12-07 22:10:35 +0100 | <kjlid[m]> | I just ate a curry |
2022-12-07 22:10:44 +0100 | <huskle> | you have one function argument |
2022-12-07 22:10:45 +0100 | <mauke> | seriously_guest: and the type A -> B -> C means A -> (B -> C) |
2022-12-07 22:10:55 +0100 | <mauke> | huskle: dude, what |
2022-12-07 22:11:13 +0100 | <huskle> | f g = |
2022-12-07 22:11:21 +0100 | <mauke> | huskle: did you not read what the bot wrote? |
2022-12-07 22:11:23 +0100 | <mauke> | also, you're wrong |
2022-12-07 22:11:29 +0100 | <huskle> | chill! |
2022-12-07 22:11:37 +0100 | <huskle> | this bot has you all het up |
2022-12-07 22:11:45 +0100 | <huskle> | its a beginer q |
2022-12-07 22:12:06 +0100 | <huskle> | and your all like "all function arrows are monomorphisms" |
2022-12-07 22:12:20 +0100 | <EvanR> | f g =, the type of g is (Name -> String -> Employee) |
2022-12-07 22:12:22 +0100 | <mauke> | seriously_guest: well, that assumes you know what \a -> ... means. do you? |
2022-12-07 22:12:31 +0100 | <mauke> | if not, this explanation was useless :-) |
2022-12-07 22:12:39 +0100 | <huskle> | EvanR: thanks... |
2022-12-07 22:13:23 +0100 | <seriously_guest> | EvanR how about f g h |
2022-12-07 22:13:30 +0100 | <huskle> | functions in one argument* (i have no idea what a monomorphism is. sry!) |
2022-12-07 22:13:41 +0100 | <EvanR> | h sounds like you want a second function argument? |
2022-12-07 22:13:51 +0100 | <EvanR> | your next argument would be Maybe Name if you want to do it that way |
2022-12-07 22:14:29 +0100 | <EvanR> | f g mname mstring = |
2022-12-07 22:14:31 +0100 | <huskle> | % :t curry |
2022-12-07 22:14:31 +0100 | <yahb2> | curry :: ((a, b) -> c) -> a -> b -> c |
2022-12-07 22:14:41 +0100 | <huskle> | % :t fmap @Maybe . uncurry |
2022-12-07 22:14:41 +0100 | <yahb2> | fmap @Maybe . uncurry ; :: (a -> b1 -> b2) -> Maybe (a, b1) -> Maybe b2 |
2022-12-07 22:14:57 +0100 | <huskle> | your sure its not this? |
2022-12-07 22:15:09 +0100 | <huskle> | he said they have to have a name *and* a string |
2022-12-07 22:15:22 +0100 | <huskle> | they* |
2022-12-07 22:15:32 +0100 | <EvanR> | sounds like you need Applicative but also we can't get there yet |
2022-12-07 22:15:48 +0100 | Inoperable | (~PLAYER_1@fancydata.science) |
2022-12-07 22:15:55 +0100 | <EvanR> | you have to swim before you can crawl |
2022-12-07 22:16:14 +0100 | <mauke> | seriously_guest: but to answer your question in full, a :: (Name -> String -> Employee); b :: Maybe Name; c :: Maybe String |
2022-12-07 22:17:25 +0100 | pavonia | (~user@user/siracusa) |
2022-12-07 22:18:17 +0100 | <gurkenglas> | Is there a MonadIO-lifted version of https://hackage.haskell.org/package/text-2.0.1/docs/Data-Text-IO.html ? |
2022-12-07 22:18:19 +0100 | tvandinther | (~tvandinth@111.69.34.210) |
2022-12-07 22:18:27 +0100 | <seriously_guest> | I apologize for causing any confusion... let me take a step back and give everyone some context. Im reading week 10 of Yorgeys CIS 194 2013. Im struggling to get through the MOTIVATION section of the reading. I don't see how having a function of type (Name -> String -> Employee) -> (Maybe Name -> Maybe String -> Maybe Employee) is useful. IM NOT |
2022-12-07 22:18:28 +0100 | <seriously_guest> | SAYING ITS NOT USEFUL. Im only saying that I CANT UNDERSTAND WHY its useful. I understand that in a business use case, we want a way to be able to parse employee io data into an Employee data type. I don understand how that function does this. |
2022-12-07 22:18:32 +0100 | <dminuoso> | gurkenglas: Probably not. You can just liftIO |
2022-12-07 22:19:03 +0100 | <dminuoso> | seriously_guest: We could perhaps start with a different motivation. |
2022-12-07 22:19:10 +0100 | <geekosaur> | gurkenglas, I would expect one of the alternative Preludes to have it |
2022-12-07 22:19:16 +0100 | <dminuoso> | seriously_guest: Say you have two numbers held in a variable `a` and `b`, and you want to add them. |
2022-12-07 22:19:28 +0100 | <dminuoso> | seriously_guest: This would just be `a + b`, right? |
2022-12-07 22:19:35 +0100 | <seriously_guest> | right |
2022-12-07 22:20:00 +0100 | <dminuoso> | So in that `a :: Int` and `b :: Int` |
2022-12-07 22:20:13 +0100 | <gurkenglas> | maybe there's some Data.Coercible-like hackery that you can wrap around a code block that is correct except for some missing liftIOs to pepper them in |
2022-12-07 22:20:18 +0100 | <huskle> | idk, maybe so its like "well if either of these records are left blank, then we can propegate an error in the form of Nothing |
2022-12-07 22:20:33 +0100 | <dminuoso> | % let a = 1; b = 2; in a + b |
2022-12-07 22:20:33 +0100 | <yahb2> | 3 |
2022-12-07 22:20:43 +0100 | <geekosaur> | seriously_guest, you start out with an ordinary constructor for an Employee, and Applicative gives you a conditional one that gives you an Employee only if the Name and String are valid (not Nothing). this is then useful with business logic that validates those and produces Just them or Nothing if they're not valid |
2022-12-07 22:20:50 +0100 | kenaryn | (~aurele@cre71-h03-89-88-44-27.dsl.sta.abo.bbox.fr) |
2022-12-07 22:20:59 +0100 | <geekosaur> | (there is for example a validation package that helps with that part) |
2022-12-07 22:21:12 +0100 | <dminuoso> | So for some reason however, assume that `a` and `b` might be empty however (say we read them from a file, but perhaps the file is empty), so we use `Maybe Int` to represent them instead. So we have `ma :: Maybe Int` and `mb :: Maybe Int` |
2022-12-07 22:21:16 +0100 | <geekosaur> | so now you can compose parts together to build your busines slogic from pieces |
2022-12-07 22:21:27 +0100 | <dminuoso> | seriously_guest: Do you see, how you can no longer just (+) them together? |
2022-12-07 22:21:53 +0100 | <dminuoso> | % let ma = Just 3; mb = Nothing in ma + mb |
2022-12-07 22:21:53 +0100 | <yahb2> | <interactive>:86:1: error: ; • No instance for (Num (Maybe Integer)) arising from a use of ‘it’ ; • In the first argument of ‘Yahb2Defs.limitedPrint’, namely ‘it’ ; In a stmt of an in... |
2022-12-07 22:22:11 +0100 | irrgit__ | (~irrgit@176.113.74.74) |
2022-12-07 22:22:23 +0100 | <seriously_guest> | dminuoso yup because there no longer Int, an instance of Number. They are now Maybe Int |
2022-12-07 22:22:27 +0100 | <dminuoso> | Right. |
2022-12-07 22:22:35 +0100 | <huskle> | dminuoso: i like your example better because it is more clear that it has to have both entries or its an error |
2022-12-07 22:22:46 +0100 | <dminuoso> | But we may want to still express the idea of "if both numbers are present, add them together" |
2022-12-07 22:22:47 +0100 | <gurkenglas> | yahb2: that should say "expected Int but found Maybe Int" |
2022-12-07 22:22:48 +0100 | king_gs | (~Thunderbi@187.201.204.122) (Ping timeout: 260 seconds) |
2022-12-07 22:22:53 +0100 | <dminuoso> | gurkenglas: nope. |
2022-12-07 22:23:04 +0100 | <dminuoso> | The error is quite right |
2022-12-07 22:23:08 +0100 | <huskle> | :t maybe |
2022-12-07 22:23:09 +0100 | <lambdabot> | b -> (a -> b) -> Maybe a -> b |
2022-12-07 22:23:35 +0100 | <dminuoso> | seriously_guest: So what we can write then is: |
2022-12-07 22:23:38 +0100 | <gurkenglas> | dminuoso: Do you mean, I misdiagnosed his issue, or you disapprove of my proposal? :D |
2022-12-07 22:23:47 +0100 | <dminuoso> | Both. |
2022-12-07 22:23:55 +0100 | <huskle> | :t both |
2022-12-07 22:23:56 +0100 | <lambdabot> | (Data.Bitraversable.Bitraversable r, Applicative f) => (a -> f b) -> r a a -> f (r b b) |
2022-12-07 22:24:00 +0100 | <huskle> | !? |
2022-12-07 22:24:01 +0100 | <dminuoso> | % let ma = Just 3; mb = Just 4 in liftA2 (+) ma mb -- seriously_guest |
2022-12-07 22:24:01 +0100 | <yahb2> | <interactive>:88:33: error: ; Variable not in scope: ; liftA2 :: (a0 -> a0 -> a0) -> Maybe a1 -> Maybe a2 -> t |
2022-12-07 22:24:07 +0100 | <dminuoso> | % import Control.Applicative (liftA2) |
2022-12-07 22:24:07 +0100 | <yahb2> | <no output> |
2022-12-07 22:24:09 +0100 | <dminuoso> | % let ma = Just 3; mb = Just 4 in liftA2 (+) ma mb -- seriously_guest |
2022-12-07 22:24:09 +0100 | <yahb2> | Just 7 |
2022-12-07 22:24:15 +0100 | <dsal> | :t each |
2022-12-07 22:24:16 +0100 | <lambdabot> | (Each s t a b, Applicative f) => (a -> f b) -> s -> f t |
2022-12-07 22:24:18 +0100 | <dminuoso> | % :t liftA2 |
2022-12-07 22:24:18 +0100 | <yahb2> | liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c |
2022-12-07 22:24:24 +0100 | <dminuoso> | seriously_guest: ^- is this clear? |
2022-12-07 22:24:38 +0100 | <huskle> | % :t liftA2 (+) |
2022-12-07 22:24:38 +0100 | <yahb2> | liftA2 (+) :: (Applicative f, Num c) => f c -> f c -> f c |
2022-12-07 22:24:43 +0100 | <dminuoso> | (It may not be immediately necessary to understand *why* liftA2 works, but merely what it does) |
2022-12-07 22:24:52 +0100 | <gurkenglas> | dminuoso: ohh! :D i thought yahb2 was a user barely scrounging together the willpower to paste what ghci spat out to us so we can debug his unrelated error |
2022-12-07 22:24:53 +0100 | <huskle> | % liftA2 (+) Nothing (Just 4) |
2022-12-07 22:24:53 +0100 | <yahb2> | Nothing |
2022-12-07 22:25:00 +0100 | <huskle> | % liftA2 (+) (Just 3) (Just 4) |
2022-12-07 22:25:00 +0100 | <yahb2> | Just 7 |
2022-12-07 22:25:04 +0100 | <huskle> | yay! |
2022-12-07 22:25:13 +0100 | takuan | (~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection) |
2022-12-07 22:25:14 +0100 | irrgit_ | (~irrgit@176.113.74.74) (Ping timeout: 246 seconds) |
2022-12-07 22:25:31 +0100 | <mauke> | % instance (Num a) => Num (Maybe a) where { (+) = liftA2 (+); (*) = liftA2 (*); abs = fmap abs; signum = fmap signum; fromInteger = pure . fromInteger; negate = fmap negate } |
2022-12-07 22:25:32 +0100 | <yahb2> | <no output> |
2022-12-07 22:25:37 +0100 | <seriously_guest> | dminuoso "% let ma = Just 3; mb = Just 4 in liftA2 (+) ma mb" - Its clear as in Yes theres a function lifaA2 which runs the function (+) inside the Functor m's values |
2022-12-07 22:25:37 +0100 | <mauke> | > Just 3 + Just 4 |
2022-12-07 22:25:39 +0100 | <lambdabot> | error: |
2022-12-07 22:25:39 +0100 | <lambdabot> | • No instance for (Num (Maybe Integer)) |
2022-12-07 22:25:39 +0100 | <lambdabot> | arising from a use of ‘e_134’ |
2022-12-07 22:25:42 +0100 | <mauke> | % Just 3 + Just 4 |
2022-12-07 22:25:42 +0100 | <yahb2> | Just 7 |
2022-12-07 22:25:51 +0100 | <huskle> | !? |
2022-12-07 22:25:56 +0100 | <mauke> | % Just 3 + Nothing |
2022-12-07 22:25:56 +0100 | <yahb2> | Nothing |
2022-12-07 22:26:04 +0100 | <huskle> | Just Int has a Num instance? |
2022-12-07 22:26:09 +0100 | <mauke> | it does now |
2022-12-07 22:26:13 +0100 | <dminuoso> | seriously_guest: Yup! So in some sense liftA2 is similar to fmap, except for functions with an arity of 2, whereas fmap only works for functions with arity of 1. |
2022-12-07 22:26:19 +0100 | <dminuoso> | seriously_guest: Is this clear so far? |
2022-12-07 22:26:54 +0100 | <huskle> | % :t negate @(Just Int) |
2022-12-07 22:26:54 +0100 | <yahb2> | <interactive>:1:10: error: ; Not in scope: type constructor or class ‘Just’ ; A data constructor of that name is in scope; did you mean DataKinds? |
2022-12-07 22:27:01 +0100 | <huskle> | % :t negate @(Maybe Int) |
2022-12-07 22:27:01 +0100 | <yahb2> | negate @(Maybe Int) :: Maybe Int -> Maybe Int |
2022-12-07 22:27:25 +0100 | <huskle> | did you just make this in another window in a convo with yahb? |
2022-12-07 22:27:31 +0100 | <mauke> | huskle: no |
2022-12-07 22:27:33 +0100 | gmg | (~user@user/gehmehgeh) |
2022-12-07 22:27:39 +0100 | <dminuoso> | In truth Applicative comes with (<*>), which lets us generalize this liftA2 for functions of _arbitrary_ arity. So say you have a function taking 5 values, but you have 5 Maybe wrapped things instead, then Applicative will let you deal with it exactly like shown above with liftA2. |
2022-12-07 22:27:39 +0100 | <huskle> | ... |
2022-12-07 22:27:44 +0100 | <mauke> | I made it in this window, literally two lines before |
2022-12-07 22:27:49 +0100 | <seriously_guest> | Yeah clear so far! to levelset though, I want to ensure were on the quest to explaining why (a -> b -> c) -> (f a -> f b -> f c) is useful in our example |
2022-12-07 22:28:01 +0100 | <dminuoso> | seriously_guest: Sure! I just wanted to set the scene. |
2022-12-07 22:28:07 +0100 | <seriously_guest> | cool |
2022-12-07 22:28:21 +0100 | <huskle> | oh the lamdabot error confused me |
2022-12-07 22:28:28 +0100 | <dminuoso> | 22:27:39 dminuoso | In truth Applicative comes with (<*>), which lets us generalize this liftA2 for functions of _arbitrary_ arity. So say you have a function taking 5 values, but you have 5 Maybe wrapped things instead, then Applicative will let you deal with it exactly like shown above with liftA2. |
2022-12-07 22:28:33 +0100 | <dsal> | @src liftA2 |
2022-12-07 22:28:33 +0100 | <lambdabot> | liftA2 f a b = f <$> a <*> b |
2022-12-07 22:28:56 +0100 | <mauke> | huskle: note how the instance body is generic and could be reused for any Applicative |
2022-12-07 22:29:00 +0100 | <dminuoso> | seriously_guest: So if you have a function that demand exactly 5 values of some particular types, but if some of them are missing, you clearly cant produce a sensible result with that. |
2022-12-07 22:29:15 +0100 | <mauke> | (including IO) |
2022-12-07 22:29:36 +0100 | <huskle> | some subset of functors? |
2022-12-07 22:30:04 +0100 | <dminuoso> | seriously_guest: The *lifting* is just a means to an end here. |
2022-12-07 22:30:20 +0100 | <huskle> | hey, does anyone want to see my differentiable random sequences thing? |
2022-12-07 22:30:30 +0100 | <dminuoso> | seriously_guest: It's not per-se being able to do `(a -> b -> c) -> (f a -> f b -> f c)`, but rather doing this *and then* applying it to `f a` and `f b` |
2022-12-07 22:30:54 +0100 | <dminuoso> | seriously_guest: So its really about `I have A -> B -> C, but am given `Maybe A` and `Maybe `B`, the above will let me get a `Maybe C` back. |
2022-12-07 22:31:16 +0100 | <dminuoso> | (Note Im particularly monomorphizing `f` to `Maybe` here. |
2022-12-07 22:31:32 +0100 | biberu | (~biberu@user/biberu) (Read error: Connection reset by peer) |
2022-12-07 22:31:43 +0100 | <huskle> | https://paste.tomsmeding.com/rZsfvbud |
2022-12-07 22:31:47 +0100 | <dminuoso> | Quite similarly to how `liftA2 (+)` is useful for being able to do `liftA2 (+) ma mb` |
2022-12-07 22:32:19 +0100 | <dminuoso> | Of course in code style it can be useful to decouple them, so you maybe do let `add_maybes = liftA2 (+) in ...` |
2022-12-07 22:32:24 +0100 | <huskle> | see, it works! |
2022-12-07 22:33:01 +0100 | wootehfoot | (~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer) |
2022-12-07 22:33:07 +0100 | <dsal> | > let (+?) = liftA2 (+) in Just 3 +? Just 5 |
2022-12-07 22:33:08 +0100 | <lambdabot> | Just 8 |
2022-12-07 22:33:16 +0100 | <huskle> | the guest is not interested |
2022-12-07 22:33:19 +0100 | <seriously_guest> | dminuoso im still comprehending some things... just a sec |
2022-12-07 22:34:00 +0100 | <huskle> | let us know when you are done comprehending things |
2022-12-07 22:35:35 +0100 | gmg | (~user@user/gehmehgeh) (Ping timeout: 255 seconds) |
2022-12-07 22:35:35 +0100 | stiell | (~stiell@gateway/tor-sasl/stiell) (Ping timeout: 255 seconds) |
2022-12-07 22:36:15 +0100 | biberu | (~biberu@user/biberu) |
2022-12-07 22:36:26 +0100 | gmg | (~user@user/gehmehgeh) |
2022-12-07 22:36:45 +0100 | stiell | (~stiell@gateway/tor-sasl/stiell) |
2022-12-07 22:38:56 +0100 | <seriously_guest> | dminuoso Im clear on this bit " dminuoso | In truth Applicative comes with (<*>)"..... (<*>) lets us lift functors and apply a function of the values. It does this as long as the number of arguments and the number of Maybes (functors) are the same |
2022-12-07 22:39:10 +0100 | <seriously_guest> | I think im clear on this bit* |
2022-12-07 22:39:20 +0100 | <seriously_guest> | on the values* |
2022-12-07 22:39:22 +0100 | money_ | (~money@user/polo) (Quit: money_) |
2022-12-07 22:39:27 +0100 | <dsal> | Consider ($) vs. (<$>) vs. (<*>) |
2022-12-07 22:39:37 +0100 | Unicorn_Princess | (~Unicorn_P@user/Unicorn-Princess/x-3540542) (Quit: Leaving) |
2022-12-07 22:39:43 +0100 | <dminuoso> | seriously_guest: A slight correcftion: |
2022-12-07 22:40:06 +0100 | <dminuoso> | If you want to use the generalizsed version, its <$> and <*> for most simple use cases. |
2022-12-07 22:40:07 +0100 | <huskle> | ... we can write liftN, for any N, sure |
2022-12-07 22:40:22 +0100 | <dminuoso> | While <*> on its own is useful too, the usecase we are talking about always looks like |
2022-12-07 22:40:31 +0100 | <dminuoso> | f <$> a1 <*> a2 <*> a3 ... <*> an |
2022-12-07 22:40:40 +0100 | <dsal> | > let (+?+) = (fmap . fmap) show . liftA2 (+) `on` readMaybe in "2" +?+ "5" -- Look, I've invented tcl! |
2022-12-07 22:40:41 +0100 | <lambdabot> | Just "7" |
2022-12-07 22:40:59 +0100 | <huskle> | yuk |
2022-12-07 22:41:27 +0100 | <dminuoso> | seriously_guest: So `<$>` on its own lets you do this for functions taking just one argument, and `<*>` lets you extend that (together with <$>) for functions of arbitrary arity. |
2022-12-07 22:41:28 +0100 | <huskle> | % @src liftA3 |
2022-12-07 22:41:28 +0100 | <yahb2> | <interactive>:120:1: error: parse error on input ‘@’ |
2022-12-07 22:41:37 +0100 | <huskle> | % :src liftA3 |
2022-12-07 22:41:37 +0100 | <yahb2> | unknown command ':src' ; use :? for help. |
2022-12-07 22:41:40 +0100 | <huskle> | ? |
2022-12-07 22:41:40 +0100 | jakalx | (~jakalx@base.jakalx.net) (Error from remote client) |
2022-12-07 22:41:43 +0100 | <dsal> | @src liftA3 |
2022-12-07 22:41:43 +0100 | <lambdabot> | Source not found. |
2022-12-07 22:41:58 +0100 | <huskle> | oh right its a lambdabot thing |
2022-12-07 22:42:04 +0100 | <seriously_guest> | dminuoso Gotcha there... now im trying to understand this part "It's not per-se being able to do `(a -> b - ......" |
2022-12-07 22:42:08 +0100 | <dsal> | Imagine it said liftA3 f a b c = f <$> a <*> b <*> c |
2022-12-07 22:42:17 +0100 | <dminuoso> | seriously_guest: If you have got what you just said, dont worry about it. |
2022-12-07 22:42:26 +0100 | <huskle> | > let liftA3 f a b c = f <$> a <*> b <*> c |
2022-12-07 22:42:27 +0100 | <lambdabot> | <no location info>: error: |
2022-12-07 22:42:27 +0100 | <lambdabot> | not an expression: ‘let liftA3 f a b c = f <$> a <*> b <*> c’ |
2022-12-07 22:42:31 +0100 | <dminuoso> | seriously_guest: liftA2 (or liftA3) is just a convenience for the 2-arity (or 3-arity) function case above. |
2022-12-07 22:42:34 +0100 | <huskle> | sorry |
2022-12-07 22:42:44 +0100 | Topsi1 | (~Topsi@dyndsl-095-033-143-231.ewe-ip-backbone.de) (Ping timeout: 256 seconds) |
2022-12-07 22:42:50 +0100 | Topsi | (~Topsi@dyndsl-095-033-227-140.ewe-ip-backbone.de) |
2022-12-07 22:42:51 +0100 | <dsal> | huskle: lambdabot doesn't know all the things, it just has some representative sources that make things easier to understand. |
2022-12-07 22:42:59 +0100 | <dminuoso> | seriously_guest: So instead of writing `f <$> a1 <*> a2 <*> a3` you can also write `liftA3 f a1 a2 a3` which does exactly the same thing. |
2022-12-07 22:42:59 +0100 | <huskle> | ahh |
2022-12-07 22:43:08 +0100 | <dsal> | e.g., this is definitely not sum: |
2022-12-07 22:43:10 +0100 | <dsal> | @src sum |
2022-12-07 22:43:10 +0100 | <lambdabot> | sum = foldl (+) 0 |
2022-12-07 22:43:16 +0100 | jakalx | (~jakalx@base.jakalx.net) |
2022-12-07 22:43:20 +0100 | <huskle> | ok |
2022-12-07 22:43:26 +0100 | <c_wraith> | @src foldr |
2022-12-07 22:43:26 +0100 | <lambdabot> | foldr f z [] = z |
2022-12-07 22:43:26 +0100 | <lambdabot> | foldr f z (x:xs) = f x (foldr f z xs) |
2022-12-07 22:43:29 +0100 | <huskle> | just some totally random reference! |
2022-12-07 22:43:36 +0100 | <dsal> | sum in Foldable is `sum = getSum #. foldMap' Sum` |
2022-12-07 22:43:37 +0100 | <c_wraith> | that one's even further from how GHC does it... |
2022-12-07 22:43:38 +0100 | <dminuoso> | seriously_guest: So what Im saying here is that `liftA3` is not useful because it lets you do this crazy transformation, but rather that `liftA3` lets you apply a 3-arity function to three Maybe things. |
2022-12-07 22:43:59 +0100 | <dminuoso> | (And the crazy transformation is just in order to apply it to three Maybe things) |
2022-12-07 22:44:02 +0100 | <huskle> | was looking at the source for "randoms" |
2022-12-07 22:44:06 +0100 | <huskle> | uses build |
2022-12-07 22:44:09 +0100 | <huskle> | for fusion |
2022-12-07 22:44:11 +0100 | <huskle> | pretty cool |
2022-12-07 22:44:14 +0100 | <seriously_guest> | So liftA3 (\x -> x + 1) (Maybe 1) (Maybe 2) (Maybe 3) = (Maybe 2) (Maybe 3) (Maybe 4) |
2022-12-07 22:44:24 +0100 | <huskle> | https://hackage.haskell.org/package/random-1.2.1.1/docs/src/System.Random.html#randoms |
2022-12-07 22:44:30 +0100 | <dminuoso> | seriously_guest: No thats not how it works. |
2022-12-07 22:44:35 +0100 | <dminuoso> | seriously_guest: Imagine this: |
2022-12-07 22:44:43 +0100 | <dminuoso> | % fun = \x y z -> (x + y) * z |
2022-12-07 22:44:43 +0100 | <yahb2> | <no output> |
2022-12-07 22:44:51 +0100 | <dminuoso> | % fun x y z = (x + y) * z |
2022-12-07 22:44:51 +0100 | <yahb2> | <no output> |
2022-12-07 22:45:22 +0100 | <dminuoso> | % fun :: Int -> Int -> Int -> Int; fun x y z = (x + y) * z |
2022-12-07 22:45:22 +0100 | <yahb2> | <no output> |
2022-12-07 22:45:38 +0100 | <dminuoso> | Now imagine you want to apply `fun` to three `Maybe Int` instead. |
2022-12-07 22:45:47 +0100 | <dsal> | % :t liftA3 fun |
2022-12-07 22:45:47 +0100 | <yahb2> | <interactive>:1:1: error: ; • Variable not in scope: liftA3 :: (Int -> Int -> Int -> Int) -> t ; • Perhaps you meant ‘liftA2’ (imported from Control.Applicative) |
2022-12-07 22:45:50 +0100 | <huskle> | % liftA3 (\x y z -> x + y * z) (Just 2) (Just 3) (Just 5) |
2022-12-07 22:45:50 +0100 | <yahb2> | <interactive>:132:1: error: ; • Variable not in scope: ; liftA3 ; :: (a0 -> a0 -> a0 -> a0) -> Maybe a1 -> Maybe a2 -> Maybe a3 -> t ; • Perhaps you meant ‘liftA2’ (import... |
2022-12-07 22:45:52 +0100 | <dminuoso> | Then you can just either write `liftA3 fun a1 a2 a3` or `fun <$> a1 <*> a2 <*> a3` |
2022-12-07 22:46:07 +0100 | <dminuoso> | % import Control.Applicative (liftA3) |
2022-12-07 22:46:08 +0100 | <yahb2> | <no output> |
2022-12-07 22:46:12 +0100 | <dminuoso> | % liftA3 (\x y z -> x + y * z) (Just 2) (Just 3) (Just 5) |
2022-12-07 22:46:12 +0100 | <yahb2> | Just 17 |
2022-12-07 22:46:21 +0100 | <dsal> | % :t liftA3 fun |
2022-12-07 22:46:21 +0100 | <yahb2> | liftA3 fun :: Applicative f => f Int -> f Int -> f Int -> f Int |
2022-12-07 22:46:26 +0100 | <dminuoso> | % liftA3 (\x y z -> x + y * z) <$> Just 2 <*> Just 3 <*> Just 5 |
2022-12-07 22:46:26 +0100 | <yahb2> | <interactive>:142:1: error: ; • Ambiguous type variable ‘f0’ arising from a use of ‘Yahb2Defs.limitedPrint’ ; prevents the constraint ‘(Show (f0 Integer))’ from being solved. ; Prob... |
2022-12-07 22:46:36 +0100 | eggplantade | (~Eggplanta@104-55-37-220.lightspeed.sntcca.sbcglobal.net) |
2022-12-07 22:46:38 +0100 | <dminuoso> | % liftA3 fun <$> Just 2 <*> Just 3 <*> Just 5 |
2022-12-07 22:46:38 +0100 | <yahb2> | Oops, something went wrong |
2022-12-07 22:46:41 +0100 | <dminuoso> | Wow. |
2022-12-07 22:46:44 +0100 | dminuoso | pokes tomsmeding |
2022-12-07 22:46:47 +0100 | <huskle> | why you still have the things between |
2022-12-07 22:46:50 +0100 | <huskle> | % liftA3 (\x y z -> x + y * z) (Just 2) (Just 3) (Just 5) |
2022-12-07 22:46:50 +0100 | <yahb2> | <interactive>:4:1: error: ; Variable not in scope: ; liftA3 ; :: (a0 -> a0 -> a0 -> a0) -> Maybe a1 -> Maybe a2 -> Maybe a3 -> t |
2022-12-07 22:46:51 +0100 | <dminuoso> | % fun <$> Just 2 <*> Just 3 <*> Just 5 |
2022-12-07 22:46:51 +0100 | <yahb2> | <interactive>:6:1: error: ; Variable not in scope: fun :: a0 -> a1 -> a2 -> b |
2022-12-07 22:47:04 +0100 | <dminuoso> | % fun :: Int -> Int -> Int -> Int; fun x y z = (x + y) * z |
2022-12-07 22:47:04 +0100 | <yahb2> | <no output> |
2022-12-07 22:47:09 +0100 | <dminuoso> | % fun <$> Just 2 <*> Just 3 <*> Just 5 |
2022-12-07 22:47:09 +0100 | <yahb2> | Just 25 |
2022-12-07 22:47:16 +0100 | Topsi | (~Topsi@dyndsl-095-033-227-140.ewe-ip-backbone.de) (Ping timeout: 256 seconds) |
2022-12-07 22:47:27 +0100 | <huskle> | % liftA3 fun (Just 2) (Just 3) (Just 5) |
2022-12-07 22:47:27 +0100 | <yahb2> | <interactive>:12:1: error: ; Variable not in scope: ; liftA3 ; :: (Int -> Int -> Int -> Int) ; -> Maybe a0 -> Maybe a1 -> Maybe a2 -> t |
2022-12-07 22:47:30 +0100 | <huskle> | rrg!! |
2022-12-07 22:47:41 +0100 | <huskle> | % liftA3 f a b c = f <$> a <*> b <*> c |
2022-12-07 22:47:41 +0100 | <yahb2> | <no output> |
2022-12-07 22:47:42 +0100 | <dminuoso> | seriously_guest: Are you still with me? |
2022-12-07 22:47:45 +0100 | <huskle> | % liftA3 fun (Just 2) (Just 3) (Just 5) |
2022-12-07 22:47:45 +0100 | <yahb2> | Just 25 |
2022-12-07 22:47:48 +0100 | <huskle> | yay! |
2022-12-07 22:48:06 +0100 | <seriously_guest> | Ohhh right ... so arity of x means a function taking x parameters ... Sorry yes! |
2022-12-07 22:48:11 +0100 | <dminuoso> | Yup. |
2022-12-07 22:48:38 +0100 | <dminuoso> | seriously_guest: One useful bit, that relates to this, is that in reality functions only take one argument in Haskell |
2022-12-07 22:48:54 +0100 | <dminuoso> | It is not an absolute truth and only perspective |
2022-12-07 22:49:14 +0100 | <huskle> | % :t fun <$> Just 1 <*> Just 2 |
2022-12-07 22:49:14 +0100 | <yahb2> | fun <$> Just 1 <*> Just 2 :: Maybe (Int -> Int) |
2022-12-07 22:49:17 +0100 | <dminuoso> | Something like `f :: Int -> Int -> Int` actually has implicit parenthesis `f :: Int -> (Int -> Int)` |
2022-12-07 22:49:20 +0100 | <huskle> | % :t fun <$> Just 1 |
2022-12-07 22:49:20 +0100 | <yahb2> | fun <$> Just 1 :: Maybe (Int -> Int -> Int) |
2022-12-07 22:49:32 +0100 | Inoperable | (~PLAYER_1@fancydata.science) (Ping timeout: 256 seconds) |
2022-12-07 22:49:37 +0100 | <huskle> | % :t (fun <$>) |
2022-12-07 22:49:37 +0100 | <yahb2> | (fun <$>) :: Functor f => f Int -> f (Int -> Int -> Int) |
2022-12-07 22:49:41 +0100 | <dminuoso> | equivalently applying to two functions sort of happens one argument at a time `f 1 2` is actually the same as `(f 1) 2` |
2022-12-07 22:49:45 +0100 | <dminuoso> | seriously_guest: Does this make sense as well? |
2022-12-07 22:49:55 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) |
2022-12-07 22:50:40 +0100 | <dminuoso> | But for sake of disussion, when we talk about a function like `Int -> Int -> Int` we usually adopt the notion that this has "2 parameters", knowing that in reality it is a function that returns a function (which is an equivalent encoding) |
2022-12-07 22:50:52 +0100 | <dminuoso> | So its useful to be able to shift this perspective from time to time |
2022-12-07 22:51:11 +0100 | <dminuoso> | This has some useful consequences (and again this relates to the confusion that sparked me getting into the discussion) |
2022-12-07 22:51:32 +0100 | eggplantade | (~Eggplanta@104-55-37-220.lightspeed.sntcca.sbcglobal.net) (Ping timeout: 268 seconds) |
2022-12-07 22:51:41 +0100 | <seriously_guest> | It makes sense as much as it can for me... I dont think its necesarily clicked on the importance of such a notion tho. |
2022-12-07 22:52:04 +0100 | <dminuoso> | If you have a function `f :: Int -> String -> Bool`, then applying `f` to a single argument produces the rest of that function |
2022-12-07 22:52:11 +0100 | <dminuoso> | So `f 10` has the type `String -> Bool` |
2022-12-07 22:52:18 +0100 | <dminuoso> | And `f 10 "Foo"` has type Bool |
2022-12-07 22:52:33 +0100 | <dminuoso> | seriously_guest | Yeah clear so far! to levelset though, I want to ensure were on the quest to explaining why (a -> b -> c) -> (f a -> f b -> f c) is useful in our example |
2022-12-07 22:52:38 +0100 | Topsi | (~Topsi@dyndsl-095-033-039-218.ewe-ip-backbone.de) |
2022-12-07 22:52:41 +0100 | <dminuoso> | So if we look at: |
2022-12-07 22:52:46 +0100 | <dminuoso> | liftA3 fun 1 2 3 |
2022-12-07 22:52:51 +0100 | <dminuoso> | (((liftA3 fun) 1) 2) 3 |
2022-12-07 22:53:32 +0100 | <dsal> | % liftA3 fun (Just 2) (Just 3) <$> [Just 1, Just 3, Just 5] |
2022-12-07 22:53:32 +0100 | <yahb2> | [Just 5,Just 15,Just 25] |
2022-12-07 22:53:34 +0100 | <dminuoso> | See how we could see this as first `liftA3 fun` turning `Int -> Int -> Int -> Int` into `Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int` |
2022-12-07 22:53:43 +0100 | <dminuoso> | Err |
2022-12-07 22:54:01 +0100 | <dminuoso> | liftA3 fun (Just 1) (Just 2) (Just 3) |
2022-12-07 22:54:07 +0100 | beteigeuze | (~Thunderbi@a79-169-109-107.cpe.netcabo.pt) |
2022-12-07 22:54:11 +0100 | <dminuoso> | (((liftA3 fun) (Just 1)) (Just 2)) (Just 3) |
2022-12-07 22:54:14 +0100 | eggplantade | (~Eggplanta@104-55-37-220.lightspeed.sntcca.sbcglobal.net) |
2022-12-07 22:54:39 +0100 | <dminuoso> | So after that lifting, we then apply the resulting function `Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int` to `Just 1`, producing a function of type `Maybe Int -> Maybe Int -> Maybe Int` and so forth. |
2022-12-07 22:55:01 +0100 | <dminuoso> | seriously_guest: Do you see why Im saying that focusing on what `liftA2` or `liftA3` do by themselves is not that useful? |
2022-12-07 22:55:02 +0100 | son0p | (~ff@S0106f88b37df247a.vn.shawcable.net) (Ping timeout: 246 seconds) |
2022-12-07 22:55:04 +0100 | <huskle> | so how do i use applicative to do this? |
2022-12-07 22:55:05 +0100 | <huskle> | https://paste.tomsmeding.com/3SrqURCW |
2022-12-07 22:55:11 +0100 | euandreh | (~Thunderbi@179.214.113.107) |
2022-12-07 22:55:18 +0100 | <dsal> | % iterate (liftA3 fun (Just 2) (Just 3)) (Just 1) |
2022-12-07 22:55:18 +0100 | <yahb2> | [Just 1,Just 5,Just 25,Just 125,Just 625,Just 3125,Just 15625,Just 78125,Just 390625,Just 1953125,Just 9765625,Just 48828125,Just 244140625,Just 1220703125,Just 6103515625,Just 30517578125,Just 152... |
2022-12-07 22:55:25 +0100 | <huskle> | see how the things in the list of list are functions? |
2022-12-07 22:55:37 +0100 | <huskle> | i want to apply them to a list of list of input arguments |
2022-12-07 22:56:12 +0100 | <dminuoso> | huskle: its your lucky day |
2022-12-07 22:56:20 +0100 | <dminuoso> | (Applicative f, Applicative g) => Applicative (Compose f g) |
2022-12-07 22:56:34 +0100 | <dminuoso> | The composition of two applicatives is an applicative too. |
2022-12-07 22:56:41 +0100 | <huskle> | using coerce? |
2022-12-07 22:56:53 +0100 | <dminuoso> | You can use coerce to get into Compose sure |
2022-12-07 22:57:03 +0100 | <dminuoso> | Or just manually wrap and unwrap |
2022-12-07 22:57:14 +0100 | <dminuoso> | Similarly your fmap can be avoided as well |
2022-12-07 22:57:26 +0100 | <dminuoso> | (that double fmap I mean) |
2022-12-07 22:57:26 +0100 | <huskle> | > [[+1]] <*> [[1]] |
2022-12-07 22:57:27 +0100 | <lambdabot> | error: |
2022-12-07 22:57:27 +0100 | <lambdabot> | A section must be enclosed in parentheses thus: (+ 1) |
2022-12-07 22:57:28 +0100 | codaraxis | (~codaraxis@user/codaraxis) |
2022-12-07 22:57:37 +0100 | <huskle> | > [[(+1)]] <*> [[1]] |
2022-12-07 22:57:39 +0100 | <lambdabot> | error: |
2022-12-07 22:57:39 +0100 | <lambdabot> | • Couldn't match expected type ‘[a1] -> b’ |
2022-12-07 22:57:39 +0100 | <lambdabot> | with actual type ‘[a0 -> a0]’ |
2022-12-07 22:57:40 +0100 | <dsal> | > [succ, pred] <*> [1..5] |
2022-12-07 22:57:42 +0100 | <lambdabot> | [2,3,4,5,6,0,1,2,3,4] |
2022-12-07 22:58:10 +0100 | <huskle> | where does the coerce go? |
2022-12-07 22:58:13 +0100 | <dminuoso> | % import Data.Functor.Compose |
2022-12-07 22:58:13 +0100 | <yahb2> | <no output> |
2022-12-07 22:59:25 +0100 | <huskle> | heres the smooth noise module again; https://paste.tomsmeding.com/zKMllsZH |
2022-12-07 22:59:29 +0100 | <dminuoso> | % import Data.Functor.Compose |
2022-12-07 22:59:29 +0100 | <yahb2> | <no output> |
2022-12-07 22:59:33 +0100 | <dminuoso> | % (Compose [[succ], [pred]]) <*> (Compose [[1..5], [2..3]]) |
2022-12-07 22:59:34 +0100 | euandreh | (~Thunderbi@179.214.113.107) (Remote host closed the connection) |
2022-12-07 22:59:35 +0100 | <dminuoso> | % (Compose [[succ], [pred]]) <*> (Compose [[1..5], [2..3]]) |
2022-12-07 22:59:35 +0100 | <yahb2> | Compose [[2,3,4,5,6],[3,4],[0,1,2,3,4],[1,2]] |
2022-12-07 22:59:55 +0100 | euandreh | (~Thunderbi@179.214.113.107) |
2022-12-07 22:59:57 +0100 | <dminuoso> | I would probably just write myself an ap2 rather |
2022-12-07 23:00:02 +0100 | euandreh | (~Thunderbi@179.214.113.107) (Client Quit) |
2022-12-07 23:00:03 +0100 | <dminuoso> | Seems more sane |
2022-12-07 23:00:12 +0100 | <huskle> | ok, so i just wrap the list of lists in compose and then unwrap |
2022-12-07 23:00:13 +0100 | <seriously_guest> | Alright here we go... So LiftA3 (\x y z -> x + y + z) (f Int) (f Int) (f Int) converts (Int -> Int -> Int) -> (f Int -> f Int -> f Int) |
2022-12-07 23:00:26 +0100 | kenaryn | (~aurele@cre71-h03-89-88-44-27.dsl.sta.abo.bbox.fr) (Quit: leaving) |
2022-12-07 23:00:38 +0100 | zq | (~zq@xorshift.org) () |
2022-12-07 23:00:43 +0100 | <dminuoso> | % ap2 f a = getCompose (Compose f `ap` Compose a) |
2022-12-07 23:00:43 +0100 | <yahb2> | <interactive>:14:33: error: ; • Variable not in scope: ; ap :: Compose f g a -> Compose f1 g1 a1 -> Compose f2 g2 a2 ; • Perhaps you meant one of these: ; ‘a’ (line 14), ‘ma... |
2022-12-07 23:00:49 +0100 | <dminuoso> | % import Control.Applicative |
2022-12-07 23:00:49 +0100 | <yahb2> | <no output> |
2022-12-07 23:01:01 +0100 | <dminuoso> | seriously_guest: For sake of clarity, pick a particular `f` |
2022-12-07 23:01:05 +0100 | <dminuoso> | seriously_guest: Lets pin it to `Maybe` |
2022-12-07 23:01:29 +0100 | <dminuoso> | There's a many reasons why thinking just about particular type is more helpful at the beginning |
2022-12-07 23:01:37 +0100 | <dsal> | seriously_guest: Also, off-by-one lift :) |
2022-12-07 23:01:49 +0100 | <dminuoso> | % ap2 f a = getCompose (Compose f `ap` Compose a) |
2022-12-07 23:01:49 +0100 | <yahb2> | <interactive>:18:33: error: ; • Variable not in scope: ; ap :: Compose f g a -> Compose f1 g1 a1 -> Compose f2 g2 a2 ; • Perhaps you meant one of these: ; ‘a’ (line 18), ‘ma... |
2022-12-07 23:02:01 +0100 | <dminuoso> | Oh its monad isnt it |
2022-12-07 23:02:07 +0100 | <dminuoso> | % ap2 f a = getCompose (Compose f <*> Compose a) |
2022-12-07 23:02:07 +0100 | <yahb2> | <no output> |
2022-12-07 23:02:24 +0100 | <dminuoso> | % [[succ], [pred]] `ap2` [[1..5], [2..3]] |
2022-12-07 23:02:24 +0100 | <yahb2> | [[2,3,4,5,6],[3,4],[0,1,2,3,4],[1,2]] |
2022-12-07 23:02:33 +0100 | <dsal> | "ap" being a monad seems like a silly wart. |
2022-12-07 23:02:37 +0100 | <dminuoso> | huskle: this is what I would do (well I would actually use #. in there as well) |
2022-12-07 23:02:47 +0100 | <dminuoso> | dsal: historical reasons, its from before applicative was a thing |
2022-12-07 23:02:50 +0100 | dsal | isn't good at wording right now |
2022-12-07 23:03:36 +0100 | <dminuoso> | % import Data.Coerce |
2022-12-07 23:03:36 +0100 | <yahb2> | <no output> |
2022-12-07 23:03:42 +0100 | <dminuoso> | % :set -XMagicHash |
2022-12-07 23:03:42 +0100 | <yahb2> | <no output> |
2022-12-07 23:04:18 +0100 | <dminuoso> | % (#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c); (#.) = coerce |
2022-12-07 23:04:18 +0100 | <yahb2> | <interactive>:28:67: error: ; • Couldn't match representation of type ‘c’ with that of ‘a -> c’ ; arising from a use of ‘coerce’ ; ‘c’ is a rigid type variable bound by ; ... |
2022-12-07 23:04:26 +0100 | <dminuoso> | % (#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c); (#.) _f = coerce |
2022-12-07 23:04:26 +0100 | <yahb2> | <no output> |
2022-12-07 23:04:38 +0100 | <dminuoso> | % ap2 f a = getCompose #. (Compose f <*> Compose a) |
2022-12-07 23:04:38 +0100 | <yahb2> | <interactive>:32:26: error: ; • Couldn't match expected type: a1 -> Compose f1 g1 a2 ; with actual type: Compose f g b ; • Possible cause: ‘(<*>)’ is applied to too many a... |
2022-12-07 23:04:46 +0100 | <huskle> | sorry that last paste had an error |
2022-12-07 23:04:47 +0100 | <huskle> | https://paste.tomsmeding.com/jqWTKDzk |
2022-12-07 23:06:00 +0100 | <seriously_guest> | So LiftA3, when given a function that operates on three values of type a, applied to 3 functors of type Maybe a, converts the given function (a -> a -> a -> a) into (Maybe a -> Maybe a -> Maybe a -> Maybe a)... |
2022-12-07 23:06:35 +0100 | <seriously_guest> | I'm definetly way better off then where I started lol |
2022-12-07 23:07:19 +0100 | <dminuoso> | seriously_guest: Mmm there falseties in that statement. |
2022-12-07 23:07:33 +0100 | <huskle> | https://paste.tomsmeding.com/wTdCxUik |
2022-12-07 23:07:33 +0100 | <dminuoso> | liftA3 will by itself do that conversion |
2022-12-07 23:07:42 +0100 | <huskle> | that has the version not using the magic hash |
2022-12-07 23:08:01 +0100 | <dminuoso> | I gotta do some pondering why my #. isnt working here |
2022-12-07 23:08:58 +0100 | <seriously_guest> | Ok so maybe let me step back and see how such a conversion can take place with actual code. For example again, lets define the function fn :: (Name -> String -> Employee) -> (Maybe Name -> Maybe String -> Maybe Employee) |
2022-12-07 23:09:16 +0100 | <dminuoso> | seriously_guest: Yes indeed! That sounds like a good excercise. |
2022-12-07 23:09:50 +0100 | <huskle> | whats it for anyway this #. |
2022-12-07 23:10:23 +0100 | <huskle> | % fn = liftA2 |
2022-12-07 23:10:24 +0100 | <yahb2> | <no output> |
2022-12-07 23:10:43 +0100 | <huskle> | % fn = liftA2 @Maybe |
2022-12-07 23:10:43 +0100 | <yahb2> | <no output> |
2022-12-07 23:10:50 +0100 | <huskle> | % :t fn |
2022-12-07 23:10:50 +0100 | <yahb2> | fn :: (a -> b -> c) -> Maybe a -> Maybe b -> Maybe c |
2022-12-07 23:11:15 +0100 | <dminuoso> | Ohh hold on, I see what's wrong. |
2022-12-07 23:11:27 +0100 | <huskle> | seriously_guest: its ok? |
2022-12-07 23:11:31 +0100 | <dminuoso> | I think its bedtime given that I thought (#.) was even needed. |
2022-12-07 23:11:47 +0100 | <huskle> | dont worry |
2022-12-07 23:11:49 +0100 | <dminuoso> | huskle: Its essentially a coercing (.) that ignores the left argument |
2022-12-07 23:11:57 +0100 | <dminuoso> | Here's an example of where its useful |
2022-12-07 23:12:01 +0100 | <huskle> | ok |
2022-12-07 23:12:03 +0100 | <dminuoso> | sum = getSum #. foldMap' Sum |
2022-12-07 23:12:26 +0100 | <dminuoso> | If we used (.) we could arise with some performance problems |
2022-12-07 23:12:40 +0100 | <seriously_guest> | fn g = maybeEmployee |
2022-12-07 23:12:55 +0100 | <seriously_guest> | sorry... didnt mean to hit enter |
2022-12-07 23:13:03 +0100 | <dminuoso> | No worries |
2022-12-07 23:14:24 +0100 | <dminuoso> | huskle: its mainly just useful in situations where you have eta reduced code and want to trip through newtypes |
2022-12-07 23:14:52 +0100 | <huskle> | eta reduction!? sounds fully jargon |
2022-12-07 23:15:14 +0100 | <dminuoso> | sum = getSum #. foldMap' Sum |
2022-12-07 23:15:16 +0100 | <dminuoso> | as opposed to |
2022-12-07 23:15:22 +0100 | <dminuoso> | sum xs = getSum (foldMap' Sum xs) |
2022-12-07 23:15:44 +0100 | <dminuoso> | Note that the obvious `sum = getSum . foldMap' Sum` can have performance issues |
2022-12-07 23:16:31 +0100 | <dminuoso> | tps://gitlab.haskell.org/ghc/ghc/-/issues/7542 |
2022-12-07 23:16:37 +0100 | <seriously_guest> | fn g = maybeEmployee where maybeEmployee (Nothing) (Nothing) = Nothing; maybeEmployee (Just _) (Nothing) = Nothing; maybeEmployee (Nothing) (Just _) = Nothing; maybeEmployee (Just name) (Just phone) = Maybe (Employee name phone) |
2022-12-07 23:17:30 +0100 | <seriously_guest> | ugh i didnt even apply g anywhere... im gonna go to bed myself |
2022-12-07 23:17:32 +0100 | <dminuoso> | Indeed, that looks correct. Note, that the parenthesis around nullary constructors like Nothing are not needed and should be omitted. |
2022-12-07 23:17:40 +0100 | <dminuoso> | Ah heh yeah |
2022-12-07 23:17:47 +0100 | <dminuoso> | Well you used `Employee` instead of `g` |
2022-12-07 23:18:06 +0100 | <seriously_guest> | :O |
2022-12-07 23:18:12 +0100 | <dminuoso> | But beyond that, its right. |
2022-12-07 23:18:30 +0100 | <dminuoso> | seriously_guest: note that for writing this out, there's a much much easier way |
2022-12-07 23:18:32 +0100 | <dminuoso> | and scalable way |
2022-12-07 23:18:38 +0100 | <seriously_guest> | Where do I donate haha... ive abused this room long enough |
2022-12-07 23:18:50 +0100 | <EvanR> | right here, over here |
2022-12-07 23:18:51 +0100 | <dminuoso> | (Also note that the data constructor is called Just, not Maybe) |
2022-12-07 23:19:11 +0100 | <dminuoso> | `maybeEmployee g (Just name) (Just phone) = Just (g name phone); maybeEmployee _ _ _ = Nothing` |
2022-12-07 23:19:14 +0100 | <huskle> | I WILL TAKE DONATIONS!! |
2022-12-07 23:19:27 +0100 | <dminuoso> | This style scales nicer, since it wont require me to elaborate all the combinations |
2022-12-07 23:19:30 +0100 | <iqubic> | huskle: For what? |
2022-12-07 23:19:34 +0100 | <huskle> | lol |
2022-12-07 23:19:37 +0100 | <huskle> | to not die |
2022-12-07 23:19:50 +0100 | <EvanR> | imagine if you will that Just and Nothing are color coded blue for value and Maybe is colored red for types |
2022-12-07 23:19:53 +0100 | <EvanR> | or something |
2022-12-07 23:20:09 +0100 | <EvanR> | this guy conor mcbride uses a lot of colors to keep it straight |
2022-12-07 23:20:23 +0100 | <dminuoso> | seriously_guest: And of course, we can just write this every time we need it. But we can more easily get the same by just writing `liftA2 g`, and have it work for an arbitrary g, or equivalently just write `g <$> maybeName <*> maybePhone` |
2022-12-07 23:21:45 +0100 | merijn | (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 268 seconds) |
2022-12-07 23:23:10 +0100 | <seriously_guest> | Gotcha... Id really like to see this logic from end to end; applied to the use case of possibly having null/empty data ... Not knowing how you can wrap possiblt null/empty values from an IO call inside a maybe, in haskell, is just making my brain skip |
2022-12-07 23:24:31 +0100 | <dminuoso> | seriously_guest: THat's part of why Im telling you to focus on just a particular type, like Maybe. |
2022-12-07 23:24:35 +0100 | <dminuoso> | Take small steps. |
2022-12-07 23:25:18 +0100 | <dminuoso> | Part of what makes Applicative special is that it generalized over these types in a lawful manner. But it is difficult to fully see and understand the pattern if you havent experimented and worked with individual instances. |
2022-12-07 23:25:53 +0100 | <tvandinther> | Design question: When would you justify making a typeclass over making the same functions pattern match a sum type? |
2022-12-07 23:26:10 +0100 | <dminuoso> | tvandinther: Probably never. |
2022-12-07 23:26:20 +0100 | <huskle> | how do you mean? |
2022-12-07 23:26:23 +0100 | <huskle> | classes rule |
2022-12-07 23:26:52 +0100 | <dminuoso> | I think a lot of typeclasses are ill-placed and not a good idea. |
2022-12-07 23:26:58 +0100 | troydm | (~troydm@host-176-37-124-197.b025.la.net.ua) |
2022-12-07 23:27:23 +0100 | <seriously_guest> | Yes i see, thank you... If I could maybe just write a quick service that calls some external function(api) which returns a employee as JSON... { "name": "jay", phone: null } and work with that |
2022-12-07 23:27:59 +0100 | <dminuoso> | seriously_guest: Sure, though that kind of interaction will require a combination of several libraries involving a variety of more complex ideas. |
2022-12-07 23:28:10 +0100 | <dminuoso> | So it may not be the best of ideas |
2022-12-07 23:28:25 +0100 | <tvandinther> | So say I had a few data structures which I want to prettyPrint, it would be advised to just make a single `prettyPrint` function that pattern matched the constructors of the various data structures? vs. creating a new `PrettyPrint a` typeclass that needs to implement `prettyPrint` |
2022-12-07 23:28:29 +0100 | <dminuoso> | HTTP interaction is not particularly pleasent, our libraries do not take shortcuts,. |
2022-12-07 23:28:47 +0100 | <dminuoso> | tvandinther: pretty printing is exactly the kind of thing typeclasses are absolutely poor at. |
2022-12-07 23:28:53 +0100 | <seriously_guest> | I know ): I've been on this journey for half a year now; started with the goal of writing the backends for my app in haskell... this is where im at currently |
2022-12-07 23:28:58 +0100 | <dminuoso> | I would just write `pprFoo`, `pprBar`, `pprQuux` functions as needed. |
2022-12-07 23:29:25 +0100 | <dminuoso> | The only value you get from a typeclass is remembering only a single name, but with ctags or HLS something like completion will address that for you |
2022-12-07 23:29:30 +0100 | <seriously_guest> | But off to bed now... thanks for everyones help... |
2022-12-07 23:29:35 +0100 | <dminuoso> | The price is that you cant have two pretty printing for the same type |
2022-12-07 23:29:45 +0100 | <dminuoso> | seriously_guest: Good night and good luck on your journey! |
2022-12-07 23:29:56 +0100 | <seriously_guest> | :) |
2022-12-07 23:30:02 +0100 | seriously_guest | (~seriously@2001:1c06:2715:c200:1a82:76d8:bd30:82fc) (Quit: Client closed) |
2022-12-07 23:30:18 +0100 | <dminuoso> | tvandinther: And further, you cant parameterize them (unless you start making even more typeclasses), you cant embed any information as to what it does |
2022-12-07 23:30:40 +0100 | <dminuoso> | and it introduces more brittleness since if the type switches, it may still end up pretty printing *something* (but quite possibly not what you intended) |
2022-12-07 23:30:52 +0100 | <tvandinther> | thats a good point |
2022-12-07 23:31:18 +0100 | <tvandinther> | you said never earlier, but is there really any condition in which a custom typeclass would be justified? |
2022-12-07 23:31:46 +0100 | <tvandinther> | Seems like its probably a tool reserved for libraries |
2022-12-07 23:31:53 +0100 | <dminuoso> | https://stackoverflow.com/a/74380240/6636995 is an answer of mine that goes into the subject in amore detailed manner |
2022-12-07 23:32:01 +0100 | <dminuoso> | it depends on who you ask |
2022-12-07 23:32:14 +0100 | <dminuoso> | but there is a certain consensus that typeclasses are best used for things that are lawful |
2022-12-07 23:32:23 +0100 | <dminuoso> | Such that you can infer laws from the typeclass usage itself |
2022-12-07 23:33:03 +0100 | <tvandinther> | and I presume laws don't change on a whim |
2022-12-07 23:33:19 +0100 | <tvandinther> | making the brittleness less of an issue |
2022-12-07 23:33:26 +0100 | <dminuoso> | Say if you have `a >> b >> c`, then you can associate it as `(a >> b) >> c` or `a >> (b >> c)` - and you can infer this from just seeing >> and knowing monad laws. |
2022-12-07 23:34:06 +0100 | <huskle> | hey! i finished my smooth noise thing and it works!! |
2022-12-07 23:34:24 +0100 | <huskle> | https://paste.tomsmeding.com/5h9Zleox |
2022-12-07 23:34:30 +0100 | <dminuoso> | tvandinther: Right. |
2022-12-07 23:34:30 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
2022-12-07 23:34:43 +0100 | <dminuoso> | tvandinther: my rule of thumb is that typeclasses are very rarely the right tool. |
2022-12-07 23:34:55 +0100 | <dminuoso> | Outside of situations where you're leveraging the type system |
2022-12-07 23:35:26 +0100 | <dminuoso> | Sometimes there's no immediate way around it like in Generic code (but I recently adopted the notion that you're probably better using TH for most of these anyway) |
2022-12-07 23:35:37 +0100 | <huskle> | erm, well actually it doesnt seem to work, those are supposed to be unifolrmly distributed on the unit interval |
2022-12-07 23:35:49 +0100 | <huskle> | but they are smooth wrt to changes in the params! |
2022-12-07 23:35:54 +0100 | Topsi | (~Topsi@dyndsl-095-033-039-218.ewe-ip-backbone.de) (Read error: Connection reset by peer) |
2022-12-07 23:36:01 +0100 | <huskle> | rrg.. |
2022-12-07 23:36:13 +0100 | <huskle> | see what i mean? |
2022-12-07 23:36:17 +0100 | <dminuoso> | tvandinther: and further, typeclasses are almost assuredly the worst thing for parsing/serializing/deserializing/decoding/encoding/pretty printing |
2022-12-07 23:36:25 +0100 | <dminuoso> | for the reasons outlined in my stackoverflow answer (and what I said earlier) |
2022-12-07 23:36:50 +0100 | <tvandinther> | Cool, good to know. It didn't feel like the right tool but good to understand some of the reasons beyond feeling haha |
2022-12-07 23:37:06 +0100 | <tvandinther> | Thanks |
2022-12-07 23:37:15 +0100 | <dminuoso> | wel "the worst thing" is a bit of a hyperbole. |
2022-12-07 23:37:24 +0100 | <huskle> | i think it must be averaging them or something... |
2022-12-07 23:37:38 +0100 | <huskle> | and some are negative? |
2022-12-07 23:37:45 +0100 | <dminuoso> | tvandinther: One thing where I do like typeclasses is classy lenses actually |
2022-12-07 23:37:47 +0100 | king_gs | (~Thunderbi@187.201.204.122) |
2022-12-07 23:37:49 +0100 | <huskle> | Why Are Some Negative!? |
2022-12-07 23:37:54 +0100 | <EvanR> | Yeah clearly you want to pretty print with Generics |
2022-12-07 23:38:21 +0100 | <huskle> | oh the seeds are negative.. |
2022-12-07 23:39:10 +0100 | <huskle> | nope that doesnt get it |
2022-12-07 23:39:21 +0100 | <dminuoso> | tvandinther: but this wildly depends on the usage scenario. In our SDN compiler, we we have over a dozen different notions of "network interface", but all of them have some CommonInterface, so its *very* useful to just express `f % commonInterface` without figuring out the exact types in the way when I just want that common structure they all share. |
2022-12-07 23:39:34 +0100 | <dminuoso> | That's driven by a HasCommonInterface typeclass |
2022-12-07 23:40:04 +0100 | <dminuoso> | (But here, the typeclass is directly tied to what is being produced, so there's no confusion ever |
2022-12-07 23:40:16 +0100 | <tvandinther> | EvanR: What would generics add to the pretty printing? |
2022-12-07 23:40:30 +0100 | <EvanR> | I'm half serious |
2022-12-07 23:40:38 +0100 | <EvanR> | since generics is accessed via type classes |
2022-12-07 23:40:55 +0100 | <EvanR> | but it does let you implement a pretty printer for all types at once |
2022-12-07 23:41:02 +0100 | <dminuoso> | tvandinther: better indentation. :p |
2022-12-07 23:41:16 +0100 | <dminuoso> | pretty-show/pretty-simple are amongst my staple libraries I add during debugging. |
2022-12-07 23:41:35 +0100 | <tvandinther> | Oh yes, I've seen the "Has" pattern of typeclassing with optparse-applicative. Seems like a nice way to do fluent construction of data of mildly different shapes. |
2022-12-07 23:41:39 +0100 | festive_kurbus | (~festive_k@user/kurbus) |
2022-12-07 23:41:42 +0100 | <dminuoso> | But then again, I dont want to add Generic just for the ability of nicer printing |
2022-12-07 23:42:13 +0100 | <dminuoso> | My recent experiences with Generics have proven that its really terrible. :( |
2022-12-07 23:42:57 +0100 | <dminuoso> | Had that one module with 33 data types, all deriving Generic, and using deriving-aeson to produce FromJSON and ToJSON instances. Simplifier ended up with 2 million types, compilation of that module with -O2 took about 4-5 minutes. |
2022-12-07 23:43:01 +0100 | <tvandinther> | I used a generic recently to "annotate" a type with additional data, is that a good use-case? |
2022-12-07 23:43:07 +0100 | <dminuoso> | Switched to TH equivalent code, and it went down to seconds.. |
2022-12-07 23:43:23 +0100 | <dminuoso> | tvandinther: Can you elaborate? |
2022-12-07 23:44:52 +0100 | <tvandinther> | I'm starting to doubt whether I am referring to the correct thing. I'm under the assumption that generic refers to a type like `data Wrapper a = Wrapper {...` |
2022-12-07 23:45:19 +0100 | <tvandinther> | But that's just my understanding of generics in an OOP context |
2022-12-07 23:45:40 +0100 | <dminuoso> | No, Generics is a meta programming technique |
2022-12-07 23:45:57 +0100 | <dminuoso> | As a random example: |
2022-12-07 23:46:56 +0100 | <dminuoso> | You can just slap `deriving Generic` onto an arbtirary data type Foo, then write `instance FromJSON Foo; instance ToJSON Bar` and by magic hands, you have two instances that can serialize and deserialize your data type from and into some JSON format |
2022-12-07 23:47:42 +0100 | <dminuoso> | So one can write up code that will behave depending on the type, in particular you can steer it based on things like constructor names, their types, etc.. |
2022-12-07 23:48:18 +0100 | <tvandinther> | How would that differ from `deriving (FromJSON, ToJSON)` |
2022-12-07 23:48:26 +0100 | <dminuoso> | It wouldnt |
2022-12-07 23:48:42 +0100 | <tvandinther> | same thing, different syntax? |
2022-12-07 23:48:50 +0100 | <dminuoso> | tvandinther: that mechanism is the same except it uses the DeriveAnyClass extension |
2022-12-07 23:49:01 +0100 | <dminuoso> | (it ends up doing the same) |
2022-12-07 23:49:25 +0100 | <tvandinther> | except that you can derive an instance in a different module from the type declaration? |
2022-12-07 23:49:29 +0100 | <dminuoso> | tvandinther: well the thing is |
2022-12-07 23:49:30 +0100 | huskle | (~huskle@250.79-105-213.static.virginmediabusiness.co.uk) (Ping timeout: 268 seconds) |
2022-12-07 23:49:35 +0100 | <dminuoso> | Ah hold on |
2022-12-07 23:49:42 +0100 | <dminuoso> | Slight misconfusion |
2022-12-07 23:49:45 +0100 | <dminuoso> | │23:48:18 tvandinther | How would that differ from `deriving (FromJSON, ToJS |
2022-12-07 23:49:48 +0100 | <dminuoso> | In principle this wont work |
2022-12-07 23:49:56 +0100 | <dminuoso> | Because GHC doesnt know how to derive FromJSON |
2022-12-07 23:50:25 +0100 | <dminuoso> | (With DeriveAnyClass you *can* write it, but then it amounts to just writing `instance FromJSON Foo` |
2022-12-07 23:50:37 +0100 | <dminuoso> | Note that you will not specify an implementation |
2022-12-07 23:50:44 +0100 | <dminuoso> | this works because FromJSON has a default implementation: |
2022-12-07 23:50:53 +0100 | <dminuoso> | default parseJSON :: (Generic a, GFromJSON Zero (Rep a)) => Value -> Parser a |
2022-12-07 23:50:58 +0100 | Tuplanolla | (~Tuplanoll@91-159-68-152.elisa-laajakaista.fi) (Quit: Leaving.) |
2022-12-07 23:51:02 +0100 | <tvandinther> | So they are the same provided you enable the language extension |
2022-12-07 23:51:20 +0100 | <dminuoso> | So as long as the type has `Generic`, then using the magic GFromJSON typeclass an implementation can be conjured. |
2022-12-07 23:51:40 +0100 | <dminuoso> | Which, beyond all the reasons I talked about earlier, has additional problems |
2022-12-07 23:52:24 +0100 | <dminuoso> | Because the way GFromJSON works, is that Generics produces very deeply nested complicated types that directly reflect the data structure of the type itself. One way to think of typeclasses and instances, is that they provide a type-level `case-of` |
2022-12-07 23:52:24 +0100 | <tvandinther> | And it can do this because there is an implementation for this typeclass for all base types, so generic derivations are algebraically constructed from those? |
2022-12-07 23:52:34 +0100 | <dminuoso> | So with typeclasses you can scrutinize types sort of.. |
2022-12-07 23:52:39 +0100 | <dminuoso> | Its not very direct |
2022-12-07 23:52:42 +0100 | <dminuoso> | Its not very fast either |
2022-12-07 23:53:10 +0100 | <dminuoso> | tvandinther: Well GHC knows how to derive Generic (assuming DeriveGeneric is enabled) |
2022-12-07 23:53:26 +0100 | <dminuoso> | Which is a typeclass that consists of two methods: |
2022-12-07 23:53:30 +0100 | <dminuoso> | And an associated type |
2022-12-07 23:53:45 +0100 | <tvandinther> | This sounds similar to Reflection in C# |
2022-12-07 23:53:49 +0100 | <dminuoso> | It very much is |
2022-12-07 23:53:52 +0100 | <dminuoso> | But it happens at compile time |
2022-12-07 23:53:56 +0100 | <dminuoso> | Via typeclasses and lookup |
2022-12-07 23:54:02 +0100 | <dminuoso> | The reflected type exists as a type itself |
2022-12-07 23:54:11 +0100 | <dminuoso> | And you generate code by pattern matching on that type with typeclass instances. |
2022-12-07 23:54:25 +0100 | <dminuoso> | And then there's a way to turn data into a generic representation |
2022-12-07 23:54:31 +0100 | <dminuoso> | that you can do the same scrutinization on data level too |
2022-12-07 23:54:43 +0100 | <dminuoso> | So we have hard to read/write code, that will compile extremely slowly |
2022-12-07 23:54:52 +0100 | <dminuoso> | And then there's a generic represnetation that GHC may not be able to get rid of |
2022-12-07 23:55:43 +0100 | <tvandinther> | I see, sounds interesting. A bit above my comfort level with Haskell still but good to be aware of. |
2022-12-07 23:55:43 +0100 | <dminuoso> | And further, once you have a Generic instance, *everybody* can pry into your object, encapsulation no longer possible |
2022-12-07 23:55:53 +0100 | <dminuoso> | Lots of bad ideas. |
2022-12-07 23:56:10 +0100 | <dminuoso> | TemplateHaskell can achieve many of the same problems |
2022-12-07 23:56:11 +0100 | <festive_kurbus> | sir this is a wendys |
2022-12-07 23:56:19 +0100 | <dminuoso> | But its *much* faster, and can easily generate optimal code |
2022-12-07 23:56:36 +0100 | huskle | (~huskle@250.79-105-213.static.virginmediabusiness.co.uk) |
2022-12-07 23:56:50 +0100 | <tvandinther> | Ah yep, sounds very familiar with the C# world. Reflection libraries are being replaced with codegen ones. |
2022-12-07 23:56:57 +0100 | <huskle> | ghci> all (>0) $ map (flip noise [0.900001..0.90001]) [1..1000] |
2022-12-07 23:56:57 +0100 | <huskle> | True |
2022-12-07 23:57:19 +0100 | <tvandinther> | Thanks for your explanations. Gotta get back to my day job now though :) |
2022-12-07 23:57:37 +0100 | litharge | (litharge@libera/bot/litharge) (Quit: restarting) |
2022-12-07 23:57:56 +0100 | litharge | (litharge@libera/bot/litharge) |
2022-12-07 23:59:30 +0100 | <huskle> | i cant see how it could possibly be getting negative values!! |
2022-12-07 23:59:35 +0100 | king_gs | (~Thunderbi@187.201.204.122) (Ping timeout: 264 seconds) |