Home liberachat/#haskell: Logs Calendar

Logs on 2022-12-07 (liberachat/#haskell)

00:12:11 × opticblast quits (~Thunderbi@secure-165.caltech.edu) (Ping timeout: 264 seconds)
00:13:30 king_gs joins (~Thunderbi@187.201.204.122)
00:17:54 × king_gs quits (~Thunderbi@187.201.204.122) (Ping timeout: 260 seconds)
00:21:07 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
00:24:37 king_gs joins (~Thunderbi@187.201.204.122)
00:28:55 × king_gs quits (~Thunderbi@187.201.204.122) (Ping timeout: 252 seconds)
00:35:39 × bjourne2 quits (~bjorn@94.191.136.201.mobile.tre.se) (Read error: Connection reset by peer)
00:41:22 Erutuon joins (~Erutuon@user/erutuon)
00:42:56 king_gs joins (~Thunderbi@187.201.204.122)
00:47:34 × king_gs quits (~Thunderbi@187.201.204.122) (Ping timeout: 256 seconds)
00:50:04 × use-value quits (~Thunderbi@2a00:23c6:8a03:2f01:2d36:9da8:a662:60e2) (Remote host closed the connection)
00:50:22 use-value joins (~Thunderbi@2a00:23c6:8a03:2f01:2d36:9da8:a662:60e2)
00:51:32 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 256 seconds)
01:02:10 × Kaiepi quits (~Kaiepi@108.175.84.104) (Ping timeout: 268 seconds)
01:06:08 <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
01:06:15 <Axman6> partition*
01:07:58 <dsal> lens probably has something for that.
01:08:31 use-value1 joins (~Thunderbi@2a00:23c6:8a03:2f01:69a2:269b:4e3d:1c6)
01:08:59 <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
01:10:17 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:111a:339b:4372:c307)
01:10:17 × albet70 quits (~xxx@2400:8902::f03c:92ff:fe60:98d8) (Remote host closed the connection)
01:10:23 × use-value quits (~Thunderbi@2a00:23c6:8a03:2f01:2d36:9da8:a662:60e2) (Ping timeout: 264 seconds)
01:10:23 use-value1 is now known as use-value
01:14:42 × xff0x quits (~xff0x@2405:6580:b080:900:f990:42a1:d746:59a8) (Ping timeout: 252 seconds)
01:14:50 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:111a:339b:4372:c307) (Ping timeout: 260 seconds)
01:14:56 king_gs joins (~Thunderbi@187.201.204.122)
01:15:35 × king_gs quits (~Thunderbi@187.201.204.122) (Client Quit)
01:15:53 king_gs joins (~Thunderbi@187.201.204.122)
01:16:24 albet70 joins (~xxx@2400:8902::f03c:92ff:fe60:98d8)
01:17:25 × AWizzArd quits (~code@gehrels.uberspace.de) (Ping timeout: 256 seconds)
01:17:31 × noctux quits (~noctux@user/noctux) (Ping timeout: 248 seconds)
01:17:31 AWizzArd joins (~code@gehrels.uberspace.de)
01:17:51 × mjacob quits (~mjacob@adrastea.uberspace.de) (Ping timeout: 260 seconds)
01:17:56 noctux joins (~noctux@user/noctux)
01:18:32 wroathe joins (~wroathe@207-153-38-140.fttp.usinternet.com)
01:18:32 × wroathe quits (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
01:18:32 wroathe joins (~wroathe@user/wroathe)
01:19:28 <zzz> h
01:19:30 mjacob joins (~mjacob@adrastea.uberspace.de)
01:26:26 Lumia joins (~Lumia@user/Lumia)
01:26:30 × raehik quits (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net) (Quit: WeeChat 3.7.1)
01:27:27 raehik joins (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net)
01:27:38 <[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
01:34:37 × troydm quits (~troydm@host-176-37-124-197.b025.la.net.ua) (Ping timeout: 252 seconds)
01:37:41 razetime joins (~quassel@49.207.203.213)
01:42:47 × zant quits (~zant@62.214.20.26) (Ping timeout: 264 seconds)
01:43:04 × raehik quits (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net) (Ping timeout: 260 seconds)
01:50:04 × tomokojun quits (~tomokojun@static-198-54-130-102.cust.tzulo.com) (Ping timeout: 260 seconds)
01:50:39 × gurkenglas quits (~gurkengla@p548ac72e.dip0.t-ipconnect.de) (Ping timeout: 260 seconds)
01:50:42 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
01:55:02 king_gs1 joins (~Thunderbi@2806:103e:29:94a4:81e0:429b:22ec:cf13)
01:55:03 × king_gs quits (~Thunderbi@187.201.204.122) (Read error: Connection reset by peer)
01:55:03 king_gs1 is now known as king_gs
01:59:58 sagax joins (~sagax_nb@user/sagax)
02:02:54 xff0x joins (~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp)
02:05:07 × Lumia quits (~Lumia@user/Lumia) (Quit: ,-)
02:07:01 bontaq joins (~user@ool-45779fe5.dyn.optonline.net)
02:09:56 × jao quits (~jao@cpc103048-sgyl39-2-0-cust502.18-2.cable.virginm.net) (Ping timeout: 248 seconds)
02:16:52 × Chai-T-Rex quits (~ChaiTRex@user/chaitrex) (Remote host closed the connection)
02:16:52 × chexum quits (~quassel@gateway/tor-sasl/chexum) (Remote host closed the connection)
02:16:52 × califax quits (~califax@user/califx) (Remote host closed the connection)
02:16:55 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection)
02:16:55 × ec_ quits (~ec@gateway/tor-sasl/ec) (Remote host closed the connection)
02:16:55 × azimut quits (~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection)
02:16:55 × jpds1 quits (~jpds@gateway/tor-sasl/jpds) (Remote host closed the connection)
02:17:21 jpds1 joins (~jpds@gateway/tor-sasl/jpds)
02:17:33 chexum joins (~quassel@gateway/tor-sasl/chexum)
02:17:36 ec_ joins (~ec@gateway/tor-sasl/ec)
02:17:57 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
02:17:58 azimut joins (~azimut@gateway/tor-sasl/azimut)
02:18:08 Chai-T-Rex joins (~ChaiTRex@user/chaitrex)
02:20:54 califax joins (~califax@user/califx)
02:21:58 zant joins (~zant@62.214.20.26)
02:22:23 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 264 seconds)
02:26:28 × zant quits (~zant@62.214.20.26) (Ping timeout: 248 seconds)
02:28:29 × chexum quits (~quassel@gateway/tor-sasl/chexum) (Remote host closed the connection)
02:28:50 chexum joins (~quassel@gateway/tor-sasl/chexum)
02:33:11 gimmeanickel joins (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0)
02:38:27 × ddellacosta quits (~ddellacos@static-198-44-136-91.cust.tzulo.com) (Ping timeout: 256 seconds)
02:40:31 ddellacosta joins (~ddellacos@static-198-44-136-134.cust.tzulo.com)
02:42:04 × Erutuon quits (~Erutuon@user/erutuon) (Ping timeout: 268 seconds)
02:42:47 × beteigeuze quits (~Thunderbi@bl14-81-220.dsl.telepac.pt) (Ping timeout: 264 seconds)
02:50:07 × Unicorn_Princess quits (~Unicorn_P@user/Unicorn-Princess/x-3540542) (Remote host closed the connection)
02:50:58 × money_ quits (~money@user/polo) (Quit: money_)
02:51:44 <Chai-T-Rex> How can I install the `split` package for the generic `ghci` command?
02:53:24 <Chai-T-Rex> Or, alternatively, how can I install it so that I can use some command line options to GHCi?
02:53:51 <c_wraith> are you comfortable using something like `cabal repl -b split` instead?
02:54:22 <Chai-T-Rex> As long as it reads `.ghc/ghci.conf`.
02:54:48 Lumia joins (~Lumia@user/Lumia)
02:56:28 <Chai-T-Rex> When I do that, it can't find the `array` package included with GHC.
02:58:04 <Chai-T-Rex> It also seems to delete some functions I'd defined in GHCi.conf.
03:01:08 <Chai-T-Rex> I found out that the unrecommended `cabal install --reinstall -O2 --lib split` works.
03:01:22 × jero98772 quits (~jero98772@2800:484:1d80:d8ce:efcc:cbb3:7f2a:6dff) (Remote host closed the connection)
03:08:08 <sm> chatgpt, compose me a command line to do haskell thing I want
03:09:22 <sm> heh. It says: ghci -package split -ghci-script ~/.ghc/ghci.conf
03:10:38 × use-value quits (~Thunderbi@2a00:23c6:8a03:2f01:69a2:269b:4e3d:1c6) (Remote host closed the connection)
03:10:57 use-value joins (~Thunderbi@2a00:23c6:8a03:2f01:69a2:269b:4e3d:1c6)
03:11:43 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:111a:339b:4372:c307)
03:13:23 × mmhat quits (~mmh@p200300f1c73b5136ee086bfffe095315.dip0.t-ipconnect.de) (Quit: WeeChat 3.7.1)
03:13:48 × Topsi quits (~Topsi@dyndsl-095-033-034-215.ewe-ip-backbone.de) (Read error: Connection reset by peer)
03:15:51 × bobbingbob quits (~dfadsva@2604:3d09:207f:f650::7b3a) (Ping timeout: 256 seconds)
03:16:10 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:111a:339b:4372:c307) (Ping timeout: 260 seconds)
03:16:56 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
03:17:38 × causal quits (~user@50.35.85.7) (Quit: WeeChat 3.7.1)
03:18:10 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
03:18:42 × gimmeanickel quits (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0) (Remote host closed the connection)
03:22:37 gimmeanickel joins (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0)
03:27:56 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 255 seconds)
03:28:45 × DigitalKiwi quits (~kiwi@2604:a880:400:d0::1ca0:e001) (Quit: quite.)
03:29:32 DigitalKiwi joins (~kiwi@2604:a880:400:d0::1ca0:e001)
03:30:47 × machinedgod quits (~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 268 seconds)
03:30:59 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
03:36:54 troydm joins (~troydm@host-176-37-124-197.b025.la.net.ua)
03:43:26 instantaphex joins (~jb@c-73-171-252-84.hsd1.fl.comcast.net)
03:45:20 × td_ quits (~td@83.135.9.33) (Ping timeout: 260 seconds)
03:45:30 × Lumia quits (~Lumia@user/Lumia) (Ping timeout: 256 seconds)
03:46:42 td_ joins (~td@83.135.9.15)
03:46:43 × gentauro quits (~gentauro@user/gentauro) (Read error: Connection reset by peer)
03:47:21 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
03:47:35 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:111a:339b:4372:c307)
03:52:20 × sloorush quits (~sloorush@52.187.184.81) (Ping timeout: 248 seconds)
03:52:27 gentauro joins (~gentauro@user/gentauro)
03:52:52 sloorush joins (~sloorush@52.187.184.81)
03:55:04 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
03:55:04 × chexum quits (~quassel@gateway/tor-sasl/chexum) (Remote host closed the connection)
03:55:04 × ec_ quits (~ec@gateway/tor-sasl/ec) (Remote host closed the connection)
03:55:04 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection)
03:55:53 chexum joins (~quassel@gateway/tor-sasl/chexum)
03:56:11 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
03:56:17 ec_ joins (~ec@gateway/tor-sasl/ec)
03:57:30 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
04:02:59 euandreh joins (~Thunderbi@179.214.113.107)
04:04:51 lisbeths joins (uid135845@id-135845.lymington.irccloud.com)
04:05:45 × euandreh quits (~Thunderbi@179.214.113.107) (Remote host closed the connection)
04:06:26 048AAH6AD joins (~Thunderbi@179.214.113.107)
04:16:13 <albet70> write a module, where the module file should be for import? is there an environment variable for the module path?
04:16:43 <albet70> what's the path 'import' will seek?
04:17:45 <sclv> without any additional flags to ghc or any cabal file it uses the cwd as the base
04:18:05 Lumia joins (~Lumia@user/Lumia)
04:19:39 <albet70> where cwd point?
04:19:46 × wroathe quits (~wroathe@user/wroathe) (Quit: leaving)
04:22:05 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 260 seconds)
04:22:27 <albet70> why it wouldn't import those custom modules where are on the same path with the caller?
04:23:40 <sm> @where paste, albet70
04:23:40 <lambdabot> I know nothing about paste,.
04:23:50 × motherfsck quits (~motherfsc@user/motherfsck) (Ping timeout: 260 seconds)
04:24:44 <sm> @where paste
04:24:44 <lambdabot> Help us help you: please paste full code, input and/or output at e.g. https://paste.tomsmeding.com
04:25:57 <albet70> sm https://paste.tomsmeding.com/nusGwMZC
04:26:29 mbuf joins (~Shakthi@49.204.118.69)
04:29:05 × freeside_ quits (~mengwong@103.252.202.193) (Ping timeout: 260 seconds)
04:29:08 × freeside quits (~mengwong@103.252.202.193) (Ping timeout: 248 seconds)
04:30:33 × shriekingnoise_ quits (~shrieking@186.137.167.202) (Quit: Quit)
04:32:50 <dsal> albet70: Custom.hs
04:33:05 <dsal> Doing this without a project is kind of hard mode, though.
04:33:07 <dsal> Same for Chai-T-Rex
04:36:41 <EvanR> imagine if you needed a project to run a bash script
04:37:06 <EvanR> actually maybe that's a workable discriminator for "scripting"
04:37:27 × Lumia quits (~Lumia@user/Lumia) (Ping timeout: 256 seconds)
04:39:08 motherfsck joins (~motherfsc@user/motherfsck)
04:39:29 <dsal> Also, you quite often *do*.
04:40:02 <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"
04:40:34 <EvanR> ok that's a dependency, not a build system or dependency management system
04:40:45 <EvanR> with additional files you have to have
04:41:07 <EvanR> to configure it
04:41:19 <dsal> Sure, these are also dependencies. People are wanting packages that aren't stock.
04:41:59 × werneta quits (~werneta@70-142-214-115.lightspeed.irvnca.sbcglobal.net) (Ping timeout: 256 seconds)
04:42:11 × king_gs quits (~Thunderbi@2806:103e:29:94a4:81e0:429b:22ec:cf13) (Ping timeout: 264 seconds)
04:42:19 <dsal> python has like, three different ways they've solved this problem so like, we're on par, I guess.
04:42:21 <EvanR> yeah, if you have the dependencies, then you still can't just compile the haskell code
04:42:39 <dsal> Similar with python virtualenv.
04:42:51 <EvanR> yeah so python isn't "scripting" anymore xD
04:42:54 <dsal> heh
04:43:00 <dsal> I've got python scripts I can't run anymore. :(
04:43:07 <dsal> Also, :) I don't like working in python
04:44:02 <sm> albet70: custom.hs should be Custom.hs
04:45:16 <albet70> ok
04:45:45 jpds2 joins (~jpds@gateway/tor-sasl/jpds)
04:46:14 × jpds1 quits (~jpds@gateway/tor-sasl/jpds) (Ping timeout: 255 seconds)
04:51:07 <albet70> if my cabal project is with 'executable' not as 'library', do I need to 'exposed-modules' for my own modules?
04:53:54 poljar joins (~poljar@93-139-83-160.adsl.net.t-com.hr)
04:54:25 <sm> I don't think so...
04:54:26 <sm> does it build ?
04:55:16 × poljar1 quits (~poljar@93-139-1-236.adsl.net.t-com.hr) (Ping timeout: 248 seconds)
04:57:19 × waleee quits (~waleee@h-176-10-137-138.NA.cust.bahnhof.se) (Ping timeout: 260 seconds)
05:02:45 × johnw quits (~johnw@2600:1700:cf00:db0:ccd8:6dba:13b3:7200) (Quit: ZNC - http://znc.in)
05:05:25 × gimmeanickel quits (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0) (Remote host closed the connection)
05:05:43 gimmeanickel joins (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0)
05:07:10 × gimmeanickel quits (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0) (Remote host closed the connection)
05:07:11 × Vajb quits (~Vajb@2001:999:504:3ad6:52a4:a3b5:32d8:e74d) (Read error: Connection reset by peer)
05:07:40 Vajb joins (~Vajb@hag-jnsbng11-58c3a5-27.dhcp.inet.fi)
05:08:51 <chreekat> It'll build regardless,I think
05:10:09 × jpds2 quits (~jpds@gateway/tor-sasl/jpds) (Remote host closed the connection)
05:10:31 jpds2 joins (~jpds@gateway/tor-sasl/jpds)
05:12:03 Lumia joins (~Lumia@user/Lumia)
05:13:59 money_ joins (~money@user/polo)
05:14:05 × sammelweis quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Read error: Connection reset by peer)
05:14:11 sammelweis_ joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
05:20:55 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
05:21:42 Erutuon joins (~Erutuon@user/erutuon)
05:23:12 <albet70> sm , no nedd for exposed-modules, it build
05:24:34 <jackdk> Where would the modules be exposed to? You can't depend on an executable from another library, ferexample.
05:26:48 × Vajb quits (~Vajb@hag-jnsbng11-58c3a5-27.dhcp.inet.fi) (Read error: Connection reset by peer)
05:27:26 Vajb joins (~Vajb@2001:999:504:3ad6:52a4:a3b5:32d8:e74d)
05:30:55 × Lumia quits (~Lumia@user/Lumia) (Ping timeout: 260 seconds)
05:33:33 <albet70> it should be listed in 'other-modules'
05:44:33 <dibblego> @src words
05:44:33 <lambdabot> words s = case dropWhile isSpace s of
05:44:33 <lambdabot> "" -> []
05:44:33 <lambdabot> s' -> w : words s'' where (w, s'') = break isSpace s'
05:52:26 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 256 seconds)
05:52:29 × np quits (~nerdypepp@user/nerdypepper) (Quit: bye)
05:52:31 werneta joins (~werneta@70-142-214-115.lightspeed.irvnca.sbcglobal.net)
05:53:47 nerdypepper joins (~nerdypepp@user/nerdypepper)
05:53:49 × tabaqui quits (~root@88.231.62.215) (Quit: WeeChat 3.7.1)
05:54:27 tabaqui joins (~root@88.231.62.215)
06:01:11 × stiell quits (~stiell@gateway/tor-sasl/stiell) (Remote host closed the connection)
06:02:26 freeside joins (~mengwong@103.252.202.193)
06:04:03 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
06:04:04 × califax quits (~califax@user/califx) (Write error: Connection reset by peer)
06:04:04 × jpds2 quits (~jpds@gateway/tor-sasl/jpds) (Write error: Connection reset by peer)
06:04:04 × Chai-T-Rex quits (~ChaiTRex@user/chaitrex) (Read error: Connection reset by peer)
06:05:09 califax joins (~califax@user/califx)
06:05:23 gimmeanickel joins (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0)
06:05:25 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
06:06:25 Chai-T-Rex joins (~ChaiTRex@user/chaitrex)
06:07:05 stiell joins (~stiell@gateway/tor-sasl/stiell)
06:07:19 × instantaphex quits (~jb@c-73-171-252-84.hsd1.fl.comcast.net) (Ping timeout: 260 seconds)
06:07:26 jpds2 joins (~jpds@gateway/tor-sasl/jpds)
06:08:52 × freeside quits (~mengwong@103.252.202.193) (Ping timeout: 248 seconds)
06:12:59 freeside joins (~mengwong@103.252.202.193)
06:17:22 takuan joins (~takuan@178-116-218-225.access.telenet.be)
06:17:35 × freeside quits (~mengwong@103.252.202.193) (Ping timeout: 264 seconds)
06:28:00 <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.
06:30:53 trev joins (~trev@user/trev)
06:32:54 <glguy> iqubic: look up : satisfy
06:38:11 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
06:41:23 × gimmeanickel quits (~gimmeanic@2405:9800:b640:c2eb:3422:7256:484b:e1c0) (Ping timeout: 260 seconds)
06:42:53 kenran joins (~user@user/kenran)
06:43:39 × lisbeths quits (uid135845@id-135845.lymington.irccloud.com) (Quit: Connection closed for inactivity)
06:44:34 × kenran quits (~user@user/kenran) (Remote host closed the connection)
06:45:56 × jpds2 quits (~jpds@gateway/tor-sasl/jpds) (Ping timeout: 255 seconds)
06:48:21 jpds2 joins (~jpds@gateway/tor-sasl/jpds)
06:48:25 × Chai-T-Rex quits (~ChaiTRex@user/chaitrex) (Remote host closed the connection)
06:49:39 Chai-T-Rex joins (~ChaiTRex@user/chaitrex)
06:50:48 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
06:51:23 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
06:59:43 Unicorn_Princess joins (~Unicorn_P@user/Unicorn-Princess/x-3540542)
07:03:16 × Erutuon quits (~Erutuon@user/erutuon) (Ping timeout: 256 seconds)
07:04:50 × incertia quits (~incertia@209.122.71.127) (Ping timeout: 260 seconds)
07:11:21 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
07:12:51 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
07:15:40 × bgs quits (~bgs@212-85-160-171.dynamic.telemach.net) (Remote host closed the connection)
07:18:04 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
07:20:40 akegalj joins (~akegalj@78-3-45-50.adsl.net.t-com.hr)
07:22:59 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 265 seconds)
07:24:05 × L29Ah quits (~L29Ah@wikipedia/L29Ah) (Ping timeout: 260 seconds)
07:26:12 lortabac joins (~lortabac@2a01:e0a:541:b8f0:1b9f:5d8:d1e3:a25a)
07:31:50 × Chai-T-Rex quits (~ChaiTRex@user/chaitrex) (Ping timeout: 255 seconds)
07:33:49 Chai-T-Rex joins (~ChaiTRex@user/chaitrex)
07:34:11 gimmeanickel joins (~gimmeanic@2405:9800:b640:c2eb:95ed:d852:31e3:4446)
07:34:18 × gimmeanickel quits (~gimmeanic@2405:9800:b640:c2eb:95ed:d852:31e3:4446) (Remote host closed the connection)
07:35:30 × jinsun quits (~jinsun@user/jinsun) ()
07:41:17 × bontaq quits (~user@ool-45779fe5.dyn.optonline.net) (Ping timeout: 252 seconds)
07:47:03 × razetime quits (~quassel@49.207.203.213) (Read error: Connection reset by peer)
07:47:16 razetime joins (~quassel@49.207.203.213)
07:48:36 michalz joins (~michalz@185.246.204.75)
07:50:40 lisbeths joins (uid135845@id-135845.lymington.irccloud.com)
07:52:43 incertia joins (~incertia@209.122.71.127)
07:53:14 Kaiepi joins (~Kaiepi@108.175.84.104)
08:03:37 zant joins (~zant@62.214.20.26)
08:03:50 jakalx parts (~jakalx@base.jakalx.net) ()
08:06:24 freeside joins (~mengwong@103.252.202.193)
08:07:21 freeside_ joins (~mengwong@103.252.202.193)
08:11:40 mncheck joins (~mncheck@193.224.205.254)
08:14:10 × use-value quits (~Thunderbi@2a00:23c6:8a03:2f01:69a2:269b:4e3d:1c6) (Remote host closed the connection)
08:14:29 use-value joins (~Thunderbi@2a00:23c6:8a03:2f01:69a2:269b:4e3d:1c6)
08:17:38 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
08:18:31 coot joins (~coot@213.134.171.3)
08:19:52 bjourne2 joins (~bjorn@94.191.136.236.mobile.tre.se)
08:21:10 × bjourne2 quits (~bjorn@94.191.136.236.mobile.tre.se) (Client Quit)
08:22:43 gmg joins (~user@user/gehmehgeh)
08:24:36 kazaf joins (~kazaf@37.112.34.29)
08:25:25 zeenk joins (~zeenk@2a02:2f04:a30d:4300::7fe)
08:26:02 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:111a:339b:4372:c307) (Remote host closed the connection)
08:28:58 fserucas__ joins (~fserucas@laubervilliers-657-1-66-228.w90-63.abo.wanadoo.fr)
08:32:52 Scraeling joins (~Scraeling@user/scraeling)
08:36:07 × sammelweis_ quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Quit: No Ping reply in 180 seconds.)
08:36:14 sammelweis joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
08:36:41 avicenzi joins (~avicenzi@2a00:ca8:a1f:b004::c32)
08:36:55 MajorBiscuit joins (~MajorBisc@2a02-a461-129d-1-193d-75d8-745d-e91e.fixed6.kpn.net)
08:36:57 × phma quits (phma@2001:5b0:2144:44d8:212c:2869:b063:882b) (Read error: Connection reset by peer)
08:37:38 phma joins (~phma@host-67-44-208-200.hnremote.net)
08:42:15 × MajorBiscuit quits (~MajorBisc@2a02-a461-129d-1-193d-75d8-745d-e91e.fixed6.kpn.net) (Ping timeout: 260 seconds)
08:43:11 MajorBiscuit joins (~MajorBisc@c-001-003-046.client.tudelft.eduvpn.nl)
08:45:49 × Sgeo quits (~Sgeo@user/sgeo) (Read error: Connection reset by peer)
08:48:48 × sammelweis quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Read error: Connection reset by peer)
08:49:54 sammelweis joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
08:53:16 machinedgod joins (~machinedg@d198-53-218-113.abhsia.telus.net)
08:53:40 use-value1 joins (~Thunderbi@2a00:23c6:8a03:2f01:556e:28e8:6695:53e8)
08:55:47 × use-value quits (~Thunderbi@2a00:23c6:8a03:2f01:69a2:269b:4e3d:1c6) (Ping timeout: 265 seconds)
08:55:47 use-value1 is now known as use-value
08:56:30 acidjnk_new joins (~acidjnk@p200300d6e7137a66c53ce5ddc06be1e3.dip0.t-ipconnect.de)
08:56:58 × fserucas__ quits (~fserucas@laubervilliers-657-1-66-228.w90-63.abo.wanadoo.fr) (Quit: Leaving)
08:57:09 fserucas joins (~fserucas@laubervilliers-657-1-66-228.w90-63.abo.wanadoo.fr)
08:59:13 functional joins (~functiona@119.8.243.19)
09:09:08 × ft quits (~ft@p508dbd59.dip0.t-ipconnect.de) (Quit: leaving)
09:14:14 × functional quits (~functiona@119.8.243.19) (Quit: Client closed)
09:14:19 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
09:16:09 kimiamania joins (~65804703@user/kimiamania)
09:23:54 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
09:25:40 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
09:26:31 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43)
09:28:23 × gmg quits (~user@user/gehmehgeh) (Ping timeout: 255 seconds)
09:28:23 × stiell quits (~stiell@gateway/tor-sasl/stiell) (Ping timeout: 255 seconds)
09:28:36 jakalx joins (~jakalx@base.jakalx.net)
09:29:41 stiell joins (~stiell@gateway/tor-sasl/stiell)
09:30:17 gmg joins (~user@user/gehmehgeh)
09:30:53 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43) (Ping timeout: 246 seconds)
09:31:57 alexiscott joins (~user@4.red-83-36-45.dynamicip.rima-tde.net)
09:34:14 CiaoSen joins (~Jura@p200300c95747e0002a3a4dfffe84dbd5.dip0.t-ipconnect.de)
09:42:36 × zeenk quits (~zeenk@2a02:2f04:a30d:4300::7fe) (Quit: Konversation terminated!)
09:45:25 gurkenglas joins (~gurkengla@p548ac72e.dip0.t-ipconnect.de)
09:46:34 szkl joins (uid110435@id-110435.uxbridge.irccloud.com)
09:47:43 ubert1 joins (~Thunderbi@2a02:8109:abc0:6434:3dae:2edc:412:e26e)
09:48:04 chele joins (~chele@user/chele)
09:51:47 × gmg quits (~user@user/gehmehgeh) (Ping timeout: 255 seconds)
09:52:45 nschoe joins (~q@141.101.51.197)
09:53:48 kalj joins (~kalj@78-71-20-170-no193.tbcn.telia.com)
09:53:54 × zant quits (~zant@62.214.20.26) (Ping timeout: 252 seconds)
09:57:37 raehik joins (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net)
09:59:20 × c_wraith quits (~c_wraith@adjoint.us) (Ping timeout: 255 seconds)
09:59:35 mtjm_ joins (~mutantmel@2604:a880:2:d0::208b:d001)
09:59:46 × Patternmaster quits (~georg@user/Patternmaster) (Ping timeout: 252 seconds)
10:00:15 × mtjm quits (~mutantmel@2604:a880:2:d0::208b:d001) (Ping timeout: 255 seconds)
10:00:31 <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
10:00:31 <kalj> (k,v), but if the data structure gets more complex, you get a lot of map's and lambda's.
10:00:34 Patternmaster joins (~georg@user/Patternmaster)
10:01:22 <dminuoso> kalj: Difficult to answer in a general manner.
10:01:32 c_wraith joins (~c_wraith@adjoint.us)
10:02:23 <dminuoso> To describe nested access and mutation, `lens` or `optics` are common solutions.
10:02:54 <kalj> dminuoso Thanks, I will have a look.
10:03:02 <dminuoso> So the access you described would be formulated as:
10:04:27 mtjm_ is now known as mtjm
10:05:18 <dminuoso> kalj: data & at "banana" %~ (++ ["newelem"])
10:05:40 <dminuoso> Which would work for `optics` at least.
10:06:05 <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.
10:06:29 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
10:07:01 <jackdk> Does optics have an `At` instance for alists?
10:07:22 <iqubic> What ar alists?
10:07:25 × tzh quits (~tzh@c-24-21-73-154.hsd1.wa.comcast.net) (Quit: zzz)
10:07:27 × xff0x quits (~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp) (Ping timeout: 255 seconds)
10:08:21 <dminuoso> jackdk: Ah good point, this should be written as `data & traversed & at "banana" %~ (++ ["newelem"])
10:08:38 <dminuoso> Gah. typo
10:08:44 <dminuoso> data & traversed % at "banana" %~ (++ ["newelem"])
10:09:19 <iqubic> What are alists in this context?
10:09:20 <iqubic> What are alists in this context?
10:09:28 <dminuoso> iqubic: [(k, v)]
10:09:49 <dminuoso> Come to think of it, maybe at wouldnt actually work
10:10:07 <dminuoso> So you need to use `ix`
10:10:44 <dminuoso> and that wouldnt work either, a0 ~ a1 => Ixed (a0, a1)
10:10:46 <dminuoso> Sigh mmm
10:11:01 <dminuoso> Then something like
10:11:09 <jackdk> iqubic: https://en.wikipedia.org/wiki/Association_list
10:11:58 × acidjnk_new quits (~acidjnk@p200300d6e7137a66c53ce5ddc06be1e3.dip0.t-ipconnect.de) (Ping timeout: 256 seconds)
10:12:41 <iqubic> jackdk: Neither Optics nor Lens provide a default for that type.
10:12:44 <dminuoso> Is there a kind of `eq :: s -> Getter s s`?
10:13:23 <dminuoso> Or no Getter is not enough. Should be Fold, perhaps
10:13:34 <iqubic> What are you trying to do here?
10:13:46 <iqubic> Fold is like Getter, but multiple targets.
10:14:19 Lord_of_Life_ joins (~Lord@user/lord-of-life/x-2819915)
10:14:36 <dminuoso> In optics lingo I would be looking for an AffineFold rather
10:15:00 × Lord_of_Life quits (~Lord@user/lord-of-life/x-2819915) (Ping timeout: 260 seconds)
10:15:08 <dminuoso> The relevant difference with a getter is that the fold could fail
10:15:17 <iqubic> Yeah... I see
10:15:20 <kalj> Amazing.
10:15:32 <dminuoso> kalj: Im conjuring up a proper solution for what you asked for, the above is wrong.
10:15:41 <jackdk> we've gone into the weeds kalj. I'll have something sensible for you in a sec
10:15:49 <jackdk> and then I'll go back into the weeds too ^^
10:16:07 <dminuoso> I guess I can use `filtered (== "foo")
10:16:37 <iqubic> What was Kalj's initial question?
10:16:42 <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
10:17:03 Lord_of_Life_ is now known as Lord_of_Life
10:17:14 acidjnk_new joins (~acidjnk@p200300d6e7137a66c53ce5ddc06be1e3.dip0.t-ipconnect.de)
10:17:33 <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."
10:18:12 <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
10:18:16 <dminuoso> let eqing a = unsafeFiltered (== a) in data & traversed % unsafeFilteredBy (_1 % eqing "banana") % _2 %~ (++ ["newelem"])
10:18:20 <dminuoso> This would work with optics.
10:18:25 <xerox> oh wrong channel, meant for aoc-spoilers
10:18:51 <dminuoso> kalj: Okay yes, for that general question `optics` or `lens` it that answer.
10:19:03 <dminuoso> Especially if the data can get quite nested.
10:19:13 <dminuoso> If its relatively shallow it may not be that useful
10:19:21 <kalj> @dmin Cool
10:19:21 <lambdabot> Not enough privileges
10:19:34 <kalj> :P
10:20:30 <jackdk> kalj: Here is a non-lensy way of attacking your problem https://www.irccloud.com/pastebin/IeHn3hi9/NotLensy.hs
10:20:43 <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`)
10:21:33 <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.
10:21:38 <dminuoso> Of course it should be said, that the deeper the nested access goes, the less fun writing it out will be.
10:22:36 <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`
10:22:50 <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)
10:23:04 <jackdk> Lemme check my misc repo, maybe I have a good example
10:23:38 <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`
10:24:34 <dminuoso> take note that jackdk's function is of type:
10:24:37 <dminuoso> alter :: (Maybe a -> Maybe a) -> Key -> IntMap a -> IntMap a
10:24:42 <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
10:24:43 <dminuoso> 'alter :: (Maybe a -> Maybe a) -> Key -> IntMap a -> IntMap a
10:24:49 <dminuoso> alistModify :: Eq k => k -> (Maybe v -> Maybe v) -> [(k, v)] -> [(k, v)]
10:25:01 <dminuoso> alter :: Ord k => (Maybe a -> Maybe a) -> k -> Map k a -> Map k a
10:25:06 <kalj> I am amazed!
10:25:08 <dminuoso> So this directly mimics `alter` from Map. :)
10:25:16 <kalj> Cool stuff, I definitely have some reading up to do
10:25:31 <kalj> Yeah, I should definitely use a Map in this case
10:26:25 <jackdk> Yeah, this all looked way harder because unlike lispers, we don't use association lists very much
10:27:24 <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..
10:27:52 <dminuoso> But it's quite a large dependency to include for just a singular use case.
10:28:47 <jackdk> I would strongly recommend learning lens **eventually**, because it's so useful, but first learn "normal" haskell
10:29:16 <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_
10:29:36 <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.
10:29:54 <dminuoso> At first glance that seems easy to write and useful
10:30:40 × troydm quits (~troydm@host-176-37-124-197.b025.la.net.ua) (Ping timeout: 256 seconds)
10:31:02 <dminuoso> Or mmm, no actually that would have to be an IxFold to work out
10:31:02 <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?
10:31:18 <dminuoso> Sure, but that's how it works anyway?
10:31:50 <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"
10:31:56 <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.
10:32:20 <dminuoso> Or gah, this wont work either. It needs IxTraversal really.
10:32:35 × lortabac quits (~lortabac@2a01:e0a:541:b8f0:1b9f:5d8:d1e3:a25a) (Ping timeout: 264 seconds)
10:33:03 <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)`
10:33:31 <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
10:33:34 <dminuoso> jackdk: I think an IxTraversal is more useful.
10:34:29 <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
10:34:49 <dminuoso> jackdk: You can use `trace` (and all similar trace* functions) to debug evaluation.
10:34:57 <dminuoso> https://hackage.haskell.org/package/base-4.17.0.0/docs/Debug-Trace.html#v:trace
10:34:59 <jackdk> dminuoso: I just said that
10:35:21 <jackdk> thanks for the haddock link though - should've posted that too
10:35:22 <dminuoso> jackdk: Oh, there was a weird line break in weechat, mentally I skipped what was above.
10:35:45 <dminuoso> Not sure why weechat does occacsionally print `- - - - - - ...`
10:36:35 <dminuoso> jackdk: Also, even your assoc should be an (Affine) traversal, rather than a `Lens'` onto a Maybe.
10:36:56 <dminuoso> Im not entirely sure why `at` uses Lens onto Maybe as well
10:37:19 <jackdk> dminuoso: because unlike `ix`, `at` allows you to create and delete entries. I wanted the same for `assoc`.
10:37:24 <mauke> xerox: what is aoc-spoilers?
10:37:25 <dminuoso> Ohhh
10:38:20 <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)
10:39:12 <kalj> Thanks, Debug.Trace helps!
10:39:15 <mauke> dminuoso: did you switch tabs in between? (i.e. is it a "last position before switch" marker?)
10:39:36 <dminuoso> mauke: not sure
10:40:17 <dminuoso> (though perhaps the Ix part is completely redundant, since you already have access to the key...)
10:41:02 <dminuoso> jackdk: Could Wither be a thing in lens/optics world?
10:41:22 <mauke> (I once implemented that feature as a ChatZilla add-on)
10:41:50 <dminuoso> type WitherLike f s t a b = (a -> f (Maybe b)) -> s -> f t
10:41:52 <dminuoso> type Wither s t a b = forall f. Applicative f => WitherLike f s t a b
10:41:54 <dminuoso> Mmmm
10:42:21 <dminuoso> That's cute :)
10:42:24 <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
10:51:23 mmhat joins (~mmh@p200300f1c73b5136ee086bfffe095315.dip0.t-ipconnect.de)
10:51:49 beteigeuze joins (~Thunderbi@bl14-81-220.dsl.telepac.pt)
10:53:12 <iqubic> Does that work with Lens?
10:56:36 × mmhat quits (~mmh@p200300f1c73b5136ee086bfffe095315.dip0.t-ipconnect.de) (Quit: WeeChat 3.7.1)
10:56:47 × econo quits (uid147250@user/econo) (Quit: Connection closed for inactivity)
11:00:23 × lisbeths quits (uid135845@id-135845.lymington.irccloud.com) (Quit: Connection closed for inactivity)
11:02:13 × fserucas quits (~fserucas@laubervilliers-657-1-66-228.w90-63.abo.wanadoo.fr) (Ping timeout: 256 seconds)
11:03:02 × bjourne quits (~bjourne@2001:6b0:1:1140:42bf:ff4:f8fa:50e5) (Quit: Konversation terminated!)
11:04:22 <xerox> mauke: #adventofcode-spoilers
11:04:40 × jmdaemon quits (~jmdaemon@user/jmdaemon) (Ping timeout: 256 seconds)
11:05:44 xff0x joins (~xff0x@ai071162.d.east.v6connect.net)
11:07:40 <jackdk> iqubic: It's got the same vague shape, so maybe?
11:08:23 <iqubic> Is Witherable ever gonna get added to the core Lens library?
11:12:24 × gurkenglas quits (~gurkengla@p548ac72e.dip0.t-ipconnect.de) (Ping timeout: 260 seconds)
11:15:02 × Chai-T-Rex quits (~ChaiTRex@user/chaitrex) (Ping timeout: 255 seconds)
11:15:50 zant joins (~zant@2a00:20:6017:5cfb:1db8:b3f9:e08:f0dd)
11:16:05 Chai-T-Rex joins (~ChaiTRex@user/chaitrex)
11:16:23 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 255 seconds)
11:18:52 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
11:20:18 × sammelweis quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Quit: No Ping reply in 180 seconds.)
11:21:36 sammelweis joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
11:23:35 × ec_ quits (~ec@gateway/tor-sasl/ec) (Ping timeout: 255 seconds)
11:25:59 zant1 joins (~zant@2a00:20:6017:5cfb:7889:b51c:c40a:b6bb)
11:26:04 ec_ joins (~ec@gateway/tor-sasl/ec)
11:27:05 × zant quits (~zant@2a00:20:6017:5cfb:1db8:b3f9:e08:f0dd) (Ping timeout: 255 seconds)
11:31:10 × razetime quits (~quassel@49.207.203.213) (Ping timeout: 268 seconds)
11:31:29 razetime joins (~quassel@49.207.203.213)
11:34:03 amano[m] joins (~amanocute@2001:470:69fc:105::2:d3f4)
11:34:53 lortabac joins (~lortabac@2a01:e0a:541:b8f0:ebf5:c68c:db4f:4f95)
11:42:36 o1lo01ol1o joins (~o1lo01ol1@2001:8a0:6a54:cb00:897b:5682:aa16:df9e)
11:42:45 <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?
11:43:10 × DigitalKiwi quits (~kiwi@2604:a880:400:d0::1ca0:e001) (Quit: quite.)
11:43:55 DigitalKiwi joins (~kiwi@137.184.156.191)
11:44:23 × zant1 quits (~zant@2a00:20:6017:5cfb:7889:b51c:c40a:b6bb) (Ping timeout: 252 seconds)
11:44:54 × kazaf quits (~kazaf@37.112.34.29) (Ping timeout: 256 seconds)
11:49:11 × haritz quits (~hrtz@user/haritz) (Quit: ZNC 1.8.2+deb2 - https://znc.in)
11:54:41 dextaa2 joins (~DV@user/dextaa)
11:57:04 × dextaa quits (~DV@user/dextaa) (Ping timeout: 268 seconds)
11:57:05 dextaa2 is now known as dextaa
12:00:28 jakalx parts (~jakalx@base.jakalx.net) ()
12:00:37 <albet70> is that any run-time exceptions are IO Exceptions?
12:01:30 <albet70> is 1/0 an exception?
12:02:38 <mauke> > 1/0
12:02:39 <[exa]> AFAIK there's no other reasonable way to "receive" an exception than IO (maybe ST)
12:02:39 <lambdabot> Infinity
12:03:03 <dminuoso> [exa]: ST cant have exceptions (and I finally understood why too!)
12:03:09 <xerox> > 1/(1/0)
12:03:10 <lambdabot> 0.0
12:03:16 <[exa]> dminuoso: ah okay, good. :D
12:03:27 × CiaoSen quits (~Jura@p200300c95747e0002a3a4dfffe84dbd5.dip0.t-ipconnect.de) (Ping timeout: 252 seconds)
12:03:51 <merijn> Dividing by 0 isn't an exception for Doubles
12:04:08 <merijn> It's just positive/negative infinity
12:04:30 <[exa]> > div 1 0
12:04:31 <dminuoso> albet70: And no, IO exceptions are separate from pure exceptions.
12:04:31 <lambdabot> *Exception: divide by zero
12:04:47 __monty__ joins (~toonn@user/toonn)
12:05:02 <dminuoso> albet70: THere's even semantic differences between them, see https://www.microsoft.com/en-us/research/publication/a-semantics-for-imprecise-exceptions/
12:05:06 <[exa]> dminuoso: btw what's the actual reason? (/me curious)
12:05:34 <mniip> [exa], you can catch them inside runST and now suddenly you're catching in pure code
12:05:48 <albet70> my real question is this https://hackage.haskell.org/package/scotty-0.12.1/docs/src/Web.Scotty.html#rescue
12:05:57 <[exa]> mniip: ah yes that makes sense
12:06:05 <albet70> I wonder how this 'rescue' handle exceptions
12:06:41 jakalx joins (~jakalx@base.jakalx.net)
12:06:52 <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
12:07:02 <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
12:07:04 zant1 joins (~zant@62.96.232.178)
12:07:18 <dminuoso> Which ends up calling `catch` like mniip pointed out
12:07:36 <[exa]> mniip: thanks!
12:07:56 <mniip> and IO's throw and catch are very thin wrappers around GHC RTS primitives (magic)
12:10:11 fserucas joins (~fserucas@laubervilliers-657-1-66-228.w90-63.abo.wanadoo.fr)
12:13:53 <albet70> there's a ContT r m a in that 'catch' and 'catchError'
12:15:59 × sammelweis quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Quit: No Ping reply in 180 seconds.)
12:16:09 sammelweis joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
12:17:33 <dminuoso> mniip: that at least makes is technically impossible as raiseIO# requires a monomorphic RealWorld parameterized state token
12:19:11 <mniip> dminuoso, there's some puity/referential transparency/... reason that I can't quite remember now
12:21:44 × 048AAH6AD quits (~Thunderbi@179.214.113.107) (Ping timeout: 256 seconds)
12:22:14 <dminuoso> mniip: raiseIO# throws precise exceptions, raise# throws imprecise exceptions. If you were allowed to throwIO# in ST, they could leak outside.
12:22:23 <dminuoso> And that would violate some optimizations and analysis
12:22:32 bgs joins (~bgs@212-85-160-171.dynamic.telemach.net)
12:24:25 <dminuoso> Though Im not entirely sure about runRW# in that respect, because unsafePerformIO would have the same problems mmm
12:24:36 euandreh joins (~Thunderbi@179.214.113.107)
12:25:00 <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?
12:25:13 <dminuoso> albet70: 1/0 actually is not an exception.
12:25:19 sammelweis_ joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
12:25:24 <dminuoso> Or at least not depending on which type you instantiate this at
12:26:18 <albet70> what about passing an String to (+), is that an exception?
12:26:24 <dminuoso> A runtime exception arises from `undefined`, `error "foo"`, missing patterns, etc..
12:26:34 <dminuoso> That is a type checker error.
12:26:39 <dminuoso> Potentially, anyway
12:26:58 <dminuoso> So `undefined`, `error "foo"`, missing patterns - these are examples of pure (and thus imprecise) exceptions
12:27:17 × sammelweis quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Ping timeout: 252 seconds)
12:27:28 <dminuoso> These are catchable using `evaluate :: a -> IO a`, but it is very important to understand what `imprecise` here means before using `evaluate`.
12:27:28 <albet70> (+) print print would get an 'error ...' right?
12:27:37 <dminuoso> No, it would just fail to compile.
12:27:41 <dminuoso> % (+) print print
12:27:41 <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...
12:28:42 <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)
12:29:06 <dminuoso> In most cases it will abort.
12:29:35 <albet70> could you give an example of pure exception?
12:29:42 <albet70> common example
12:29:42 <dminuoso> │13:26:58 dminuoso | So `undefined`, `error "foo"`, missing patterns - these are examples of pure (and thus imprecise) exceptions
12:30:24 <dminuoso> % (error "thing") + 2
12:30:24 <yahb2> *** Exception: thing ; CallStack (from HasCallStack): ; error, called at <interactive>:70:2 in interactive:Ghci13
12:30:55 <dminuoso> % putStr "foo" >> putStr (error "no!")
12:30:55 <yahb2> foo*** Exception: no! ; CallStack (from HasCallStack): ; error, called at <interactive>:72:25 in interactive:Ghci13
12:30:59 <albet70> but those are raised by your intension
12:31:09 <dminuoso> ^- note how the execution has already printed `foo` before the explosion?
12:31:23 <albet70> intention
12:31:37 <dminuoso> So there's two classes of when pure exceptions are found in Haskell code
12:32:10 <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.
12:32:48 <dminuoso> b) writing unsafe code, like `head (x:xs) = x; head [] = error "head: empty list"`
12:33:12 <dminuoso> The latter of which is often considered bad style especially in a standard library (because misusing it will usually terminate an entire program)
12:33:16 <dminuoso> The worst example of this is `read`
12:33:24 <dminuoso> If `read` fails, it will abort with a pure exception
12:33:44 <dminuoso> % (read "100-1") :: Int
12:33:44 <yahb2> *** Exception: Prelude.read: no parse
12:34:35 <dminuoso> So burying a `read` inside a library is particularly awful, because it can crash your program.
12:34:44 <dminuoso> Or any program that relies on that library.
12:34:56 <merijn> We should just delete read from existing :p
12:35:03 <dminuoso> +1
12:35:17 <merijn> Replace it with readMaybe
12:35:34 <dminuoso> Or better yet, proper parsing. :)
12:37:36 aliosablack joins (~chomwitt@2a02:587:7a0c:6a00:1ac0:4dff:fedb:a3f1)
12:37:40 <mniip> this is a question of sane defaults and there's no right answer
12:39:17 <merijn> eh
12:39:30 <merijn> readMaybe is the obvious right answer for sane default
12:39:33 <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?
12:39:37 <merijn> So, hard disagree with you there :p
12:40:47 <albet70> merijn, without read, how to turn string to Int?
12:41:49 <merijn> :t readMaybe
12:41:50 <lambdabot> error: Variable not in scope: readMaybe
12:41:53 <merijn> :O
12:41:59 <merijn> :t Text.Read.readMaybe
12:42:00 <lambdabot> Read a => String -> Maybe a
12:42:44 <dminuoso> Or `readEither` even
12:42:55 <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
12:43:44 CiaoSen joins (~Jura@p200300c95747e0002a3a4dfffe84dbd5.dip0.t-ipconnect.de)
12:48:30 Topsi joins (~Topsi@217.64.164.1)
12:48:49 Topsi1 joins (~Topsi@dyndsl-095-033-143-231.ewe-ip-backbone.de)
12:49:11 <albet70> merijn, how about remove Maybe since Either can do the exactly same thing
12:49:28 <merijn> readEither already exists too
12:49:52 <albet70> :t maybe
12:49:53 <lambdabot> b -> (a -> b) -> Maybe a -> b
12:50:58 × akegalj quits (~akegalj@78-3-45-50.adsl.net.t-com.hr) (Quit: leaving)
12:52:11 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
12:53:37 bontaq joins (~user@ool-45779fe5.dyn.optonline.net)
12:57:41 johnw joins (~johnw@2600:1700:cf00:db0:1da8:bc45:1742:a938)
13:01:00 <albet70> when b~IO b, maybe can turn a Maybe a to IO b, this is amazing I think
13:04:52 × sammelweis_ quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Quit: No Ping reply in 180 seconds.)
13:05:08 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Quit: = "")
13:05:11 × Scraeling quits (~Scraeling@user/scraeling) (Remote host closed the connection)
13:05:58 sammelweis joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
13:06:23 × o1lo01ol1o quits (~o1lo01ol1@2001:8a0:6a54:cb00:897b:5682:aa16:df9e) (Ping timeout: 260 seconds)
13:08:09 <albet70> IIRC there is module, I forget the name, replace Either with Exception?
13:08:59 <merijn> Sounds like a great way to get lynched by colleagues
13:11:52 <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 :-(
13:12:12 <freeside_> https://github.com/mengwong/adventofcode/blob/2022/apps/aoc2019-day16.hs#L64-L79
13:12:47 <kuribas> albet70: either (const $ throw myException) pure
13:12:56 <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
13:13:12 <freeside_> my runtimes are growing by 1, 2, 3, 4, 5, 6 seconds for the same size input
13:13:15 <kuribas> :t (id :: Int -> Int) --trev
13:13:16 <lambdabot> Int -> Int
13:13:58 dora joins (~dora@kwlan4.uoks.uj.edu.pl)
13:14:33 × freeside quits (~mengwong@103.252.202.193) (Quit: re-nick)
13:14:43 freeside_ is now known as freeside
13:16:52 <trev> kuribas i don't get it
13:17:06 <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 :(
13:17:10 <trev> how would the identify function work if i don't explicity give it the type?
13:17:16 <kuribas> :t (read :: String -> Int)
13:17:17 <lambdabot> String -> Int
13:17:41 <kuribas> trev: then it determines the type from the context.
13:17:54 <freeside> trev: if you want to be explicit about it, see https://github.com/mengwong/adventofcode/blob/0eaef98a90ee886b3ce9fe9ce2eb33336032deeb/apps/aoc2022-day04.hs#L12
13:18:25 <trev> i think it works if i just put `:: [Int] ` at the end
13:18:53 <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
13:19:03 <trev> :t (map read <$> lines) "1\n2" :: Int
13:19:04 <lambdabot> error:
13:19:04 <lambdabot> • Couldn't match type ‘[b0]’ with ‘Int’
13:19:04 <lambdabot> Expected type: [Char] -> Int
13:19:47 <trev> :t (map read <$> lines) "1\n2" :: [Int]
13:19:48 <lambdabot> [Int]
13:20:10 <trev> lol how do i get it to evaluate here?
13:20:51 <trev> % (map read <$> lines) "1\n2" :: [Int]
13:20:51 <yahb2> [1,2]
13:21:03 <trev> i should've scrolled up cause someone else just did this
13:23:40 causal joins (~user@50.35.85.7)
13:25:42 notzmv joins (~zmv@user/notzmv)
13:26:20 × sammelweis quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Ping timeout: 260 seconds)
13:27:01 sammelweis joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
13:27:52 zeenk joins (~zeenk@2a02:2f04:a30d:4300::7fe)
13:29:32 <merijn> freeside: Is this inside ghci?
13:30:24 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43)
13:31:22 <merijn> because while that is not efficient code, it should not blow up to 24GB
13:32:06 <kuribas> trev: but as merijn says, better never to use read.
13:33:23 <merijn> oh, wait I was looking at the wrong code for the blowup
13:34:10 <merijn> freeside: I see at least one memory blow up in your code
13:34:37 <merijn> Well, potential one, anyway
13:35:05 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43) (Ping timeout: 260 seconds)
13:36:36 <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
13:36:43 <merijn> V.fromList is gonna kill you
13:37:33 <merijn> freeside: What you want instead of that fromList is to use generate
13:37:35 <merijn> https://hackage.haskell.org/package/vector-0.13.0.0/docs/Data-Vector.html#v:generate
13:37:55 <kuribas> freeside: those strictness annotations don't look very useful.
13:38:12 <merijn> Since you have a fixed vector size and each element is directly generated from the index
13:38:24 Erutuon joins (~Erutuon@user/erutuon)
13:38:51 shriekingnoise joins (~shrieking@186.137.167.202)
13:39:06 <kuribas> freeside: also, if you want performance, don't use "(Monad m) => ..."
13:40:10 <kuribas> freeside: IO is already strict
13:40:25 <merijn> kuribas: ??
13:40:35 <merijn> Not sure if that's relevant, tbh
13:40:49 <merijn> and also his Monad m function should trivially specialise in code this simple
13:41:15 <merijn> freeside: Also, you should try running this code with "+RTS -sstderr" and see what that says
13:41:17 × azimut quits (~azimut@gateway/tor-sasl/azimut) (Ping timeout: 255 seconds)
13:41:48 <kuribas> merijn: in this case yes
13:42:17 <kuribas> freeside: and if you don't need lazy vectors, use unboxed vecors.
13:42:29 <kuribas> freeside: they will be an order of magnitude faster.
13:42:43 <merijn> oh, yes
13:43:08 <merijn> ok, so first thing to try would be: use unboxed vector + V.generate (instead of V.fromList)
13:43:13 <merijn> and see how much faster that is
13:43:44 <merijn> oh...
13:43:45 <merijn> also
13:43:48 <kuribas> merijn: "return $! toreturn" doesn't look so useful, or was that for the timing?
13:44:04 <merijn> you have a ghc-options field that is a billion miles long, but no -O?
13:44:14 × money_ quits (~money@user/polo) (Quit: money_)
13:44:54 <kuribas> maybe he needs to do toreturn `seq` getPOSIXTime instead then?
13:45:59 × acidjnk_new quits (~acidjnk@p200300d6e7137a66c53ce5ddc06be1e3.dip0.t-ipconnect.de) (Ping timeout: 256 seconds)
13:46:02 <merijn> kuribas: my comment was mostly that "IO is strict" and "$! probably does nothing there" are completely orthogonal
13:46:22 <kuribas> hmm, I suppose so...
13:47:13 <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"
13:47:14 <kuribas> in any case, toreturn with lazy vec will not be deep forced by $!
13:47:30 <kuribas> merijn: fair enough
13:48:15 <merijn> I'm not even done with my own AOC for today and I'm already nerdsniped...
13:48:19 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
13:49:18 × albet70 quits (~xxx@2400:8902::f03c:92ff:fe60:98d8) (Remote host closed the connection)
13:50:00 <kuribas> yeah, I should also do my actual job, which is some rather convoluted python code.
13:51:04 <dminuoso> 14:08:59 merijn | Sounds like a great way to get lynched by colleagues
13:51:17 <dminuoso> Not necessarily, cooking local functions `Maybe a -> IO a` is a very useful thing.
13:51:33 <merijn> dminuoso: I was referring to "renaming Either to Exception"
13:51:36 <dminuoso> Ah.
13:51:52 <kuribas> dminuoso: I do that, but make sure to prefix them with `unsafe`.
13:52:09 <dminuoso> Why unsafe?
13:52:26 <kuribas> because it can throw an exception.
13:52:29 <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
13:52:35 <dminuoso> IO already denotes the preseence of exceptions.
13:52:52 <dminuoso> And in fact, almost every IO action *can* produce exceptions.
13:53:02 <merijn> hmmm, I was trying to get baseline performance from the 2019 example
13:53:02 <dminuoso> Even something mundane as `putStrLn`
13:53:10 <kuribas> yes, one of the biggest haskell flaws
13:53:11 <merijn> but I'm not patient enough to wait xD
13:53:15 <dminuoso> Not sure about flaw, really.
13:53:43 <dminuoso> IO exceptions are great, especially with the extensione hiararchy of exceptions
13:53:53 <merijn> dminuoso: You know what would be better?
13:53:59 <merijn> dminuoso: Checked IO exceptions! :p
13:54:04 <dminuoso> merijn: Sure.
13:54:20 <dminuoso> If someone had a *good* way of incorporating that into the type system, Id be game for it.
13:54:45 <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
13:55:06 <merijn> dminuoso: I'm still occasionally working on a sketch for that
13:55:14 <merijn> and now I no longer have my thesis distracting me :p
13:55:19 <merijn> Just videogames :p
13:55:21 <freeside> kuribas: thanks, i am trying a few of your suggestions in turn
13:55:25 albet70 joins (~xxx@2400:8902::f03c:92ff:fe60:98d8)
13:55:33 <dminuoso> And even without checked exceptions, IO exceptions are still great.
13:56:09 <kuribas> dminuoso: right, those "unsafe" functions where not in IO.
13:56:12 <freeside> so, i tried unboxed vectors, and it ran slower, though maybe after I try a few other things, unboxed will be faster.
13:56:20 <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
13:56:28 <dminuoso> kuribas: I dont use those. I tend to drag IO very deeply through programs.
13:56:32 × __monty__ quits (~toonn@user/toonn) (Quit: leaving)
13:56:38 <dminuoso> Because as it turns out, this is very useful for getting good diagnostics.
13:56:48 <dminuoso> And at that point you get nice catch control
13:57:12 <dminuoso> And best of all - IO exceptions let you preserve MonadUnliftIO :)
13:57:22 <freeside> merijn: i have smaller input sets, if you'd like; i'll check them in.
13:57:25 <merijn> dminuoso: People always underestimate how pleasant IO heavy Haskell is :)
13:58:04 <kuribas> haskell is the best imperative language :)
13:58:15 <dminuoso> merijn: Indeed. It was GHC that actually demonstrated to me how nice it was.
13:58:23 <dminuoso> Given that virtuall all of GHC runs in IO
13:58:48 <dminuoso> (Yes it has lots of pure code, but it has a very IO centric spine)
14:00:19 × albet70 quits (~xxx@2400:8902::f03c:92ff:fe60:98d8) (Remote host closed the connection)
14:01:13 <freeside> so, the Vec.fromList on line 45, undesirable because, why?
14:01:20 × sammelweis quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Ping timeout: 260 seconds)
14:01:25 troydm joins (~troydm@host-176-37-124-197.b025.la.net.ua)
14:01:32 <merijn> freeside: dynamically building vectors of unknown length is expensive
14:01:40 <freeside> I can switch it to use a generate -- the genBase function on 31 is basically that already.
14:01:40 × kalj quits (~kalj@78-71-20-170-no193.tbcn.telia.com) (Quit: Client closed)
14:01:54 <merijn> freeside: Because you keep having to reallocate and copy each time your original vector is too small
14:01:57 sammelweis joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
14:02:03 <freeside> and then it gets the `n` out of the input by using a simple ! then
14:02:14 <merijn> freeside: V.generate takes a static length so it will just allocate and initialise in place once
14:02:48 <merijn> Allocate once + fill is always gonna be more efficient than a dynamic approach :)
14:02:57 <merijn> It plays nicer with fusion too
14:03:08 o1lo01ol1o joins (~o1lo01ol1@2001:8a0:6a54:cb00:897b:5682:aa16:df9e)
14:03:25 <dminuoso> How does Data.Vector.fromList work then?
14:04:43 × dora quits (~dora@kwlan4.uoks.uj.edu.pl) (Ping timeout: 260 seconds)
14:05:01 <dminuoso> And shouldnt you be able to use fromListN at least, given that the length is statically known?
14:05:15 accord joins (uid568320@id-568320.hampstead.irccloud.com)
14:05:22 <merijn> dminuoso: Then you still end up pointlessly creating a list and stuff
14:05:33 swamp_ joins (~zmt00@user/zmt00)
14:05:44 <dminuoso> Fair
14:05:44 <merijn> And the actual function here is trivially rewritable as a function of vector index
14:06:16 <merijn> (since it's just a function looped over values 1 through l)
14:06:27 albet70 joins (~xxx@2400:8902::f03c:92ff:fe60:98d8)
14:06:45 <merijn> So just need to offset it by 1 to work of 0 based indices
14:07:30 <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?
14:07:53 <dminuoso> Wouldnt it be cheaper to scan the length of the list first?
14:08:04 <merijn> Depends how long your list is
14:08:14 <merijn> Also, if your list is giant and lazy that's gonna blow up
14:08:19 <freeside> my list has 6.5 million elements
14:08:23 <dminuoso> It would blow up regardless on the allocation, no>
14:08:37 <freeside> i was hoping that unboxed it would take 6.5 megs in ram
14:08:49 <dminuoso> Or is the point that the cons cell is more expensive than potentially the element size in the vector?>
14:09:08 × zmt01 quits (~zmt00@user/zmt00) (Ping timeout: 246 seconds)
14:09:19 <merijn> dminuoso: If your vector operations fuse into a Vector.sum, then it doesn't have to
14:09:22 <dminuoso> Or even that seems unlikely given that Vector has boxed elements
14:09:46 <dminuoso> merijn: is there RULES in place to elide the vector for that?
14:10:02 <dminuoso> Ah I guess there must be
14:10:08 <dminuoso> That explains the fusion framework then
14:10:15 <merijn> dminuoso: That's the entire point of vector's fusion framework, no? :p
14:10:27 <dminuoso> Wouldnt know honestly, never looked at vector. :()
14:10:38 <merijn> :O
14:10:40 <merijn> Vector is nice
14:11:08 <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
14:11:26 <merijn> overall this solution feels slower than it, naively, should be
14:11:39 L29Ah joins (~L29Ah@wikipedia/L29Ah)
14:12:01 <merijn> but also, I'm not 100% sure I follow what it's doing, so... :p
14:12:03 <dminuoso> Okay so things are falling into place now.
14:12:04 × shapr quits (~user@68.54.166.125) (Ping timeout: 260 seconds)
14:12:15 <dminuoso> Data.Text.pack goes through a stream framework as well
14:12:17 <dminuoso> Presumably for the same reason?
14:12:28 <freeside> sorry, i should have also shared the original problem. https://adventofcode.com/2019/day/16
14:12:37 <freeside> basically, this is a matrix multiplication problem.
14:12:42 <dminuoso> "TEXT length/pack -> P.length" forall t. length (pack t) = P.length t
14:12:46 <dminuoso> Ah-ha!
14:12:59 <dminuoso> Libraries are suddenly starting to make sense. :)
14:13:00 <freeside> however, because the matrix is 6.5M x 6.5M, fitting everything into RAM is difficult.
14:13:09 <merijn> oh, wait, this is FFT?
14:13:21 <freeside> the name of the thing is FFT, but reading the question, i don't think it's FFT.
14:13:28 <freeside> it's closer to a repeated block cipher
14:14:00 <merijn> Well, one clue is that FFT has recursive sharing between the blocks of a transform
14:14:27 <merijn> So I think the problem might be "spot the recursive sharing of your computation" rather than trying to make the naive computation faster
14:14:44 <merijn> I think last year had a similar exponential blow up puzzle
14:17:07 <merijn> the puzzle formulation seems to also strongly hint at recursive sharing
14:17:52 <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
14:18:52 <freeside> i would be grateful, thank you
14:19:09 <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
14:20:07 <merijn> freeside: https://github.com/merijn/AdventOfCode/blob/master/2021/Day14.hs
14:21:13 freeside looks
14:22:21 <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
14:22:28 <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")
14:22:39 <merijn> I expect this day 16 puzzle has a similar trick
14:22:48 <merijn> You just gotta find it
14:22:51 jakalx parts (~jakalx@base.jakalx.net) (Error from remote client)
14:23:38 <merijn> Especially since the entire thing FFT is famous for is being fast due to clever recursive sharing tricks
14:26:38 <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.
14:27:08 <merijn> freeside: It took me hours of trying to make my function faster before I realised that last year too
14:27:25 <kuribas> freeside: garbage collection?
14:27:36 <freeside> i force a performGC at the top of every "go"
14:27:46 <merijn> I actually spend *a lot* of effort on my original solution to have a clever streaming solution which was constant space
14:27:49 <merijn> And it actually worked
14:28:00 <merijn> in that I never had memory blow up, it just took forever to compute xD
14:28:07 <merijn> freeside: Actually, what if you don't?
14:28:07 <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
14:28:22 <merijn> freeside: unnecessary GC can really fuck you over :p
14:28:34 <freeside> hm, ok, let me try a/b testing that next.
14:29:01 <merijn> freeside: If you have inputs that finish in reasonable time, try that while passing "+RTS -sstderr"
14:29:03 <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.
14:29:19 <merijn> (or "-- +RTS -sstderr" if you use "cabal run", else you pass the flags to cabal :p)
14:29:23 <money> mine never goes on
14:29:40 <merijn> freeside: That will report GC info and memory usage
14:30:20 × albet70 quits (~xxx@2400:8902::f03c:92ff:fe60:98d8) (Remote host closed the connection)
14:30:23 <merijn> If you have a big live set (you probably do) GC can waste *a lot* of time
14:30:51 <freeside> can i just run stack --profile to get the RTS?
14:31:00 <merijn> --profile is different
14:31:01 <freeside> i've been using stack run instead of cabal
14:31:15 <merijn> freeside: Presumably "-- +RTS -sstderr" works with stack too
14:31:28 <freeside> ok, i will incant
14:31:33 × o1lo01ol1o quits (~o1lo01ol1@2001:8a0:6a54:cb00:897b:5682:aa16:df9e) (Ping timeout: 260 seconds)
14:31:54 <merijn> You might need to compile with -rtsopts (i.e. add -rtsopts to you ghc-options)
14:34:50 × ec_ quits (~ec@gateway/tor-sasl/ec) (Ping timeout: 255 seconds)
14:34:59 elevenkb joins (~elevenkb@105.184.79.224)
14:35:27 <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
14:35:39 <merijn> (which is "time not spend doing GC / total time")
14:35:57 <merijn> Productivity below 80% is generally a red flag
14:36:27 albet70 joins (~xxx@2400:8902::f03c:92ff:fe60:98d8)
14:36:28 <merijn> (which is why you wanna test the performGC stuff with the GC reporting, you wanna check it's not wrecking your productivity)
14:36:34 acidjnk_new joins (~acidjnk@p200300d6e7137a767ca9aed60fa8d1f2.dip0.t-ipconnect.de)
14:37:00 ec_ joins (~ec@gateway/tor-sasl/ec)
14:37:00 jakalx joins (~jakalx@base.jakalx.net)
14:41:24 <freeside> currently fighting with package.yaml to get rtsopts behaving
14:41:51 <albet70> is (liftIO x) >> (liftIO y) == liftIO $ x >> y?
14:42:15 festive_kurbus joins (~festive_k@user/kurbus)
14:43:19 <c_wraith> albet70: did you check the docs?
14:43:48 <albet70> not yet
14:44:05 <c_wraith> albet70: (yes, it is. But that's something the docs say)
14:48:45 <trev> why does it keep telling me that `x` is a Char instead of String? https://paste.tomsmeding.com/zfwaa9wr
14:48:51 [itchyjunk] joins (~itchyjunk@user/itchyjunk/x-7353470)
14:48:55 <albet70> https://hackage.haskell.org/package/conduit-1.3.4.3/docs/Conduit.html#t:MonadIO
14:49:13 <albet70> liftIO (m >>= f) = liftIO m >>= (liftIO . f)
14:51:14 <albet70> c_wraith , it is >>= not >> in the docs
14:51:25 <c_wraith> so use your algebra
14:51:29 <c_wraith> it's just a bit of rewriting
14:52:17 <c_wraith> m >> n === m >>= \_ -> n
14:53:33 king_gs joins (~Thunderbi@187.201.204.122)
14:53:51 <dminuoso> trev: Because you pattern match on [x : xs], presumably you meant (x:xs)
14:54:12 <money> xxx
14:54:22 dora joins (~dora@rivendell.ksi.ii.uj.edu.pl)
14:54:30 <trev> O___O
14:54:33 <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`
14:54:38 <dminuoso> Note that `type String = [Char]`
14:54:57 <trev> i actually tried [x:xs] and the formatter kept fixing it LOL
14:55:01 <dminuoso> Which is why something like `case "foo" of x:xs -> ...` will work :)
14:55:16 <merijn> freeside: You should be able to just edit -rtsopts into the ghc-options in your cabal file
14:55:23 <dminuoso> Binding `x` to 'f' and xs to "foo"
14:55:26 <dminuoso> "oo" I meant.
14:55:49 <merijn> ah, wait you're using hpack
14:56:00 <dminuoso> trev: iow "foo" is just syntax sugar for 'f' : 'o' : 'o' : []
14:56:12 <trev> dminuoso oh man, i missed that it was a bracket and not parens
14:56:13 <merijn> My biased advise would be to just ditch hpack, tbh.
14:56:20 <trev> i've been at the computer too long..
14:56:35 <trev> dminuoso thank you
14:56:37 <freeside> because i am using stack, for my sins, i am trying to `lift` that instruction over hpack's package.yaml
14:56:49 <dminuoso> freeside: You can use stack without hpack just fine.
14:57:01 <freeside> i will try.
14:57:53 <dminuoso> Im not sure why stack defaults to it anyway
14:58:03 <dminuoso> The .cabal file format is pretty much fine?
14:58:20 <dminuoso> With hpack you need to learn both the hpack syntax *and* the corresponding cabal generated code and semantics.
14:58:26 <dminuoso> With cabal.. just the second part.
14:58:56 <freeside> yar. let me come back after i have flensed package.yaml from my setup
14:59:02 <dminuoso> Not to mention, that you want a .cabal file anyway for non-stack users to use your code...
14:59:11 <merijn> freeside: Stack does not require hpack/package.yaml, it just happens to automatically invoke hpack when needed
14:59:20 <merijn> dminuoso: to be fair, he has a .cabal file checked in
15:00:05 <dminuoso> Im just saying that hpack adds more complication since you need to keep that synchronized.
15:00:17 shapr joins (~user@68.54.166.125)
15:00:32 <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
15:00:44 <merijn> If you're gonna have a custom format it might as well be first class
15:00:51 <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.
15:01:06 <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.
15:01:29 Sgeo joins (~Sgeo@user/sgeo)
15:01:54 <dminuoso> Mostly because you still need to learn a special format, because youc ant just write arbitrary YAML and expect it to make sense..
15:01:56 × EvanR quits (~EvanR@user/evanr) (Remote host closed the connection)
15:02:18 <dminuoso> The only difference is that the whitespace layouting rules are clear...
15:02:22 <dminuoso> Or uniform.
15:02:27 EvanR joins (~EvanR@user/evanr)
15:02:41 <merijn> dminuoso: People are still actively arguing for it on github
15:02:42 <dminuoso> (But then again, the whitespace rules in YAML are quite absurd)
15:02:52 <merijn> So please register your displeasure for the idea >.>
15:03:04 <dminuoso> Where on github?
15:03:56 <merijn> dminuoso: https://github.com/haskell/cabal/issues/8605 https://github.com/haskell/cabal/issues/7548
15:05:06 akegalj joins (~akegalj@180-243.dsl.iskon.hr)
15:06:11 <merijn> obligatory "I implemented a TOML to cabal program!" that then only uses 10% of the syntax/feature of cabal files >.>
15:07:46 × sammelweis quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Ping timeout: 256 seconds)
15:08:38 sammelweis joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
15:11:00 kenran joins (~user@user/kenran)
15:12:11 × sammelweis quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Client Quit)
15:12:58 × kenran quits (~user@user/kenran) (Remote host closed the connection)
15:13:17 sammelweis joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
15:21:22 × foul_owl quits (~kerry@193.29.61.77) (Ping timeout: 256 seconds)
15:21:37 × festive_kurbus quits (~festive_k@user/kurbus) (Quit: Client closed)
15:25:13 × king_gs quits (~Thunderbi@187.201.204.122) (Ping timeout: 260 seconds)
15:28:50 <freeside> woohoo! i figured out RTS, and now i have output: https://github.com/mengwong/adventofcode/commit/71d6e5a83f092c58aee8126ed31a05b600c8b80d#commitcomment-92308201
15:29:22 <freeside> am tempted to turn on profiling and draw the heap profile using hp2ps
15:30:34 <freeside> 3,097,783,264 bytes maximum residency
15:30:39 <freeside> Productivity 1.2% of total user, 6.7% of total elapsed
15:31:22 <freeside> rerunning with performGC disabled
15:32:25 <freeside> 3,002,958,440 bytes maximum residency
15:32:30 <freeside> Productivity 15.6% of total user, 11.6% of total elapsed
15:32:36 <freeside> we must trust the garbage collector
15:34:46 festive_kurbus joins (~festive_k@user/kurbus)
15:35:45 <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?
15:35:46 <merijn> freeside: ok, so productivity of 15% is clearly better, but still *atrocious*
15:35:50 foul_owl joins (~kerry@157.97.134.158)
15:35:56 <merijn> freeside: It means 85% of your runtime is GC :p
15:37:27 <merijn> freeside: Is that with unboxed or just as-is?
15:37:41 <int-e> that's quite a lot of residency.
15:38:19 <freeside> this is boxed
15:38:34 <freeside> i feel like some of the consumed data is still lingering
15:38:38 <merijn> freeside: boxed is gonna add *minimum* 8 bytes per item
15:38:49 <merijn> (extra pointer indirection)
15:39:38 <freeside> i will rerun unboxed
15:40:19 <merijn> I'm wondering if the input string is kept alive
15:40:52 <merijn> but that shouldn't be that expensive
15:41:08 <freeside> the really weird thing now is my last run hung at "answer: ", which suggests some laziness is still being resolved
15:41:21 × sammelweis quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Quit: No Ping reply in 180 seconds.)
15:42:13 <freeside> running unboxed is a lot slower, but the RAM is staying under 13MB, so that's a relief.
15:42:27 sammelweis joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
15:44:52 <merijn> Interesting
15:45:09 <merijn> Are you using -O or -O2 now, btw?
15:46:01 <freeside> er, i don't know, possibly neither?
15:46:25 <merijn> ah, yeah, you're not, so that's probably another thing to do :p
15:46:51 <merijn> Just add -O (or -O2) to ghc-options in the cabal file
15:47:10 <merijn> freeside: Without that the optimiser isn't enabled and especially for numeric heavy code that can matter A LOT
15:47:28 <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
15:49:33 <c_wraith> I though cabal defaulted to -O until you specify otherwise
15:50:14 <merijn> c_wraith: depends on what's in your config, I guess
15:50:18 × lortabac quits (~lortabac@2a01:e0a:541:b8f0:ebf5:c68c:db4f:4f95) (Quit: WeeChat 2.8)
15:50:27 <c_wraith> *thought
15:50:37 <c_wraith> anyway, default meaning "if you don't specify"
15:55:21 <freeside> yeah, i'm pretty sure the Boxed computations are being thunked, even though I had LANGUAGE Strict.
15:55:32 <int-e> oh that problem... there's a really stupid thing about it
15:56:43 <c_wraith> -XStrict does not prevent thunks.
15:56:46 <c_wraith> that's not what it's for
15:57:04 <c_wraith> The ghc user guide explains pretty explicitly what it does
15:57:36 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
15:59:59 <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.
16:01:20 <merijn> -XStrict is so overhyped
16:01:22 <c_wraith> I've been burned so many times by libraries breaking my code with too much strict evaluation.
16:01:31 <merijn> There is no way to avoid thinking about strictness
16:01:39 × dsrt^ quits (~dsrt@76.145.185.103) (Remote host closed the connection)
16:01:51 <merijn> -XStrict is not a magical solution, it just swaps the default to an (arguably) stupider one
16:02:11 <DigitalKiwi> ahem i avoid it by not thinking
16:03:11 <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
16:05:37 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43)
16:07:05 × acidjnk_new quits (~acidjnk@p200300d6e7137a767ca9aed60fa8d1f2.dip0.t-ipconnect.de) (Ping timeout: 256 seconds)
16:09:54 × festive_kurbus quits (~festive_k@user/kurbus) (Quit: Client closed)
16:10:54 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
16:11:18 × dora quits (~dora@rivendell.ksi.ii.uj.edu.pl) (Ping timeout: 260 seconds)
16:12:23 × beteigeuze quits (~Thunderbi@bl14-81-220.dsl.telepac.pt) (Ping timeout: 246 seconds)
16:12:48 beteigeuze joins (~Thunderbi@bl14-81-220.dsl.telepac.pt)
16:12:50 festive_kurbus joins (~festive_k@user/kurbus)
16:15:09 × tomku quits (~tomku@user/tomku) (Ping timeout: 260 seconds)
16:21:17 × MajorBiscuit quits (~MajorBisc@c-001-003-046.client.tudelft.eduvpn.nl) (Quit: WeeChat 3.6)
16:28:40 × zeenk quits (~zeenk@2a02:2f04:a30d:4300::7fe) (Quit: Konversation terminated!)
16:29:29 <maerwald> I work in a strict Haskell dialect, so not sure I agree
16:36:38 tomku joins (~tomku@user/tomku)
16:37:39 × alexiscott quits (~user@4.red-83-36-45.dynamicip.rima-tde.net) (Ping timeout: 268 seconds)
16:37:52 × nschoe quits (~q@141.101.51.197) (Ping timeout: 256 seconds)
16:39:55 × fserucas quits (~fserucas@laubervilliers-657-1-66-228.w90-63.abo.wanadoo.fr) (Ping timeout: 252 seconds)
16:41:48 bobbingbob joins (~dfadsva@2604:3d09:207f:f650::7b3a)
16:43:56 × euandreh quits (~Thunderbi@179.214.113.107) (Quit: euandreh)
16:47:02 Lycurgus joins (~juan@user/Lycurgus)
16:49:50 × califax quits (~califax@user/califx) (Ping timeout: 255 seconds)
16:49:57 califax_ joins (~califax@user/califx)
16:51:10 califax_ is now known as califax
16:53:09 × Topsi quits (~Topsi@217.64.164.1) (Quit: Client closed)
16:54:58 <bobbingbob> im interested in Data.Sum but don't really understand it. Any willing to point to or give an explanation?
16:55:30 <bobbingbob> i want to try it out for a extensible widget system for my gui. Does this sound like a reasonable application?
16:56:47 × Xeroine quits (~Xeroine@user/xeroine) (Ping timeout: 260 seconds)
16:58:47 Xeroine joins (~Xeroine@user/xeroine)
17:02:56 × michalz quits (~michalz@185.246.204.75) (Remote host closed the connection)
17:05:53 econo joins (uid147250@user/econo)
17:05:56 × CiaoSen quits (~Jura@p200300c95747e0002a3a4dfffe84dbd5.dip0.t-ipconnect.de) (Ping timeout: 246 seconds)
17:06:22 michalz joins (~michalz@185.246.204.77)
17:07:04 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43) (Remote host closed the connection)
17:07:08 <merijn> What is Data.Sum?
17:07:44 opticblast joins (~Thunderbi@secure-165.caltech.edu)
17:08:35 × festive_kurbus quits (~festive_k@user/kurbus) (Quit: Client closed)
17:08:41 <bobbingbob> so you know the open union type stuff in oleg's effect stuff? this is that part by itself
17:09:14 <bobbingbob> im wondering if it could be used for a hetergenous collection
17:09:35 <bobbingbob> or maybe im wildy misunderstanding things
17:09:40 <[exa]> bobbingbob: you meant Data.Functor.Sum ?
17:10:22 <bobbingbob> [exa]: i mean the package fastsum
17:10:45 <[exa]> ah
17:10:56 Guest|56 joins (~Guest|56@ip241-94-176-143.adsl2.static.versatel.nl)
17:11:38 × Guest|56 quits (~Guest|56@ip241-94-176-143.adsl2.static.versatel.nl) (Client Quit)
17:13:20 <bobbingbob> i going to reread the effects paper. i vaguely understood the early portions. i think i will do my own mock implementation
17:13:43 <[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
17:14:24 × Lycurgus quits (~juan@user/Lycurgus) (Quit: Exeunt https://tinyurl.com/4m8d4kd5)
17:14:29 <bobbingbob> ok so i would do better with GADTs
17:14:38 <[exa]> re "various properties" you might think of "may satisfy many Constraints"
17:14:49 <[exa]> do you know how `mtl` or `transformers` work?
17:14:59 <bobbingbob> not in depth
17:14:59 × accord quits (uid568320@id-568320.hampstead.irccloud.com) (Quit: Connection closed for inactivity)
17:15:30 <bobbingbob> there is a simple monad stack in repa-V4l2 that i looked at
17:15:50 <bobbingbob> i understand the lifting
17:16:27 <bobbingbob> i will look for some papers on monad transformers
17:16:34 × bgs quits (~bgs@212-85-160-171.dynamic.telemach.net) (Remote host closed the connection)
17:16:36 <[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`
17:18:27 <[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
17:19:58 <Hecate> bgamari: you should show Andres Löh this, he would love it for his workshops: https://social.treehouse.systems/@armael/109473361778060633
17:21:03 <Hecate> ah silly me, he's kosmikus
17:22:06 <bgamari[m]> Hecate: indeed
17:22:56 <bgamari[m]> Hecate: do you know about https://hackage.haskell.org/package/ghc-heap-view
17:23:12 phill96 joins (~phill@2600:8807:8100:1e:fddd:78c0:9f78:c96f)
17:23:22 Tuplanolla joins (~Tuplanoll@91-159-68-152.elisa-laajakaista.fi)
17:23:22 phill96 is now known as ph_l
17:24:20 × ubert1 quits (~Thunderbi@2a02:8109:abc0:6434:3dae:2edc:412:e26e) (Ping timeout: 256 seconds)
17:24:24 festive_kurbus joins (~festive_k@user/kurbus)
17:29:19 × razetime quits (~quassel@49.207.203.213) (Quit: https://quassel-irc.org - Chat comfortably. Anywhere.)
17:29:51 razetime joins (~quassel@49.207.203.213)
17:33:51 mestre joins (~mestre@191.177.185.178)
17:34:59 <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`
17:35:14 <fendor[m]> actually just `Type -> Type`, but same thing
17:37:56 <fendor[m]> ah, that seems to require an explicit kind signature
17:38:49 <fendor[m]> a stand alone kind signature to be precise.
17:45:12 × festive_kurbus quits (~festive_k@user/kurbus) (Quit: Client closed)
17:46:15 festive_kurbus joins (~festive_k@user/kurbus)
17:48:23 × razetime quits (~quassel@49.207.203.213) (Quit: https://quassel-irc.org - Chat comfortably. Anywhere.)
17:49:52 × notzmv quits (~zmv@user/notzmv) (Ping timeout: 265 seconds)
17:50:42 × kuribas quits (~user@ptr-17d51eo0qm84xeejuqw.18120a2.ip6.access.telenet.be) (Quit: ERC (IRC client for Emacs 27.1))
17:50:47 × son0p quits (~ff@2604:3d08:5b7f:5540::a58f) (Ping timeout: 256 seconds)
17:51:35 jakalx parts (~jakalx@base.jakalx.net) (Error from remote client)
17:52:02 wootehfoot joins (~wootehfoo@user/wootehfoot)
17:52:27 <merijn> man...megaparsec used to be so easy, why did the docs become such a mess :\
17:53:20 <merijn> Can't even find out how to parse a word
17:58:18 azimut joins (~azimut@gateway/tor-sasl/azimut)
17:58:34 jakalx joins (~jakalx@base.jakalx.net)
18:05:15 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43)
18:09:08 × ph_l quits (~phill@2600:8807:8100:1e:fddd:78c0:9f78:c96f) (Ping timeout: 260 seconds)
18:11:10 × mbuf quits (~Shakthi@49.204.118.69) (Quit: Leaving)
18:13:17 <sm> merijn: I think it's when it outsourced generic combinators to another package
18:13:41 <merijn> sm: That's not a generic combinator, though
18:14:01 <merijn> But it turns out takeWhileP is what I wanted, but couldn't find
18:15:46 × manwithluck quits (~manwithlu@194.177.28.176) (Remote host closed the connection)
18:15:47 × stiell quits (~stiell@gateway/tor-sasl/stiell) (Ping timeout: 255 seconds)
18:16:21 × chele quits (~chele@user/chele) (Quit: Leaving)
18:16:29 <sm> megaparsec's docs are above average, but there's always room for improvement I guess
18:17:41 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:30d2:fcaf:3b1c:ad43) (Remote host closed the connection)
18:17:54 <sm> would some letterChar have worked ?
18:18:23 × akegalj quits (~akegalj@180-243.dsl.iskon.hr) (Ping timeout: 246 seconds)
18:18:46 stiell joins (~stiell@gateway/tor-sasl/stiell)
18:19:48 × elevenkb quits (~elevenkb@105.184.79.224) (Quit: Client closed)
18:22:15 <tomsmeding> 11:35 <dminuoso> Not sure why weechat does occacsionally print `- - - - - - ...`
18:22:43 <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
18:23:03 <tomsmeding> not sure how this mechanic works if you have multiple buffers on screen, but with one full-screen buffer it's very predictable
18:25:00 × pavonia quits (~user@user/siracusa) (Quit: Bye!)
18:29:32 o1lo01ol1o joins (~o1lo01ol1@2001:8a0:6a54:cb00:4d39:d844:8601:6cb2)
18:29:38 <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?
18:29:53 × festive_kurbus quits (~festive_k@user/kurbus) (Quit: Client closed)
18:30:20 × coot quits (~coot@213.134.171.3) (Quit: coot)
18:30:51 <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.
18:33:57 <Chai-T-Rex> Are there any recommended VS Code extensions for programming in Haskell?
18:34:51 <sm> Haskell
18:35:35 × beteigeuze quits (~Thunderbi@bl14-81-220.dsl.telepac.pt) (Ping timeout: 264 seconds)
18:36:48 <sm> o1lo01ol1o: ghci runs in a different mode than compiled code. Are there threads involved, eg ?
18:37:21 <o1lo01ol1o> sm: there are no threads involved.  it's a JSON round-trip test
18:37:55 <sm> is it pure haskell, or calling out to a C lib ?
18:38:00 <o1lo01ol1o> pure haskell
18:38:31 <o1lo01ol1o> it's literally serializing a recurisve datatype using Aeson and deserializing it again
18:38:48 <sm> mystery.. remove bits until it works I guess
18:39:28 <o1lo01ol1o> but it's already fairly minimal, the current test has like 15 terms.
18:39:45 <o1lo01ol1o> it works without a hitch in ghci
18:40:24 eggplantade joins (~Eggplanta@104-55-37-220.lightspeed.sntcca.sbcglobal.net)
18:40:55 <sm> nevertheless.. my Excellent Debugging Technique Of Success is guaranteed!
18:41:11 son0p joins (~ff@s0106f88b37df247a.vn.shawcable.net)
18:41:18 <o1lo01ol1o> sm: :plus 1"
18:41:37 <mauke> strace -f
18:42:02 sm sucks in breath sharply... a challenger!
18:42:12 <sm> it is powerful!
18:43:19 <sm> and I guess the same package versions are being used in both cases
18:43:56 <o1lo01ol1o> sm: it's in nix, everything is pinned
18:44:36 haritz joins (~hrtz@82-69-11-11.dsl.in-addr.zen.co.uk)
18:44:37 × haritz quits (~hrtz@82-69-11-11.dsl.in-addr.zen.co.uk) (Changing host)
18:44:37 haritz joins (~hrtz@user/haritz)
18:44:38 <sm> sure, but... are you running ghci via cabal repl ?
18:44:44 <o1lo01ol1o> yes
18:45:09 <sm> cool, cool
18:47:30 gurkenglas joins (~gurkengla@p548ac72e.dip0.t-ipconnect.de)
18:48:17 beteigeuze joins (~Thunderbi@bl14-81-220.dsl.telepac.pt)
18:48:37 × jle`` quits (~jusle@user/jle/x-3894663) (Quit: WeeChat 3.6)
18:50:24 manwithluck joins (~manwithlu@194.177.28.176)
18:52:44 × beteigeuze quits (~Thunderbi@bl14-81-220.dsl.telepac.pt) (Ping timeout: 256 seconds)
18:54:41 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
18:55:13 festive_kurbus joins (~festive_k@user/kurbus)
18:59:52 × raehik quits (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net) (Ping timeout: 252 seconds)
19:01:24 × zant1 quits (~zant@62.96.232.178) (Ping timeout: 260 seconds)
19:03:24 tomokojun joins (~tomokojun@static-198-54-134-86.cust.tzulo.com)
19:03:40 tzh joins (~tzh@c-24-21-73-154.hsd1.or.comcast.net)
19:03:56 king_gs joins (~Thunderbi@187.201.204.122)
19:05:43 × o1lo01ol1o quits (~o1lo01ol1@2001:8a0:6a54:cb00:4d39:d844:8601:6cb2) (Ping timeout: 260 seconds)
19:08:25 <Chai-T-Rex> sm: Thanks.
19:12:30 Guest75 joins (Guest75@2a01:7e01::f03c:92ff:fe5d:7b18)
19:13:41 <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
19:13:55 <Guest75> is giving "Perhaps this statement should be within a 'do' block?" error
19:13:59 <gurkenglas> [Leary]: nope! but it's close in spirit
19:14:11 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
19:14:17 <Guest75> what versions (ghci etc) or whitespace settings should I check in order for it to work?
19:15:44 acidjnk_new joins (~acidjnk@p200300d6e7137a767ca9aed60fa8d1f2.dip0.t-ipconnect.de)
19:18:28 <Guest75> UPD: sorry, "stack build" command doesn't work on local machine either
19:19:51 <dminuoso> tomsmeding: Things you learn. Mmm
19:19:52 <Guest75> fixed ws and it works.
19:20:28 <dminuoso> Guest75: By the way, the marked line has some very quirky parenthesis style.
19:20:49 <dminuoso> Consider writing `(m2e "JSON root element must be a map") $ asKeyMap b` as: m2e "JSON root element must be a map" (asKeyMap b)
19:21:47 <Guest75> yes, such caveats are what I'm always afraid of
19:22:11 × king_gs quits (~Thunderbi@187.201.204.122) (Ping timeout: 265 seconds)
19:22:48 <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.
19:23:28 × Guest75 quits (Guest75@2a01:7e01::f03c:92ff:fe5d:7b18) (Quit: Client closed)
19:24:10 Guest75 joins (~Guest75@192.46.237.51)
19:24:13 <Guest75> Will <$> and <*> also disappear?
19:24:42 doyougnu joins (~doyougnu@cpe-74-69-132-225.stny.res.rr.com)
19:24:50 <Guest75> Not sure if <*> has prefix version though
19:24:56 <dsal> Someone at work has being using `do` in place of `$` and it just looks irrationally offensive to me.
19:25:04 <dsal> :t ap
19:25:05 <lambdabot> Monad m => m (a -> b) -> m a -> m b
19:25:19 crazazy joins (~user@130.89.171.62)
19:26:06 [exa] foresees -XBlockDollar
19:26:10 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 256 seconds)
19:26:19 <Guest75> ah yes, ap
19:26:20 <Guest75> lol
19:26:43 <dsal> Hopefully we can still use ¢
19:30:46 <romes[m]> I was reading on custom memory allocators and was now wondering whether GHC's RTS could benefit from them
19:31:17 <romes[m]> As in "malloc and free are very slow operations so we should create our own custom memory allocator" :)
19:31:27 <romes[m]> Wondering if anyone's thought about those things
19:31:33 <c_wraith> dminuoso: don't make me use lambdas instead of right sections of $
19:31:46 × troydm quits (~troydm@host-176-37-124-197.b025.la.net.ua) (Ping timeout: 252 seconds)
19:32:05 × sammelweis quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Ping timeout: 260 seconds)
19:32:21 <romes[m]> > "Keep heap allocations to a minimum, and never allocate from the heap within a tight loop."
19:32:23 <lambdabot> "Keep heap allocations to a minimum, and never allocate from the heap within...
19:32:23 <c_wraith> romes[m]: why do you think GHC uses malloc and free?
19:33:24 <dsal> Functional programming languages are garbage producers.
19:33:36 <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
19:33:41 <romes[m]> stgMalloc wraps malloc
19:33:46 <festive_kurbus> dsal: they're not gonna like that one
19:33:51 <geekosaur> you got wrong
19:34:32 <mauke> all memory allocations are done through malloc if you grep -i malloc
19:34:40 <dminuoso> c_wraith: Heh.
19:34:49 × irrgit__ quits (~irrgit@86.106.90.226) (Read error: Connection reset by peer)
19:35:08 <romes[m]> maybe I'm searching in the wrong place (rts/)
19:35:14 × son0p quits (~ff@s0106f88b37df247a.vn.shawcable.net) (Ping timeout: 256 seconds)
19:35:45 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
19:36:17 <geekosaur> since ghc7ish ghc has been using a 2-stage page-based allocator on 64 bit platforms
19:36:54 <romes[m]> Cool!
19:36:57 <romes[m]> (note: I was really just asking if it's been thought of, not affirming it's not)
19:37:30 <dminuoso> https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/rts/storage
19:37:32 <dminuoso> https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/rts/storage/block-alloc
19:37:38 <dminuoso> These may be of interest to you
19:37:48 <romes[m]> Reading... Thanks!
19:38:23 <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.
19:38:47 <gurkenglas> Control.Exception uses its isDoesNotExistError example two times, but doesn't actually export isDoesNotExistError? :(
19:39:06 × festive_kurbus quits (~festive_k@user/kurbus) (Quit: Client closed)
19:39:09 <dminuoso> tomsmeding: Take note that the wiki articles, the ones linked in particular, contain links to relevant source files at the top.
19:39:16 <mauke> :t isDoesNotExistError
19:39:17 <lambdabot> error:
19:39:17 <lambdabot> Variable not in scope: isDoesNotExistError
19:39:43 <gurkenglas> mauke, I regret to inform you that this identifier
19:39:46 <gurkenglas> doesn't exist
19:39:57 <dminuoso> gurkenglas: It's from System.IO.Error
19:40:02 <mauke> YEEAAAAHHH
19:40:32 <gurkenglas> oh, silly of me
19:42:10 <dminuoso> Control.Exception is just the generic exception interface, with System.IO.Error defining IOError and relating utilities.
19:42:53 <gurkenglas> typecheck: "Perhaps you want to add ‘SomeException’ to the import list in the import of ‘Control.Exception’"
19:42:55 × Erutuon quits (~Erutuon@user/erutuon) (Ping timeout: 260 seconds)
19:42:56 irrgit_ joins (~irrgit@176.113.74.74)
19:42:57 <gurkenglas> hls: "No quick fixes available"
19:44:21 festive_kurbus joins (~festive_k@user/kurbus)
19:44:23 sammelweis joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
19:45:09 <gurkenglas> how come doesNotExistError is identified at runtime instead of on the type level :(
19:45:50 <festive_kurbus> because skill issue
19:46:14 <dminuoso> You could in principle do it with catch, but that would require extending the hierarchy
19:46:31 <geekosaur[m]> Because sane people write type level programs in Idris, not Haskell
19:47:24 Erutuon joins (~Erutuon@user/erutuon)
19:47:32 <mauke> inb4 type-level catch
19:47:35 <dminuoso> gurkenglas: Besides, IOException is a conceptual mapping to the standard errno error codes.
19:47:51 <dminuoso> (Or the errno interface in general)
19:48:01 × avicenzi quits (~avicenzi@2a00:ca8:a1f:b004::c32) (Ping timeout: 252 seconds)
19:48:02 <dminuoso> It's very low level and simple, probably for historic reasons.
19:48:18 <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?
19:48:43 <dminuoso> gurkenglas: well we can do the latter in exceptions actually
19:48:46 <dminuoso> with full subtyping.
19:48:54 <dminuoso> but it doesnt work with superclasses
19:49:05 <dminuoso> https://simonmar.github.io/bib/papers/ext-exceptions.pdf
19:49:25 <dminuoso> It's a wonderful mechanism that GHC uses to some extend, but is widely underappreciated.
19:49:41 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
19:50:02 <dminuoso> Think of it as java-style exceptions, with being able to catch a parent or child exception type (except they are not checked)
19:51:39 <dminuoso> It's just that for one reason or another the IOException sub-exceptions do not use this mechanism.
19:52:08 coot joins (~coot@2a02:a310:e241:1b00:ec1a:e9df:79ac:66ba)
19:52:15 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
19:52:38 <gurkenglas> How do I make goto definition work on definitions imported from libraries in hls?
19:52:48 <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)
19:53:18 × mestre quits (~mestre@191.177.185.178) (Quit: Lost terminal)
19:54:37 <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.
19:55:05 mauke discovers BlockArguments, falls in love
19:55:37 <gurkenglas> are there plans to let any such API changes come with a codebase migrator?
19:56:14 × doyougnu quits (~doyougnu@cpe-74-69-132-225.stny.res.rr.com) (Ping timeout: 260 seconds)
19:56:16 <dminuoso> No. Mostly its just some written notes in the gitlab wiki, and deprecation warnings (that people barely read because nobody enables -Wcompat)
19:56:33 beteigeuze joins (~Thunderbi@a79-169-109-107.cpe.netcabo.pt)
19:56:38 <dminuoso> Things will then break after the long grace periods that we grant, frustrating users...
19:57:32 × beteigeuze quits (~Thunderbi@a79-169-109-107.cpe.netcabo.pt) (Client Quit)
19:58:00 <gurkenglas> I guess that'll come with the automated coder revolution one of these years, then
19:58:25 × shapr quits (~user@68.54.166.125) (Remote host closed the connection)
20:09:17 jmdaemon joins (~jmdaemon@user/jmdaemon)
20:11:33 son0p joins (~ff@S0106f88b37df247a.vn.shawcable.net)
20:12:20 × stiell quits (~stiell@gateway/tor-sasl/stiell) (Ping timeout: 255 seconds)
20:12:46 × trev quits (~trev@user/trev) (Remote host closed the connection)
20:12:49 <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.
20:15:34 tremon joins (~tremon@83-84-18-241.cable.dynamic.v4.ziggo.nl)
20:16:50 <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.
20:17:19 <dminuoso> That depends on your editor and its lsp integration.
20:17:31 <dminuoso> hls will respond to whatever the lsp client will ask it
20:17:53 <dminuoso> though `else` is not a valid expression
20:18:01 <dminuoso> So that's definitely a curious example
20:18:14 <dminuoso> (Perhaps HLS has some kind of heuristic for this?)
20:18:26 <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
20:19:41 <monochrom> The most obvious thing to try is drag-selecting a subexpression.
20:19:45 <dminuoso> Im guessing HLS will go up in the CST until it finds a full expression?
20:20:17 <dminuoso> Which if you do what monochrom suggested wouldnt happen, since the selected region would already be an expression
20:20:22 <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.
20:20:36 <gurkenglas> tried drag-selecting. it's vscode
20:21:37 <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.
20:22:28 <festive_kurbus> moom #haskell devolved into nihilism again
20:22:49 <monochrom> A very humble emacs haskell-mode already does (with help from ghci integration) drag-select subexpr for type. dante does too.
20:23:26 <dminuoso> "with help from ghci integration", the standard haskell-mode does not do that.
20:23:33 <dminuoso> What are you using?
20:23:52 <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.
20:23:54 <gurkenglas> https://marketplace.visualstudio.com/items?itemName=haskell.haskell
20:24:07 <monochrom> The standard haskell-mode. It does.
20:24:56 <dminuoso> Oh it does?>
20:25:40 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 252 seconds)
20:25:45 <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.
20:26:32 × jmdaemon quits (~jmdaemon@user/jmdaemon) (Quit: ZNC 1.8.2 - https://znc.in)
20:26:50 <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
20:27:03 kenran joins (~user@user/kenran)
20:27:23 <monochrom> So everyone simply inferred, from the hype, that there is no other way.
20:27:57 <monochrom> or s/other/low-tech/
20:28:14 stiell joins (~stiell@gateway/tor-sasl/stiell)
20:28:16 <geekosaur> nobody wants low-tech ways
20:28:17 <monochrom> This is how advertisements work psychologically in general.
20:28:27 dminuoso wants physical buttons in his car
20:28:39 <Rembane> +1
20:29:29 <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.
20:30:17 <Rembane> Withouth Benilyn they are gone in ten days!
20:30:29 <gurkenglas> intero had it way before ghci, right?
20:31:59 <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.
20:32:11 seriously_guest joins (~seriously@2001:1c06:2715:c200:1a82:76d8:bd30:82fc)
20:32:28 money_ joins (~money@user/polo)
20:33:53 <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%
20:34:05 <dolio> I don't think so. Wasn't intero using the same mechanism as dante, except it only worked with stack?
20:35:07 <geekosaur> dante used ghci, intero involved a modified stack-only ghci iirc
20:35:22 <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.
20:35:34 <monochrom> Oh modified ghci, haha that's epic.
20:35:43 <monochrom> worst of both worlds haha
20:35:56 <geekosaur> well, anything using ghc-api in a general fashion is just a reworked ghci
20:36:09 <monochrom> OK fair.
20:36:12 <geekosaur> I don't know exact details but ghci is a thin wrapper over ghc-api
20:36:37 <geekosaur> (exact details re intero that os)
20:36:39 <geekosaur> *is
20:37:25 <gurkenglas> *looks at ListT* *looks at ListT done right* neither of these are what I want, I think O_o. I want IO [a]
20:37:47 <monochrom> IO [a] would be the former ListT.
20:37:49 <gurkenglas> am i... about to reach for acme-iot
20:38:08 × festive_kurbus quits (~festive_k@user/kurbus) (Quit: Client closed)
20:38:30 <monochrom> OK, unless the former ListT's >>= is not to your liking.
20:38:55 <gurkenglas> oh, i failed to look at the former ListT instead of two different search results for the done right one
20:39:21 <gurkenglas> and thought the difference between them must be some technicality i didnt see at first glance
20:40:11 × kenran quits (~user@user/kenran) (Remote host closed the connection)
20:40:14 <gurkenglas> the >>= logic should be... everything in line 118 happens before everything in line 119
20:41:06 <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)
20:41:29 <gurkenglas> (logic perhaps not being the right phrase, instead of "IO sequencing")
20:42:01 <monochrom> I don't understand the question.
20:42:25 <geekosaur> seriously_guest, what does your function produce if either Name or String is Nothing?
20:42:57 <seriously_guest> geekosaur Employee (Nothing) (Nothing)
20:43:12 <monochrom> Does Employee allow that?
20:43:17 <seriously_guest> or Employee (Just "Frank") (Nothing)
20:44:18 <seriously_guest> Employee by the examples defition does not monochrom
20:44:29 <geekosaur> then you have the point
20:44:51 <monochrom> I'm too lazy to search. Which URL has the definition of Employee?
20:44:53 <seriously_guest> But thats why im suggeesting just create a data Employee = Employee (Maybe Name) (Maybe String)
20:44:54 festive_kurbus joins (~festive_k@user/kurbus)
20:45:00 <seriously_guest> https://www.cis.upenn.edu/~cis1940/spring13/lectures/10-applicative.html
20:45:15 <monochrom> Well then Employee doesn't allow Nothing.
20:45:18 <dsal> Do you want an employee whose name you don't know?
20:45:44 <dsal> An Employee Has No Name
20:45:54 <monochrom> If one day you have a webapp in which "data Employee = Employee (Maybe Name) (Maybe String)" is totally legit, good for you.
20:46:00 <seriously_guest> haha... no
20:46:04 <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?
20:46:07 × eggplantade quits (~Eggplanta@104-55-37-220.lightspeed.sntcca.sbcglobal.net) (Remote host closed the connection)
20:46:11 <monochrom> For now, my webapp says that it should make no sense and it should be disallowed.
20:46:38 <monochrom> Then I really legit only have either Just (Employee foo bar) or Nothing, i.e., Maybe Employee.
20:46:42 <dsal> It's a good idea to make illegal states unrepresentable.
20:46:58 <dminuoso> Now whether a missing name is illegal state, that's for you to decide.
20:47:11 <seriously_guest> I see
20:47:45 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
20:48:29 huskle joins (~huskle@250.79-105-213.static.virginmediabusiness.co.uk)
20:48:39 <huskle> hi, i just installed haskell on ubuntu
20:48:45 <huskle> having just installed ubuntu
20:48:52 <huskle> when i do cabal v2-install random
20:48:54 <huskle> it fails!
20:49:15 × Inoperable quits (~PLAYER_1@fancydata.science) (Ping timeout: 268 seconds)
20:49:18 <Rembane> huskle: How does it fail?
20:49:21 <huskle> i installed ghcup using curl as it says to
20:49:34 <huskle> Rembrane: /usr/bin/ld.gold: error: cannot find -lgmp
20:50:08 <huskle> is this a dependency that ghcup should have installed?
20:50:20 <dolio> You probably need to install it with apt.
20:50:20 <Rembane> huskle: Have you tried sudo apt-get install build-essential
20:50:24 <monochrom> sudo apt install libgmp-dev
20:50:38 <monochrom> build-essential doesn't have it.
20:50:59 <geekosaur> but you'll probably need build-essential anyway
20:51:07 <huskle> Rembrane: says they are there already
20:51:09 <monochrom> Yeah, build-essential is for gcc.
20:51:49 ft joins (~ft@p508dbd59.dip0.t-ipconnect.de)
20:51:57 <huskle> yay! now it works
20:52:13 <huskle> libgmp-dev seems to have been missing
20:52:24 <huskle> so why does ghcup not install this?
20:52:57 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 268 seconds)
20:53:04 <monochrom> ghcup does not know that it is not "pacman foobar libgmp-dev"?
20:53:25 <mauke> I don't think you need the -dev package; libgmp10 might have been sufficient
20:53:30 <dolio> Yeah, does ghcup interact at all with the system package manager?
20:53:35 <monochrom> Alternatively but equivalently, "patches welcome".
20:53:57 <monochrom> Although, ghcup absolutely avoids sudo.
20:54:10 <huskle> beyond me
20:54:17 <monochrom> libgmp10 is positively verified to be insufficient.
20:54:26 <mauke> oh, neat
20:54:50 <huskle> sounds like an issue encountered before!
20:54:54 waleee joins (~waleee@2001:9b0:213:7200:cc36:a556:b1e8:b340)
20:55:38 <huskle> im making some differentialble random number sequences if anyones interested
20:55:49 <huskle> its for machine learning
20:55:56 × haritz quits (~hrtz@user/haritz) (Quit: ZNC 1.8.2+deb2 - https://znc.in)
20:56:13 <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.
20:56:31 <monochrom> GHC just needs the libfoo.so symlink.
20:56:49 <monochrom> You could argue that you don't need libfoo-dev for that, you could make the symlink yourself.
20:57:12 <huskle> (!?)
20:57:14 <monochrom> Explaining that takes 100 times more effort than instructing "sudo apt install libfoo-dev".
20:57:19 <mauke> that strikes me as slightly weird. why is the .so link part of the dev package?
20:57:35 <monochrom> Ideology?
20:57:54 <monochrom> Every linux distro makes ideological, irrational decisions.
20:58:02 <monochrom> Just look at archlinux. :)
20:58:22 <mauke> I'm not sure "irrational" has semantics
20:58:32 <huskle> well, better than windows installing updates that ensure the bloatawre cannot be disabled
20:59:05 <huskle> that also use so much resources as to prevent taskmanager from being opened to stop other processes
20:59:34 <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".
20:59:38 <huskle> i want the last year of my life back
21:00:35 <huskle> anyway, with linux, i can now open a text editor and a directory browser in less than a minute!
21:00:45 <EvanR> yes irrational = not rational is terribly negative. What's the positive version
21:00:49 <monochrom> For the semantics of "irrational", you can start with your own "slightly weird, why did they do it?"
21:00:50 <huskle> i used to use wordpad, because it took *less* time than eclipseIDE to start
21:01:23 <seriously_guest> Can someone help me write an implementation of this type (continuing my previoius train of thought): (Name -> String -> Employee) ->
21:01:23 <seriously_guest> (Maybe Name -> Maybe String -> Maybe Employee)
21:01:43 <mauke> \_ _ _ -> Nothing
21:01:48 <huskle> lol
21:02:07 <monochrom> You can do pattern matching on two Maybe parameters.
21:02:08 <huskle> can they have no name or string or do they have to have a name or a string?
21:02:31 <seriously_guest> Have to have a name and a string
21:02:34 <monochrom> You can first call it 4 cases. Later you can merge 3 of them.
21:02:50 <huskle> not name *and* ...
21:03:00 <mauke> @djinn (Name -> String -> Employee) -> (Maybe Name -> Maybe String -> Maybe Employee)
21:03:00 <lambdabot> Error: Undefined type Name
21:03:06 <dolio> EvanR: Has a continued fraction representation with specified, finite gaps between non-zero coefficients.
21:03:25 <huskle> so its more like (Maybe (Name,String)) -> Maybe Employee?
21:03:30 <huskle> because then you can use fmap
21:03:44 <huskle> % :t fmap @Maybe
21:03:44 <yahb2> fmap @Maybe :: (a -> b) -> Maybe a -> Maybe b
21:03:52 king_gs joins (~Thunderbi@187.201.204.122)
21:03:55 <seriously_guest> Sorry huskle I believe you joined after I explained that this is in regards to cis 194 assignment 10
21:04:09 <monochrom> No, totally unlike (Maybe (Name,String)) -> Maybe Employee
21:04:10 <huskle> ok
21:04:15 <mauke> @djinn (name -> string -> employee) -> (Maybe name -> Maybe string -> Maybe employee)
21:04:15 <lambdabot> f a b c =
21:04:15 <lambdabot> case b of
21:04:15 <lambdabot> Nothing -> Nothing
21:04:15 <lambdabot> Just d -> case c of
21:04:15 <lambdabot> Nothing -> Nothing
21:04:17 <lambdabot> Just e -> Just (a d e)
21:04:36 <mauke> well, that's not very elegant
21:06:07 <seriously_guest> What would the types of a, b, and c be ?
21:06:07 × festive_kurbus quits (~festive_k@user/kurbus) (Quit: Client closed)
21:06:16 <mauke> wtf
21:06:31 <mauke> it's your type signature
21:06:57 <mauke> I gave it to the bot; it generated code; why are you now asking for the type of the code we started from?
21:07:19 <seriously_guest> why are you even assuming i know what this bot is doing?
21:08:15 <monochrom> Why is no one caring about my advice?
21:08:16 <mauke> hmm
21:08:48 <mauke> it's not so much that; what I'm assuming is that you can read/understand basic haskell code
21:08:53 <iqubic> Just use liftA3
21:09:17 <dsal> liftA2
21:09:26 <iqubic> Oh yeah
21:09:38 <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?
21:09:44 <dsal> Off by one lift
21:09:52 <gurkenglas> What's the current way to make hls add imports for me?
21:09:57 <mauke> seriously_guest: ooh, you're stuck on currying!
21:10:32 <mauke> seriously_guest: f a b c = ... is syntactic sugar for f = \a -> \b -> \c -> ...
21:10:35 <huskle> seriously_guest: thats wrong
21:10:35 <kjlid[m]> I just ate a curry
21:10:44 <huskle> you have one function argument
21:10:45 <mauke> seriously_guest: and the type A -> B -> C means A -> (B -> C)
21:10:55 <mauke> huskle: dude, what
21:11:13 <huskle> f g =
21:11:21 <mauke> huskle: did you not read what the bot wrote?
21:11:23 <mauke> also, you're wrong
21:11:29 <huskle> chill!
21:11:37 <huskle> this bot has you all het up
21:11:45 <huskle> its a beginer q
21:12:06 <huskle> and your all like "all function arrows are monomorphisms"
21:12:20 <EvanR> f g =, the type of g is (Name -> String -> Employee)
21:12:22 <mauke> seriously_guest: well, that assumes you know what \a -> ... means. do you?
21:12:31 <mauke> if not, this explanation was useless :-)
21:12:39 <huskle> EvanR: thanks...
21:13:23 <seriously_guest> EvanR how about f g h
21:13:30 <huskle> functions in one argument* (i have no idea what a monomorphism is. sry!)
21:13:41 <EvanR> h sounds like you want a second function argument?
21:13:51 <EvanR> your next argument would be Maybe Name if you want to do it that way
21:14:29 <EvanR> f g mname mstring =
21:14:31 <huskle> % :t curry
21:14:31 <yahb2> curry :: ((a, b) -> c) -> a -> b -> c
21:14:41 <huskle> % :t fmap @Maybe . uncurry
21:14:41 <yahb2> fmap @Maybe . uncurry ; :: (a -> b1 -> b2) -> Maybe (a, b1) -> Maybe b2
21:14:57 <huskle> your sure its not this?
21:15:09 <huskle> he said they have to have a name *and* a string
21:15:22 <huskle> they*
21:15:32 <EvanR> sounds like you need Applicative but also we can't get there yet
21:15:48 Inoperable joins (~PLAYER_1@fancydata.science)
21:15:55 <EvanR> you have to swim before you can crawl
21:16:14 <mauke> seriously_guest: but to answer your question in full, a :: (Name -> String -> Employee); b :: Maybe Name; c :: Maybe String
21:17:25 pavonia joins (~user@user/siracusa)
21:18:17 <gurkenglas> Is there a MonadIO-lifted version of https://hackage.haskell.org/package/text-2.0.1/docs/Data-Text-IO.html ?
21:18:19 tvandinther joins (~tvandinth@111.69.34.210)
21:18:27 <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
21:18:28 <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.
21:18:32 <dminuoso> gurkenglas: Probably not. You can just liftIO
21:19:03 <dminuoso> seriously_guest: We could perhaps start with a different motivation.
21:19:10 <geekosaur> gurkenglas, I would expect one of the alternative Preludes to have it
21:19:16 <dminuoso> seriously_guest: Say you have two numbers held in a variable `a` and `b`, and you want to add them.
21:19:28 <dminuoso> seriously_guest: This would just be `a + b`, right?
21:19:35 <seriously_guest> right
21:20:00 <dminuoso> So in that `a :: Int` and `b :: Int`
21:20:13 <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
21:20:18 <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
21:20:33 <dminuoso> % let a = 1; b = 2; in a + b
21:20:33 <yahb2> 3
21:20:43 <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
21:20:50 kenaryn joins (~aurele@cre71-h03-89-88-44-27.dsl.sta.abo.bbox.fr)
21:20:59 <geekosaur> (there is for example a validation package that helps with that part)
21:21:12 <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`
21:21:16 <geekosaur> so now you can compose parts together to build your busines slogic from pieces
21:21:27 <dminuoso> seriously_guest: Do you see, how you can no longer just (+) them together?
21:21:53 <dminuoso> % let ma = Just 3; mb = Nothing in ma + mb
21:21:53 <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...
21:22:11 irrgit__ joins (~irrgit@176.113.74.74)
21:22:23 <seriously_guest> dminuoso yup because there no longer Int, an instance of Number. They are now Maybe Int
21:22:27 <dminuoso> Right.
21:22:35 <huskle> dminuoso: i like your example better because it is more clear that it has to have both entries or its an error
21:22:46 <dminuoso> But we may want to still express the idea of "if both numbers are present, add them together"
21:22:47 <gurkenglas> yahb2: that should say "expected Int but found Maybe Int"
21:22:48 × king_gs quits (~Thunderbi@187.201.204.122) (Ping timeout: 260 seconds)
21:22:53 <dminuoso> gurkenglas: nope.
21:23:04 <dminuoso> The error is quite right
21:23:08 <huskle> :t maybe
21:23:09 <lambdabot> b -> (a -> b) -> Maybe a -> b
21:23:35 <dminuoso> seriously_guest: So what we can write then is:
21:23:38 <gurkenglas> dminuoso: Do you mean, I misdiagnosed his issue, or you disapprove of my proposal? :D
21:23:47 <dminuoso> Both.
21:23:55 <huskle> :t both
21:23:56 <lambdabot> (Data.Bitraversable.Bitraversable r, Applicative f) => (a -> f b) -> r a a -> f (r b b)
21:24:00 <huskle> !?
21:24:01 <dminuoso> % let ma = Just 3; mb = Just 4 in liftA2 (+) ma mb -- seriously_guest
21:24:01 <yahb2> <interactive>:88:33: error: ; Variable not in scope: ; liftA2 :: (a0 -> a0 -> a0) -> Maybe a1 -> Maybe a2 -> t
21:24:07 <dminuoso> % import Control.Applicative (liftA2)
21:24:07 <yahb2> <no output>
21:24:09 <dminuoso> % let ma = Just 3; mb = Just 4 in liftA2 (+) ma mb -- seriously_guest
21:24:09 <yahb2> Just 7
21:24:15 <dsal> :t each
21:24:16 <lambdabot> (Each s t a b, Applicative f) => (a -> f b) -> s -> f t
21:24:18 <dminuoso> % :t liftA2
21:24:18 <yahb2> liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
21:24:24 <dminuoso> seriously_guest: ^- is this clear?
21:24:38 <huskle> % :t liftA2 (+)
21:24:38 <yahb2> liftA2 (+) :: (Applicative f, Num c) => f c -> f c -> f c
21:24:43 <dminuoso> (It may not be immediately necessary to understand *why* liftA2 works, but merely what it does)
21:24:52 <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
21:24:53 <huskle> % liftA2 (+) Nothing (Just 4)
21:24:53 <yahb2> Nothing
21:25:00 <huskle> % liftA2 (+) (Just 3) (Just 4)
21:25:00 <yahb2> Just 7
21:25:04 <huskle> yay!
21:25:13 × takuan quits (~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection)
21:25:14 × irrgit_ quits (~irrgit@176.113.74.74) (Ping timeout: 246 seconds)
21:25:31 <mauke> % instance (Num a) => Num (Maybe a) where { (+) = liftA2 (+); (*) = liftA2 (*); abs = fmap abs; signum = fmap signum; fromInteger = pure . fromInteger; negate = fmap negate }
21:25:32 <yahb2> <no output>
21:25:37 <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
21:25:37 <mauke> > Just 3 + Just 4
21:25:39 <lambdabot> error:
21:25:39 <lambdabot> • No instance for (Num (Maybe Integer))
21:25:39 <lambdabot> arising from a use of ‘e_134’
21:25:42 <mauke> % Just 3 + Just 4
21:25:42 <yahb2> Just 7
21:25:51 <huskle> !?
21:25:56 <mauke> % Just 3 + Nothing
21:25:56 <yahb2> Nothing
21:26:04 <huskle> Just Int has a Num instance?
21:26:09 <mauke> it does now
21:26:13 <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.
21:26:19 <dminuoso> seriously_guest: Is this clear so far?
21:26:54 <huskle> % :t negate @(Just Int)
21:26:54 <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?
21:27:01 <huskle> % :t negate @(Maybe Int)
21:27:01 <yahb2> negate @(Maybe Int) :: Maybe Int -> Maybe Int
21:27:25 <huskle> did you just make this in another window in a convo with yahb?
21:27:31 <mauke> huskle: no
21:27:33 gmg joins (~user@user/gehmehgeh)
21: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.
21:27:39 <huskle> ...
21:27:44 <mauke> I made it in this window, literally two lines before
21:27:49 <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
21:28:01 <dminuoso> seriously_guest: Sure! I just wanted to set the scene.
21:28:07 <seriously_guest> cool
21:28:21 <huskle> oh the lamdabot error confused me
21:28:28 <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.
21:28:33 <dsal> @src liftA2
21:28:33 <lambdabot> liftA2 f a b = f <$> a <*> b
21:28:56 <mauke> huskle: note how the instance body is generic and could be reused for any Applicative
21:29:00 <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.
21:29:15 <mauke> (including IO)
21:29:36 <huskle> some subset of functors?
21:30:04 <dminuoso> seriously_guest: The *lifting* is just a means to an end here.
21:30:20 <huskle> hey, does anyone want to see my differentiable random sequences thing?
21:30:30 <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`
21:30:54 <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.
21:31:16 <dminuoso> (Note Im particularly monomorphizing `f` to `Maybe` here.
21:31:32 × biberu quits (~biberu@user/biberu) (Read error: Connection reset by peer)
21:31:43 <huskle> https://paste.tomsmeding.com/rZsfvbud
21:31:47 <dminuoso> Quite similarly to how `liftA2 (+)` is useful for being able to do `liftA2 (+) ma mb`
21:32:19 <dminuoso> Of course in code style it can be useful to decouple them, so you maybe do let `add_maybes = liftA2 (+) in ...`
21:32:24 <huskle> see, it works!
21:33:01 × wootehfoot quits (~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
21:33:07 <dsal> > let (+?) = liftA2 (+) in Just 3 +? Just 5
21:33:08 <lambdabot> Just 8
21:33:16 <huskle> the guest is not interested
21:33:19 <seriously_guest> dminuoso im still comprehending some things... just a sec
21:34:00 <huskle> let us know when you are done comprehending things
21:35:35 × gmg quits (~user@user/gehmehgeh) (Ping timeout: 255 seconds)
21:35:35 × stiell quits (~stiell@gateway/tor-sasl/stiell) (Ping timeout: 255 seconds)
21:36:15 biberu joins (~biberu@user/biberu)
21:36:26 gmg joins (~user@user/gehmehgeh)
21:36:45 stiell joins (~stiell@gateway/tor-sasl/stiell)
21:38:56 <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
21:39:10 <seriously_guest> I think im clear on this bit*
21:39:20 <seriously_guest> on the values*
21:39:22 × money_ quits (~money@user/polo) (Quit: money_)
21:39:27 <dsal> Consider ($) vs. (<$>) vs. (<*>)
21:39:37 × Unicorn_Princess quits (~Unicorn_P@user/Unicorn-Princess/x-3540542) (Quit: Leaving)
21:39:43 <dminuoso> seriously_guest: A slight correcftion:
21:40:06 <dminuoso> If you want to use the generalizsed version, its <$> and <*> for most simple use cases.
21:40:07 <huskle> ... we can write liftN, for any N, sure
21:40:22 <dminuoso> While <*> on its own is useful too, the usecase we are talking about always looks like
21:40:31 <dminuoso> f <$> a1 <*> a2 <*> a3 ... <*> an
21:40:40 <dsal> > let (+?+) = (fmap . fmap) show . liftA2 (+) `on` readMaybe in "2" +?+ "5" -- Look, I've invented tcl!
21:40:41 <lambdabot> Just "7"
21:40:59 <huskle> yuk
21:41:27 <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.
21:41:28 <huskle> % @src liftA3
21:41:28 <yahb2> <interactive>:120:1: error: parse error on input ‘@’
21:41:37 <huskle> % :src liftA3
21:41:37 <yahb2> unknown command ':src' ; use :? for help.
21:41:40 <huskle> ?
21:41:40 jakalx parts (~jakalx@base.jakalx.net) (Error from remote client)
21:41:43 <dsal> @src liftA3
21:41:43 <lambdabot> Source not found.
21:41:58 <huskle> oh right its a lambdabot thing
21:42:04 <seriously_guest> dminuoso Gotcha there... now im trying to understand this part "It's not per-se being able to do `(a -> b - ......"
21:42:08 <dsal> Imagine it said liftA3 f a b c = f <$> a <*> b <*> c
21:42:17 <dminuoso> seriously_guest: If you have got what you just said, dont worry about it.
21:42:26 <huskle> > let liftA3 f a b c = f <$> a <*> b <*> c
21:42:27 <lambdabot> <no location info>: error:
21:42:27 <lambdabot> not an expression: ‘let liftA3 f a b c = f <$> a <*> b <*> c’
21:42:31 <dminuoso> seriously_guest: liftA2 (or liftA3) is just a convenience for the 2-arity (or 3-arity) function case above.
21:42:34 <huskle> sorry
21:42:44 × Topsi1 quits (~Topsi@dyndsl-095-033-143-231.ewe-ip-backbone.de) (Ping timeout: 256 seconds)
21:42:50 Topsi joins (~Topsi@dyndsl-095-033-227-140.ewe-ip-backbone.de)
21:42:51 <dsal> huskle: lambdabot doesn't know all the things, it just has some representative sources that make things easier to understand.
21:42:59 <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.
21:42:59 <huskle> ahh
21:43:08 <dsal> e.g., this is definitely not sum:
21:43:10 <dsal> @src sum
21:43:10 <lambdabot> sum = foldl (+) 0
21:43:16 jakalx joins (~jakalx@base.jakalx.net)
21:43:20 <huskle> ok
21:43:26 <c_wraith> @src foldr
21:43:26 <lambdabot> foldr f z [] = z
21:43:26 <lambdabot> foldr f z (x:xs) = f x (foldr f z xs)
21:43:29 <huskle> just some totally random reference!
21:43:36 <dsal> sum in Foldable is `sum = getSum #. foldMap' Sum`
21:43:37 <c_wraith> that one's even further from how GHC does it...
21:43:38 <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.
21:43:59 <dminuoso> (And the crazy transformation is just in order to apply it to three Maybe things)
21:44:02 <huskle> was looking at the source for "randoms"
21:44:06 <huskle> uses build
21:44:09 <huskle> for fusion
21:44:11 <huskle> pretty cool
21:44:14 <seriously_guest> So liftA3 (\x -> x + 1) (Maybe 1) (Maybe 2) (Maybe 3) = (Maybe 2) (Maybe 3) (Maybe 4)
21:44:24 <huskle> https://hackage.haskell.org/package/random-1.2.1.1/docs/src/System.Random.html#randoms
21:44:30 <dminuoso> seriously_guest: No thats not how it works.
21:44:35 <dminuoso> seriously_guest: Imagine this:
21:44:43 <dminuoso> % fun = \x y z -> (x + y) * z
21:44:43 <yahb2> <no output>
21:44:51 <dminuoso> % fun x y z = (x + y) * z
21:44:51 <yahb2> <no output>
21:45:22 <dminuoso> % fun :: Int -> Int -> Int -> Int; fun x y z = (x + y) * z
21:45:22 <yahb2> <no output>
21:45:38 <dminuoso> Now imagine you want to apply `fun` to three `Maybe Int` instead.
21:45:47 <dsal> % :t liftA3 fun
21:45:47 <yahb2> <interactive>:1:1: error: ; • Variable not in scope: liftA3 :: (Int -> Int -> Int -> Int) -> t ; • Perhaps you meant ‘liftA2’ (imported from Control.Applicative)
21:45:50 <huskle> % liftA3 (\x y z -> x + y * z) (Just 2) (Just 3) (Just 5)
21:45:50 <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...
21:45:52 <dminuoso> Then you can just either write `liftA3 fun a1 a2 a3` or `fun <$> a1 <*> a2 <*> a3`
21:46:07 <dminuoso> % import Control.Applicative (liftA3)
21:46:08 <yahb2> <no output>
21:46:12 <dminuoso> % liftA3 (\x y z -> x + y * z) (Just 2) (Just 3) (Just 5)
21:46:12 <yahb2> Just 17
21:46:21 <dsal> % :t liftA3 fun
21:46:21 <yahb2> liftA3 fun :: Applicative f => f Int -> f Int -> f Int -> f Int
21:46:26 <dminuoso> % liftA3 (\x y z -> x + y * z) <$> Just 2 <*> Just 3 <*> Just 5
21:46:26 <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...
21:46:36 eggplantade joins (~Eggplanta@104-55-37-220.lightspeed.sntcca.sbcglobal.net)
21:46:38 <dminuoso> % liftA3 fun <$> Just 2 <*> Just 3 <*> Just 5
21:46:38 <yahb2> Oops, something went wrong
21:46:41 <dminuoso> Wow.
21:46:44 dminuoso pokes tomsmeding
21:46:47 <huskle> why you still have the things between
21:46:50 <huskle> % liftA3 (\x y z -> x + y * z) (Just 2) (Just 3) (Just 5)
21:46:50 <yahb2> <interactive>:4:1: error: ; Variable not in scope: ; liftA3 ; :: (a0 -> a0 -> a0 -> a0) -> Maybe a1 -> Maybe a2 -> Maybe a3 -> t
21:46:51 <dminuoso> % fun <$> Just 2 <*> Just 3 <*> Just 5
21:46:51 <yahb2> <interactive>:6:1: error: ; Variable not in scope: fun :: a0 -> a1 -> a2 -> b
21:47:04 <dminuoso> % fun :: Int -> Int -> Int -> Int; fun x y z = (x + y) * z
21:47:04 <yahb2> <no output>
21:47:09 <dminuoso> % fun <$> Just 2 <*> Just 3 <*> Just 5
21:47:09 <yahb2> Just 25
21:47:16 × Topsi quits (~Topsi@dyndsl-095-033-227-140.ewe-ip-backbone.de) (Ping timeout: 256 seconds)
21:47:27 <huskle> % liftA3 fun (Just 2) (Just 3) (Just 5)
21:47:27 <yahb2> <interactive>:12:1: error: ; Variable not in scope: ; liftA3 ; :: (Int -> Int -> Int -> Int) ; -> Maybe a0 -> Maybe a1 -> Maybe a2 -> t
21:47:30 <huskle> rrg!!
21:47:41 <huskle> % liftA3 f a b c = f <$> a <*> b <*> c
21:47:41 <yahb2> <no output>
21:47:42 <dminuoso> seriously_guest: Are you still with me?
21:47:45 <huskle> % liftA3 fun (Just 2) (Just 3) (Just 5)
21:47:45 <yahb2> Just 25
21:47:48 <huskle> yay!
21:48:06 <seriously_guest> Ohhh right ... so arity of x means a function taking x parameters ... Sorry yes!
21:48:11 <dminuoso> Yup.
21:48:38 <dminuoso> seriously_guest: One useful bit, that relates to this, is that in reality functions only take one argument in Haskell
21:48:54 <dminuoso> It is not an absolute truth and only perspective
21:49:14 <huskle> % :t fun <$> Just 1 <*> Just 2
21:49:14 <yahb2> fun <$> Just 1 <*> Just 2 :: Maybe (Int -> Int)
21:49:17 <dminuoso> Something like `f :: Int -> Int -> Int` actually has implicit parenthesis `f :: Int -> (Int -> Int)`
21:49:20 <huskle> % :t fun <$> Just 1
21:49:20 <yahb2> fun <$> Just 1 :: Maybe (Int -> Int -> Int)
21:49:32 × Inoperable quits (~PLAYER_1@fancydata.science) (Ping timeout: 256 seconds)
21:49:37 <huskle> % :t (fun <$>)
21:49:37 <yahb2> (fun <$>) :: Functor f => f Int -> f (Int -> Int -> Int)
21:49:41 <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`
21:49:45 <dminuoso> seriously_guest: Does this make sense as well?
21:49:55 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
21:50:40 <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)
21:50:52 <dminuoso> So its useful to be able to shift this perspective from time to time
21:51:11 <dminuoso> This has some useful consequences (and again this relates to the confusion that sparked me getting into the discussion)
21:51:32 × eggplantade quits (~Eggplanta@104-55-37-220.lightspeed.sntcca.sbcglobal.net) (Ping timeout: 268 seconds)
21:51:41 <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.
21:52:04 <dminuoso> If you have a function `f :: Int -> String -> Bool`, then applying `f` to a single argument produces the rest of that function
21:52:11 <dminuoso> So `f 10` has the type `String -> Bool`
21:52:18 <dminuoso> And `f 10 "Foo"` has type Bool
21:52:33 <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
21:52:38 Topsi joins (~Topsi@dyndsl-095-033-039-218.ewe-ip-backbone.de)
21:52:41 <dminuoso> So if we look at:
21:52:46 <dminuoso> liftA3 fun 1 2 3
21:52:51 <dminuoso> (((liftA3 fun) 1) 2) 3
21:53:32 <dsal> % liftA3 fun (Just 2) (Just 3) <$> [Just 1, Just 3, Just 5]
21:53:32 <yahb2> [Just 5,Just 15,Just 25]
21:53:34 <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`
21:53:43 <dminuoso> Err
21:54:01 <dminuoso> liftA3 fun (Just 1) (Just 2) (Just 3)
21:54:07 beteigeuze joins (~Thunderbi@a79-169-109-107.cpe.netcabo.pt)
21:54:11 <dminuoso> (((liftA3 fun) (Just 1)) (Just 2)) (Just 3)
21:54:14 eggplantade joins (~Eggplanta@104-55-37-220.lightspeed.sntcca.sbcglobal.net)
21:54:39 <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.
21:55:01 <dminuoso> seriously_guest: Do you see why Im saying that focusing on what `liftA2` or `liftA3` do by themselves is not that useful?
21:55:02 × son0p quits (~ff@S0106f88b37df247a.vn.shawcable.net) (Ping timeout: 246 seconds)
21:55:04 <huskle> so how do i use applicative to do this?
21:55:05 <huskle> https://paste.tomsmeding.com/3SrqURCW
21:55:11 euandreh joins (~Thunderbi@179.214.113.107)
21:55:18 <dsal> % iterate (liftA3 fun (Just 2) (Just 3)) (Just 1)
21:55:18 <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...
21:55:25 <huskle> see how the things in the list of list are functions?
21:55:37 <huskle> i want to apply them to a list of list of input arguments
21:56:12 <dminuoso> huskle: its your lucky day
21:56:20 <dminuoso> (Applicative f, Applicative g) => Applicative (Compose f g)
21:56:34 <dminuoso> The composition of two applicatives is an applicative too.
21:56:41 <huskle> using coerce?
21:56:53 <dminuoso> You can use coerce to get into Compose sure
21:57:03 <dminuoso> Or just manually wrap and unwrap
21:57:14 <dminuoso> Similarly your fmap can be avoided as well
21:57:26 <dminuoso> (that double fmap I mean)
21:57:26 <huskle> > [[+1]] <*> [[1]]
21:57:27 <lambdabot> error:
21:57:27 <lambdabot> A section must be enclosed in parentheses thus: (+ 1)
21:57:28 codaraxis joins (~codaraxis@user/codaraxis)
21:57:37 <huskle> > [[(+1)]] <*> [[1]]
21:57:39 <lambdabot> error:
21:57:39 <lambdabot> • Couldn't match expected type ‘[a1] -> b’
21:57:39 <lambdabot> with actual type ‘[a0 -> a0]’
21:57:40 <dsal> > [succ, pred] <*> [1..5]
21:57:42 <lambdabot> [2,3,4,5,6,0,1,2,3,4]
21:58:10 <huskle> where does the coerce go?
21:58:13 <dminuoso> % import Data.Functor.Compose
21:58:13 <yahb2> <no output>
21:59:25 <huskle> heres the smooth noise module again; https://paste.tomsmeding.com/zKMllsZH
21:59:29 <dminuoso> % import Data.Functor.Compose
21:59:29 <yahb2> <no output>
21:59:33 <dminuoso> % (Compose [[succ], [pred]]) <*> (Compose [[1..5], [2..3]])
21:59:34 × euandreh quits (~Thunderbi@179.214.113.107) (Remote host closed the connection)
21:59:35 <dminuoso> % (Compose [[succ], [pred]]) <*> (Compose [[1..5], [2..3]])
21:59:35 <yahb2> Compose [[2,3,4,5,6],[3,4],[0,1,2,3,4],[1,2]]
21:59:55 euandreh joins (~Thunderbi@179.214.113.107)
21:59:57 <dminuoso> I would probably just write myself an ap2 rather
22:00:02 × euandreh quits (~Thunderbi@179.214.113.107) (Client Quit)
22:00:03 <dminuoso> Seems more sane
22:00:12 <huskle> ok, so i just wrap the list of lists in compose and then unwrap
22:00:13 <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)
22:00:26 × kenaryn quits (~aurele@cre71-h03-89-88-44-27.dsl.sta.abo.bbox.fr) (Quit: leaving)
22:00:38 zq parts (~zq@xorshift.org) ()
22:00:43 <dminuoso> % ap2 f a = getCompose (Compose f `ap` Compose a)
22:00:43 <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...
22:00:49 <dminuoso> % import Control.Applicative
22:00:49 <yahb2> <no output>
22:01:01 <dminuoso> seriously_guest: For sake of clarity, pick a particular `f`
22:01:05 <dminuoso> seriously_guest: Lets pin it to `Maybe`
22:01:29 <dminuoso> There's a many reasons why thinking just about particular type is more helpful at the beginning
22:01:37 <dsal> seriously_guest: Also, off-by-one lift :)
22:01:49 <dminuoso> % ap2 f a = getCompose (Compose f `ap` Compose a)
22:01:49 <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...
22:02:01 <dminuoso> Oh its monad isnt it
22:02:07 <dminuoso> % ap2 f a = getCompose (Compose f <*> Compose a)
22:02:07 <yahb2> <no output>
22:02:24 <dminuoso> % [[succ], [pred]] `ap2` [[1..5], [2..3]]
22:02:24 <yahb2> [[2,3,4,5,6],[3,4],[0,1,2,3,4],[1,2]]
22:02:33 <dsal> "ap" being a monad seems like a silly wart.
22:02:37 <dminuoso> huskle: this is what I would do (well I would actually use #. in there as well)
22:02:47 <dminuoso> dsal: historical reasons, its from before applicative was a thing
22:02:50 dsal isn't good at wording right now
22:03:36 <dminuoso> % import Data.Coerce
22:03:36 <yahb2> <no output>
22:03:42 <dminuoso> % :set -XMagicHash
22:03:42 <yahb2> <no output>
22:04:18 <dminuoso> % (#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c); (#.) = coerce
22:04:18 <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 ; ...
22:04:26 <dminuoso> % (#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c); (#.) _f = coerce
22:04:26 <yahb2> <no output>
22:04:38 <dminuoso> % ap2 f a = getCompose #. (Compose f <*> Compose a)
22:04:38 <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...
22:04:46 <huskle> sorry that last paste had an error
22:04:47 <huskle> https://paste.tomsmeding.com/jqWTKDzk
22:06:00 <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)...
22:06:35 <seriously_guest> I'm definetly way better off then where I started lol
22:07:19 <dminuoso> seriously_guest: Mmm there falseties in that statement.
22:07:33 <huskle> https://paste.tomsmeding.com/wTdCxUik
22:07:33 <dminuoso> liftA3 will by itself do that conversion
22:07:42 <huskle> that has the version not using the magic hash
22:08:01 <dminuoso> I gotta do some pondering why my #. isnt working here
22:08:58 <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)
22:09:16 <dminuoso> seriously_guest: Yes indeed! That sounds like a good excercise.
22:09:50 <huskle> whats it for anyway this  #.
22:10:23 <huskle> % fn = liftA2
22:10:24 <yahb2> <no output>
22:10:43 <huskle> % fn = liftA2 @Maybe
22:10:43 <yahb2> <no output>
22:10:50 <huskle> % :t fn
22:10:50 <yahb2> fn :: (a -> b -> c) -> Maybe a -> Maybe b -> Maybe c
22:11:15 <dminuoso> Ohh hold on, I see what's wrong.
22:11:27 <huskle> seriously_guest: its ok?
22:11:31 <dminuoso> I think its bedtime given that I thought (#.) was even needed.
22:11:47 <huskle> dont worry
22:11:49 <dminuoso> huskle: Its essentially a coercing (.) that ignores the left argument
22:11:57 <dminuoso> Here's an example of where its useful
22:12:01 <huskle> ok
22:12:03 <dminuoso> sum = getSum #. foldMap' Sum
22:12:26 <dminuoso> If we used (.) we could arise with some performance problems
22:12:40 <seriously_guest> fn g = maybeEmployee
22:12:55 <seriously_guest> sorry... didnt mean to hit enter
22:13:03 <dminuoso> No worries
22:14:24 <dminuoso> huskle: its mainly just useful in situations where you have eta reduced code and want to trip through newtypes
22:14:52 <huskle> eta reduction!? sounds fully jargon
22:15:14 <dminuoso> sum = getSum #. foldMap' Sum
22:15:16 <dminuoso> as opposed to
22:15:22 <dminuoso> sum xs = getSum (foldMap' Sum xs)
22:15:44 <dminuoso> Note that the obvious `sum = getSum . foldMap' Sum` can have performance issues
22:16:31 <dminuoso> tps://gitlab.haskell.org/ghc/ghc/-/issues/7542
22:16:37 <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)
22:17:30 <seriously_guest> ugh i didnt even apply g anywhere... im gonna go to bed myself
22:17:32 <dminuoso> Indeed, that looks correct. Note, that the parenthesis around nullary constructors like Nothing are not needed and should be omitted.
22:17:40 <dminuoso> Ah heh yeah
22:17:47 <dminuoso> Well you used `Employee` instead of `g`
22:18:06 <seriously_guest> :O
22:18:12 <dminuoso> But beyond that, its right.
22:18:30 <dminuoso> seriously_guest: note that for writing this out, there's a much much easier way
22:18:32 <dminuoso> and scalable way
22:18:38 <seriously_guest> Where do I donate haha...  ive abused this room long enough
22:18:50 <EvanR> right here, over here
22:18:51 <dminuoso> (Also note that the data constructor is called Just, not Maybe)
22:19:11 <dminuoso> `maybeEmployee g (Just name) (Just phone) = Just (g name phone); maybeEmployee _ _ _ = Nothing`
22:19:14 <huskle> I WILL TAKE DONATIONS!!
22:19:27 <dminuoso> This style scales nicer, since it wont require me to elaborate all the combinations
22:19:30 <iqubic> huskle: For what?
22:19:34 <huskle> lol
22:19:37 <huskle> to not die
22:19:50 <EvanR> imagine if you will that Just and Nothing are color coded blue for value and Maybe is colored red for types
22:19:53 <EvanR> or something
22:20:09 <EvanR> this guy conor mcbride uses a lot of colors to keep it straight
22:20:23 <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`
22:21:45 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 268 seconds)
22:23:10 <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
22:24:31 <dminuoso> seriously_guest: THat's part of why Im telling you to focus on just a particular type, like Maybe.
22:24:35 <dminuoso> Take small steps.
22:25:18 <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.
22:25:53 <tvandinther> Design question: When would you justify making a typeclass over making the same functions pattern match a sum type?
22:26:10 <dminuoso> tvandinther: Probably never.
22:26:20 <huskle> how do you mean?
22:26:23 <huskle> classes rule
22:26:52 <dminuoso> I think a lot of typeclasses are ill-placed and not a good idea.
22:26:58 troydm joins (~troydm@host-176-37-124-197.b025.la.net.ua)
22:27:23 <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
22:27:59 <dminuoso> seriously_guest: Sure, though that kind of interaction will require a combination of several libraries involving a variety of more complex ideas.
22:28:10 <dminuoso> So it may not be the best of ideas
22:28:25 <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`
22:28:29 <dminuoso> HTTP interaction is not particularly pleasent, our libraries do not take shortcuts,.
22:28:47 <dminuoso> tvandinther: pretty printing is exactly the kind of thing typeclasses are absolutely poor at.
22:28:53 <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
22:28:58 <dminuoso> I would just write `pprFoo`, `pprBar`, `pprQuux` functions as needed.
22:29:25 <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
22:29:30 <seriously_guest> But off to bed now... thanks for everyones help...
22:29:35 <dminuoso> The price is that you cant have two pretty printing for the same type
22:29:45 <dminuoso> seriously_guest: Good night and good luck on your journey!
22:29:56 <seriously_guest> :)
22:30:02 × seriously_guest quits (~seriously@2001:1c06:2715:c200:1a82:76d8:bd30:82fc) (Quit: Client closed)
22:30:18 <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
22:30:40 <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)
22:30:52 <tvandinther> thats a good point
22:31:18 <tvandinther> you said never earlier, but is there really any condition in which a custom typeclass would be justified?
22:31:46 <tvandinther> Seems like its probably a tool reserved for libraries
22:31:53 <dminuoso> https://stackoverflow.com/a/74380240/6636995 is an answer of mine that goes into the subject in amore detailed manner
22:32:01 <dminuoso> it depends on who you ask
22:32:14 <dminuoso> but there is a certain consensus that typeclasses are best used for things that are lawful
22:32:23 <dminuoso> Such that you can infer laws from the typeclass usage itself
22:33:03 <tvandinther> and I presume laws don't change on a whim
22:33:19 <tvandinther> making the brittleness less of an issue
22:33:26 <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.
22:34:06 <huskle> hey! i finished my smooth noise thing and it works!!
22:34:24 <huskle> https://paste.tomsmeding.com/5h9Zleox
22:34:30 <dminuoso> tvandinther: Right.
22:34:30 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
22:34:43 <dminuoso> tvandinther: my rule of thumb is that typeclasses are very rarely the right tool.
22:34:55 <dminuoso> Outside of situations where you're leveraging the type system
22:35:26 <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)
22:35:37 <huskle> erm, well actually it doesnt seem to work, those are supposed to be unifolrmly distributed on the unit interval
22:35:49 <huskle> but they are smooth wrt to changes in the params!
22:35:54 × Topsi quits (~Topsi@dyndsl-095-033-039-218.ewe-ip-backbone.de) (Read error: Connection reset by peer)
22:36:01 <huskle> rrg..
22:36:13 <huskle> see what i mean?
22:36:17 <dminuoso> tvandinther: and further, typeclasses are almost assuredly the worst thing for parsing/serializing/deserializing/decoding/encoding/pretty printing
22:36:25 <dminuoso> for the reasons outlined in my stackoverflow answer (and what I said earlier)
22:36:50 <tvandinther> Cool, good to know. It didn't feel like the right tool but good to understand some of the reasons beyond feeling haha
22:37:06 <tvandinther> Thanks
22:37:15 <dminuoso> wel "the worst thing" is a bit of a hyperbole.
22:37:24 <huskle> i think it must be averaging them or something...
22:37:38 <huskle> and some are negative?
22:37:45 <dminuoso> tvandinther: One thing where I do like typeclasses is classy lenses actually
22:37:47 king_gs joins (~Thunderbi@187.201.204.122)
22:37:49 <huskle> Why Are Some Negative!?
22:37:54 <EvanR> Yeah clearly you want to pretty print with Generics
22:38:21 <huskle> oh the seeds are negative..
22:39:10 <huskle> nope that doesnt get it
22:39:21 <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.
22:39:34 <dminuoso> That's driven by a HasCommonInterface typeclass
22:40:04 <dminuoso> (But here, the typeclass is directly tied to what is being produced, so there's no confusion ever
22:40:16 <tvandinther> EvanR: What would generics add to the pretty printing?
22:40:30 <EvanR> I'm half serious
22:40:38 <EvanR> since generics is accessed via type classes
22:40:55 <EvanR> but it does let you implement a pretty printer for all types at once
22:41:02 <dminuoso> tvandinther: better indentation. :p
22:41:16 <dminuoso> pretty-show/pretty-simple are amongst my staple libraries I add during debugging.
22:41:35 <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.
22:41:39 festive_kurbus joins (~festive_k@user/kurbus)
22:41:42 <dminuoso> But then again, I dont want to add Generic just for the ability of nicer printing
22:42:13 <dminuoso> My recent experiences with Generics have proven that its really terrible. :(
22:42:57 <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.
22:43:01 <tvandinther> I used a generic recently to "annotate" a type with additional data, is that a good use-case?
22:43:07 <dminuoso> Switched to TH equivalent code, and it went down to seconds..
22:43:23 <dminuoso> tvandinther: Can you elaborate?
22:44:52 <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 {...`
22:45:19 <tvandinther> But that's just my understanding of generics in an OOP context
22:45:40 <dminuoso> No, Generics is a meta programming technique
22:45:57 <dminuoso> As a random example:
22:46:56 <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
22:47:42 <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..
22:48:18 <tvandinther> How would that differ from `deriving (FromJSON, ToJSON)`
22:48:26 <dminuoso> It wouldnt
22:48:42 <tvandinther> same thing, different syntax?
22:48:50 <dminuoso> tvandinther: that mechanism is the same except it uses the DeriveAnyClass extension
22:49:01 <dminuoso> (it ends up doing the same)
22:49:25 <tvandinther> except that you can derive an instance in a different module from the type declaration?
22:49:29 <dminuoso> tvandinther: well the thing is
22:49:30 × huskle quits (~huskle@250.79-105-213.static.virginmediabusiness.co.uk) (Ping timeout: 268 seconds)
22:49:35 <dminuoso> Ah hold on
22:49:42 <dminuoso> Slight misconfusion
22:49:45 <dminuoso> │23:48:18 tvandinther | How would that differ from `deriving (FromJSON, ToJS
22:49:48 <dminuoso> In principle this wont work
22:49:56 <dminuoso> Because GHC doesnt know how to derive FromJSON
22:50:25 <dminuoso> (With DeriveAnyClass you *can* write it, but then it amounts to just writing `instance FromJSON Foo`
22:50:37 <dminuoso> Note that you will not specify an implementation
22:50:44 <dminuoso> this works because FromJSON has a default implementation:
22:50:53 <dminuoso> default parseJSON :: (Generic a, GFromJSON Zero (Rep a)) => Value -> Parser a
22:50:58 × Tuplanolla quits (~Tuplanoll@91-159-68-152.elisa-laajakaista.fi) (Quit: Leaving.)
22:51:02 <tvandinther> So they are the same provided you enable the language extension
22:51:20 <dminuoso> So as long as the type has `Generic`, then using the magic GFromJSON typeclass an implementation can be conjured.
22:51:40 <dminuoso> Which, beyond all the reasons I talked about earlier, has additional problems
22:52:24 <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`
22:52:24 <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?
22:52:34 <dminuoso> So with typeclasses you can scrutinize types sort of..
22:52:39 <dminuoso> Its not very direct
22:52:42 <dminuoso> Its not very fast either
22:53:10 <dminuoso> tvandinther: Well GHC knows how to derive Generic (assuming DeriveGeneric is enabled)
22:53:26 <dminuoso> Which is a typeclass that consists of two methods:
22:53:30 <dminuoso> And an associated type
22:53:45 <tvandinther> This sounds similar to Reflection in C#
22:53:49 <dminuoso> It very much is
22:53:52 <dminuoso> But it happens at compile time
22:53:56 <dminuoso> Via typeclasses and lookup
22:54:02 <dminuoso> The reflected type exists as a type itself
22:54:11 <dminuoso> And you generate code by pattern matching on that type with typeclass instances.
22:54:25 <dminuoso> And then there's a way to turn data into a generic representation
22:54:31 <dminuoso> that you can do the same scrutinization on data level too
22:54:43 <dminuoso> So we have hard to read/write code, that will compile extremely slowly
22:54:52 <dminuoso> And then there's a generic represnetation that GHC may not be able to get rid of
22:55:43 <tvandinther> I see, sounds interesting. A bit above my comfort level with Haskell still but good to be aware of.
22:55:43 <dminuoso> And further, once you have a Generic instance, *everybody* can pry into your object, encapsulation no longer possible
22:55:53 <dminuoso> Lots of bad ideas.
22:56:10 <dminuoso> TemplateHaskell can achieve many of the same problems
22:56:11 <festive_kurbus> sir this is a wendys
22:56:19 <dminuoso> But its *much* faster, and can easily generate optimal code
22:56:36 huskle joins (~huskle@250.79-105-213.static.virginmediabusiness.co.uk)
22:56:50 <tvandinther> Ah yep, sounds very familiar with the C# world. Reflection libraries are being replaced with codegen ones.
22:56:57 <huskle> ghci> all (>0) $ map (flip noise [0.900001..0.90001]) [1..1000]
22:56:57 <huskle> True
22:57:19 <tvandinther> Thanks for your explanations. Gotta get back to my day job now though :)
22:57:37 × litharge quits (litharge@libera/bot/litharge) (Quit: restarting)
22:57:56 litharge joins (litharge@libera/bot/litharge)
22:59:30 <huskle> i cant see how it could possibly be getting negative values!!
22:59:35 × king_gs quits (~Thunderbi@187.201.204.122) (Ping timeout: 264 seconds)
23:00:20 <huskle> oh ffs!
23:00:30 <huskle> there were two random seed creations
23:00:41 <huskle> and i only put one of them to generate strictly positive seeds
23:00:44 <huskle> it works now!@
23:02:44 srk- joins (~sorki@user/srk)
23:03:25 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
23:05:55 × srk quits (~sorki@user/srk) (Ping timeout: 260 seconds)
23:05:56 srk- is now known as srk
23:07:42 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
23:09:28 × coot quits (~coot@2a02:a310:e241:1b00:ec1a:e9df:79ac:66ba) (Quit: coot)
23:09:41 <masterbuilder> Do you guys think "What I wish I knew When Learning Haskell" is a good introductory book? For somebody not unfamiliar with FP, the Haskell book felt very slow at least in the beginning
23:10:22 <huskle> https://paste.tomsmeding.com/78JboB5O
23:10:33 <huskle> totally more excellent!
23:10:42 <huskle> can i have good marks on my assignment?
23:11:16 <huskle> masterbuilder: maybe you are used to VR books which are more fast paced
23:11:40 × gmg quits (~user@user/gehmehgeh) (Quit: Leaving)
23:12:07 <monochrom> https://www.google.com/search?q=wish+knew+haskell already exist and is not big enough to be a book.
23:12:11 <EvanR> it's funny how generics, reflection, and polymorphism means something totally different depending on language
23:12:30 <masterbuilder> huskle: what is a VR book?
23:12:48 <EvanR> like they took concepts and scrambled them with a group theory table
23:12:49 jmdaemon joins (~jmdaemon@user/jmdaemon)
23:13:14 <huskle> masterbuilder: like a regular book except blasted through your mind with ladar
23:13:22 <EvanR> then ruby added literal "concepts"
23:13:30 <huskle> lidar*
23:13:32 <huskle> whatever it is
23:13:35 <monochrom> "equality, fairness" mean totally opposite things to opposite people, too. :)
23:13:42 <huskle> blasted through your mind is the important part
23:13:44 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
23:13:49 <huskle> never mind how they combine the lazers and radar
23:13:53 × festive_kurbus quits (~festive_k@user/kurbus) (Quit: Client closed)
23:14:34 <huskle> both of which have `a' in the second charicter so iv no idea why its called lidar and not ladar
23:14:45 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
23:14:48 <masterbuilder> huskle: Lol, well idk, I just want something that talks about the challenging aspects of Haskell and yet is not an "advanced book", the syntax is familiar to me but I still lack many fundamentals probably
23:15:22 <EvanR> maybe you're ready to tackle A Gentle Introduction xD
23:15:30 <masterbuilder> seems like the haskell book is meant to be a first programming book almost, which is fine
23:15:38 <masterbuilder> EvanR: anything but?
23:15:46 <EvanR> I thought it was pretty tame
23:15:54 <EvanR> but had already read SICP
23:16:06 × opticblast quits (~Thunderbi@secure-165.caltech.edu) (Quit: opticblast)
23:16:09 <huskle> masterbuilder: there are no challenging parts of haskell, this is an uncommon misconception
23:16:20 opticblast joins (~Thunderbi@secure-165.caltech.edu)
23:16:23 <huskle> everyone knows haskell is the central language in computing
23:16:25 <geekosaur> it does things like jump into pattern matching assuming you already know what it is
23:16:35 <masterbuilder> the type system is a bit more elaborate than most languages
23:16:38 <mauke> https://www.haskell.org/tutorial/index.html this one?
23:16:40 <huskle> thats why lisp was based on it originally before they made C++
23:16:42 <monochrom> I wouldn't say learning Haskell is easy. But I wouldn't say learning any programming at all is easy either.
23:17:02 <monochrom> I could say though that some instant-gratification languages sugar-coat it.
23:17:13 <huskle> the type system is fine...
23:17:23 <huskle> most languages dont have one. this is not fine
23:17:38 <EvanR> lisp was based on what before who made C++
23:17:45 <monochrom> More generally, as in everything in life, the greatest challenge is expectation management.
23:17:46 <mauke> having a unitype is still a system
23:17:50 <EvanR> I can't complete that thought
23:18:01 × ec_ quits (~ec@gateway/tor-sasl/ec) (Remote host closed the connection)
23:18:02 <huskle> i mean, your probably not going to start writting associated type families strait away
23:18:03 <masterbuilder> well I don't know anything about type/cat theory, any books that explore those through haskell?
23:18:11 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
23:18:16 <huskle> or wondering why the hell your not allowed to make instances on data families
23:18:41 <huskle> masterbuilder: yeah, the stuff by van larhoven or whatever he's called
23:18:48 <mauke> masterbuilder: don't know about books, but there's a series of video lectures on youtube
23:18:49 ec_ joins (~ec@gateway/tor-sasl/ec)
23:18:50 <monochrom> There is a "math and logic through haskell" book.
23:18:56 <huskle> bartoz
23:19:02 <mauke> masterbuilder: category theory by bartosz milewski
23:19:05 <huskle> https://bartoszmilewski.com/2021/04/01/traversals-1-van-laarhoven-and-existentials/
23:19:17 <EvanR> I went through a lot of bartosz and never got to the part where programming came up
23:19:24 <monochrom> And yeah there are bartoz lectures and articles explaining cat theory in programmer terms.
23:19:30 <huskle> its crazyness
23:19:36 <huskle> why would anyone ask for that!?
23:19:39 <EvanR> just like I went through a lot of intro category theory and never got to any applications xD
23:19:41 <monochrom> not haskell-specific but certainly FP-specific.
23:19:48 <huskle> its the kind of stuff we basically resent edkmett associating us to
23:19:59 <huskle> hes all profunctors this and yoneda that
23:20:12 money_ joins (~money@user/polo)
23:20:18 <huskle> im like "wheres my biplate!?"
23:20:56 <masterbuilder> thanks for the links
23:20:59 <monochrom> I don't resent that.
23:21:07 <EvanR> yoneda dawg I heard you like functors in your functors
23:21:16 <huskle> i do! i had to bloody describe stacks ffs!
23:21:36 <huskle> https://ncatlab.org/nlab/show/Deligne-Mumford+stack
23:21:59 <monochrom> What I resent is how humans have polarized extremist opinions either way.
23:22:05 srk- joins (~sorki@user/srk)
23:22:21 <masterbuilder> in terms of books that get you writing haskell and learning the language without boring you though, is the gentle introduction the best option?
23:22:32 <huskle> i hate how elon musk isnt allowed to say he'll kill all his detractors
23:22:35 <EvanR> I like it for just getting to the point
23:22:38 <monochrom> Why do grown-ups still act like hormonized teenagers "this is the worst thing ever!" "this is the best thing ever!".
23:22:48 × srk quits (~sorki@user/srk) (Ping timeout: 268 seconds)
23:22:50 <huskle> because we are on drugs!
23:22:53 <masterbuilder> I can write some basic haskell programs but I can't say I really understand the language in any meaningful way
23:23:02 <huskle> its called DDS
23:23:17 × stiell quits (~stiell@gateway/tor-sasl/stiell) (Remote host closed the connection)
23:23:19 <huskle> https://en.wikipedia.org/wiki/Dopamine_dysregulation_syndrome
23:23:30 <EvanR> masterbuilder, well maybe you want to look into the denotational semantics or into the compiler intermediate languages for "more"
23:23:33 <monochrom> I think the gentle introduction is not boring.
23:23:46 <huskle> you should have more compassion, not everone is mentally capable of neutrality
23:24:02 <masterbuilder> EvanR: oof I tried to get into denotational semantics once, kind of dense
23:24:08 <masterbuilder> but interesting
23:24:09 stiell joins (~stiell@gateway/tor-sasl/stiell)
23:24:21 <monochrom> I think someone did opine that, though, HPFFP is drawn out, therefore boring. >:)
23:24:39 <EvanR> dense is often what I complain about youtube videos not being
23:24:47 srk- is now known as srk
23:24:48 <EvanR> they're quite diluted these days
23:25:07 <EvanR> give me a high dose of information please
23:25:08 × michalz quits (~michalz@185.246.204.77) (Remote host closed the connection)
23:25:24 <monochrom> Yeah I can pause when I need to.
23:25:56 <monochrom> Stop being entertaining. Just get to the point already.
23:26:37 <huskle> im starting a study into predicting structural activity relationships in a functional reactive model of the brain... if anyones interested
23:26:46 <huskle> based on some earlier work on sloppy modeling
23:26:59 <huskle> in the words of box "all models are wrong, but some are useful"
23:27:06 <hpc> monochrom: don't you know #haskell encourages pointfree style? :D
23:27:13 <monochrom> hahaha
23:28:32 <monochrom> My useful model is: people's minds have a backend that's more than 70% correct, and a not-gate as the frontend.
23:28:33 <huskle> did you know that certain serotonin receptors are hypothesized to work by mediating the activity at dopamine receptors?
23:28:48 <hpc> (also i still kind of like LYAH - it doesn't have any exercises, but i always felt those were too artificial for me to really want to do anyway)
23:28:54 <huskle> you have enough of that going on and you end up with an overdetermined system
23:29:21 <huskle> so we want to resparsify it, to get an effective model for the brain chemistry more conducive for denovo drug design
23:29:31 <monochrom> I come up with my own exercises.
23:30:18 <hpc> yeah, the best exercises are just having something of your own that you're motiviated to solve
23:30:24 <monochrom> But I'm scientific-method minded, I treat my understanding as hypotheses so I test them, even try to refute them. There are my exercises.
23:30:35 <huskle> its a big graph of up/down regulation, and its too big and needs pruning. basically, and rotating. not using "a quotient stack of a scheme over the étale site all whose automorphism groups are finite groups"
23:30:36 <hpc> ah, that's different from me
23:30:38 <sm> ha.. I asked chatgpt to condense HPFFP into six pages for me, it spun a while then kicked me out
23:30:50 <monochrom> haha
23:31:00 × eggplantade quits (~Eggplanta@104-55-37-220.lightspeed.sntcca.sbcglobal.net) (Remote host closed the connection)
23:31:10 <monochrom> I think six pages is unfair though. I think 200 pages is more fair.
23:31:26 eudjhsh joins (~nsanos@94.142.179.159)
23:31:35 eudjhsh parts (~nsanos@94.142.179.159) ()
23:32:30 <huskle> recently was desgned a class of drugs called dopamine disinhibitors, for people with parkisnons-like symptoms
23:32:35 <sm> I think it is having a meltdown
23:32:45 <huskle> what, your gpt3 bot?
23:32:52 <huskle> maybe you need to treat it better
23:33:04 <huskle> stop trying to feed it hormones or whatever your doing to it
23:33:07 <sm> the chatgpt AI generally
23:33:28 <sm> it was just a little summary, no big deal
23:33:40 <monochrom> Author: C. Allen, J. Moronuki, and ChatGPT. Title: HPFFPfromHPFFP.
23:33:47 <huskle> thats why elon had to fire all the twitter birds, because they were messing up the codebase with latte's
23:33:59 <huskle> and complacency
23:34:19 <sm> it's probably working through all the exercises and getting stuck on tooling issues
23:34:41 <huskle> the reprecussions of all the moderation glitches could have caused an outbreak of unfettered jibbering
23:35:12 <monochrom> ChatGPT learned lambda calculus and discovered the Y combinator and played with it and is still in the infinite loop... :)
23:35:16 <huskle>  and we would all end up living in Lanarks "Unthank", which i think is based on glasgow
23:36:10 <huskle> monochrom: i know! and it was using curly braces! it had to be stopped!
23:38:21 <huskle> all the neural-link satalites were going to fall out the sky!
23:39:13 <sm> off topic but.. after seeing a few examples and using chatgpt3 a little myself... suddenly I am expecting all software to understand my natural language... it's quite jarring
23:39:54 <hpc> i don't even expect humans to understand my natural language :P
23:40:07 <sm> maybe it was like this when early text adventurers first played an infocom game
23:40:28 × bobbingbob quits (~dfadsva@2604:3d09:207f:f650::7b3a) (Ping timeout: 260 seconds)
23:41:07 <EvanR> oh I threw so much nonsense at zork
23:41:21 <EvanR> command interpreters have only gone down hill from there
23:42:14 <huskle> In book three, Lanark cannot remember his past, and so in the prologue (at the end of book three) Lanark asks an oracle to tell him who he is, with the oracle stating he will tell him about Duncan Thaw. This ends book one and takes the reader to Thaw's story, thereby suggesting that Thaw and Lanark are perhaps the same person. There are also marked
23:42:14 <huskle> similarities between Unthank and Glasgow, again suggesting that both places are the same. Both localities are dystopian and both are ultimately apocalyptic for the characters - ending in destruction and death.
23:44:49 <huskle> any (if not all) of the other denizens of Unthank suffer from similar literal
23:44:49 <huskle> manifestations of their psychic-affective maladies; Lanark comes to find, sometimes to his
23:44:50 <huskle> horror, that each person he encounters is diseased. Each of these physically corresponds to
23:44:50 <huskle> something that is broken about their emotional state, but unlike Thaw/Lanark, I am only able to
23:44:51 <huskle> make conjecture about the childhood etiology of other characters’ diseases, and so will be
23:44:51 <huskle> positioning my interpretation squarely in their affect and in their politicized bodies. Likewise,
23:44:52 <huskle> Lanark’s etiology is both in Thaw’s childhood and the events that led up to his suicide, as well as
23:44:52 <huskle> his political body in the semi-dystopia of Unthank.
23:45:18 <huskle> its about as much gibberish as the original
23:45:28 <huskle> adios amigos!
23:45:32 × huskle quits (~huskle@250.79-105-213.static.virginmediabusiness.co.uk) (Quit: Connection closed)
23:48:15 × tomokojun quits (~tomokojun@static-198-54-134-86.cust.tzulo.com) (Remote host closed the connection)
23:48:30 crazazy` joins (~user@130.89.173.127)
23:48:34 tomokojun joins (~tomokojun@static-198-54-134-86.cust.tzulo.com)
23:49:16 <EvanR> what just happened
23:49:36 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
23:50:33 × crazazy quits (~user@130.89.171.62) (Ping timeout: 268 seconds)
23:50:42 Lears joins (~Leary]@user/Leary/x-0910699)
23:50:52 <monochrom> tangent :)
23:51:02 money is now known as polo
23:51:03 <monochrom> This is what's wrong with compassion.
23:51:04 × [Leary] quits (~Leary]@user/Leary/x-0910699) (Write error: Broken pipe)
23:53:01 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 268 seconds)
23:55:29 zant1 joins (~zant@62.214.20.26)

All times are in UTC on 2022-12-07.