Home liberachat/#haskell: Logs Calendar

Logs on 2023-03-04 (liberachat/#haskell)

00:00:58 finn_elija joins (~finn_elij@user/finn-elija/x-0085643)
00:00:58 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
00:00:58 finn_elija is now known as FinnElija
00:01:50 Albina_Pavlovna joins (~Albina_Pa@2603-7000-1203-4d7c-8c00-75d6-3287-dba1.res6.spectrum.com)
00:04:09 mauke_ joins (~mauke@user/mauke)
00:04:20 × gmg quits (~user@user/gehmehgeh) (Quit: Leaving)
00:04:32 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 255 seconds)
00:05:31 × mauke quits (~mauke@user/mauke) (Ping timeout: 248 seconds)
00:05:32 mauke_ is now known as mauke
00:07:20 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
00:07:54 × Tuplanolla quits (~Tuplanoll@91-159-68-152.elisa-laajakaista.fi) (Quit: Leaving.)
00:13:59 × jpds quits (~jpds@gateway/tor-sasl/jpds) (Ping timeout: 255 seconds)
00:14:55 jpds joins (~jpds@gateway/tor-sasl/jpds)
00:16:37 teo joins (~teo@user/teo)
00:17:20 × Albina_Pavlovna quits (~Albina_Pa@2603-7000-1203-4d7c-8c00-75d6-3287-dba1.res6.spectrum.com) (Quit: bb)
00:24:41 × segfaultfizzbuzz quits (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 255 seconds)
00:26:32 segfaultfizzbuzz joins (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
00:30:03 jmdaemon joins (~jmdaemon@user/jmdaemon)
00:33:48 × ix quits (~ix@46.68.8.176) (Ping timeout: 255 seconds)
00:35:58 ix joins (~ix@92.40.200.235.threembb.co.uk)
00:43:54 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
00:44:01 <danso> does ghc have an option (like a cli flag) to always import a module, even if nothing from it is used?
00:44:27 <danso> i see no reason not to have the stuff from Data.Function and Data.Functor always available
00:44:37 <geekosaur> no
00:44:54 <geekosaur> you can simulate it in ghci by putting imports in your .ghci file
00:45:22 <danso> yeah, i do that for ghci with many modules
00:46:33 <geekosaur> and one problem with doing that with ghc is it becomes difficult for you to distribute packages without forcing it on your users as well
00:46:36 × _xor quits (~xor@72.49.195.228) (Quit: exit)
00:48:32 × hugo- quits (znc@verdigris.lysator.liu.se) (Ping timeout: 248 seconds)
00:48:32 cheater_ joins (~Username@user/cheater)
00:49:55 × ix quits (~ix@92.40.200.235.threembb.co.uk) (Ping timeout: 260 seconds)
00:51:11 × cheater quits (~Username@user/cheater) (Ping timeout: 248 seconds)
00:51:18 cheater_ is now known as cheater
00:51:35 ix joins (~ix@213.205.241.31)
00:51:37 <danso> that makes sense to me. guess i'll just have to wait patiently for & and <&> to be added to the prelude
00:55:54 hugo joins (znc@verdigris.lysator.liu.se)
01:01:49 mauke_ joins (~mauke@user/mauke)
01:03:33 × mauke quits (~mauke@user/mauke) (Ping timeout: 268 seconds)
01:03:34 mauke_ is now known as mauke
01:08:18 wroathe joins (~wroathe@207-153-38-140.fttp.usinternet.com)
01:08:18 × wroathe quits (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
01:08:18 wroathe joins (~wroathe@user/wroathe)
01:10:53 × albet70 quits (~xxx@2400:8902::f03c:92ff:fe60:98d8) (Remote host closed the connection)
01:13:11 wroathe_ joins (~wroathe@207-153-38-140.fttp.usinternet.com)
01:14:39 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 268 seconds)
01:17:00 albet70 joins (~xxx@2400:8902::f03c:92ff:fe60:98d8)
01:24:20 × mncheck quits (~mncheck@193.224.205.254) (Ping timeout: 252 seconds)
01:25:49 × cheater quits (~Username@user/cheater) (Read error: Connection reset by peer)
01:26:33 cheater joins (~Username@user/cheater)
01:27:10 × Midjak quits (~Midjak@82.66.147.146) (Quit: This computer has gone to sleep)
01:46:41 × adanwan_ quits (~adanwan@gateway/tor-sasl/adanwan) (Ping timeout: 255 seconds)
01:46:49 adanwan joins (~adanwan@gateway/tor-sasl/adanwan)
01:59:02 × azimut quits (~azimut@gateway/tor-sasl/azimut) (Quit: ZNC - https://znc.in)
01:59:47 azimut joins (~azimut@gateway/tor-sasl/azimut)
02:05:50 × gurkenglas quits (~gurkengla@dynamic-046-114-176-169.46.114.pool.telefonica.de) (Ping timeout: 268 seconds)
02:05:52 × thegeekinside quits (~thegeekin@189.141.115.134) (Ping timeout: 248 seconds)
02:08:11 × JimL quits (~quassel@89-162-26-217.fiber.signal.no) (Ping timeout: 248 seconds)
02:09:24 × adanwan quits (~adanwan@gateway/tor-sasl/adanwan) (Remote host closed the connection)
02:09:41 adanwan joins (~adanwan@gateway/tor-sasl/adanwan)
02:17:25 × hpc quits (~juzz@ip98-169-35-163.dc.dc.cox.net) (Ping timeout: 260 seconds)
02:19:05 hpc joins (~juzz@ip98-169-35-163.dc.dc.cox.net)
02:20:41 × Lord_of_Life quits (~Lord@user/lord-of-life/x-2819915) (Ping timeout: 256 seconds)
02:21:48 Lord_of_Life joins (~Lord@user/lord-of-life/x-2819915)
02:25:41 bontaq joins (~user@ool-45779fe5.dyn.optonline.net)
02:39:48 × wroathe_ quits (~wroathe@207-153-38-140.fttp.usinternet.com) (Quit: leaving)
02:54:41 × harveypwca quits (~harveypwc@2601:246:c180:a570:3828:d8:e523:3f67) (Quit: Leaving)
03:02:13 × jero98772 quits (~jero98772@2800:484:1d80:d8ce:efcc:cbb3:7f2a:6dff) (Remote host closed the connection)
03:05:05 grnman_ joins (~michaelsc@c-66-176-3-51.hsd1.fl.comcast.net)
03:10:46 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
03:12:32 jero98772 joins (~jero98772@2800:484:1d80:d8ce:efcc:cbb3:7f2a:6dff)
03:15:11 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 248 seconds)
03:18:30 × vglfr quits (~vglfr@145.224.100.65) (Ping timeout: 255 seconds)
03:19:11 Guest391 joins (~talismani@2601:200:c000:f7a0::5321)
03:20:01 <Guest391> If I have a variable inside a do-block like `lst <- liftIO $ STM.readTVarIO listVar` which is only used once
03:20:27 <Guest391> (say: `forM_ (reverse $ zip [0 ..] lst) $ ...`)
03:20:41 <Guest391> how can I inline it so it doesn't take up its own line?
03:20:43 × jero98772 quits (~jero98772@2800:484:1d80:d8ce:efcc:cbb3:7f2a:6dff) (Remote host closed the connection)
03:22:31 gastus_ joins (~gastus@185.6.123.186)
03:26:00 × gastus quits (~gastus@185.6.123.181) (Ping timeout: 268 seconds)
03:33:42 finn_elija joins (~finn_elij@user/finn-elija/x-0085643)
03:33:42 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
03:33:42 finn_elija is now known as FinnElija
03:35:09 × td_ quits (~td@i5387090C.versanet.de) (Ping timeout: 255 seconds)
03:36:54 td_ joins (~td@i53870919.versanet.de)
03:47:23 × jrm quits (~jrm@user/jrm) (Quit: ciao)
03:47:45 jrm joins (~jrm@user/jrm)
03:51:27 vglfr joins (~vglfr@145.224.100.65)
04:04:50 × califax quits (~califax@user/califx) (Ping timeout: 255 seconds)
04:06:26 califax joins (~califax@user/califx)
04:09:37 × euandreh quits (~Thunderbi@189.6.18.7) (Remote host closed the connection)
04:18:25 × waleee quits (~waleee@2001:9b0:21c:4000:5bf9:6515:c030:57b7) (Quit: WeeChat 3.8)
04:19:12 × bontaq quits (~user@ool-45779fe5.dyn.optonline.net) (Ping timeout: 248 seconds)
04:20:37 waleee joins (~waleee@2001:9b0:21c:4000:5bf9:6515:c030:57b7)
04:23:58 × ix quits (~ix@213.205.241.31) (Ping timeout: 268 seconds)
04:25:25 ix joins (~ix@213.205.241.31)
04:30:45 × ix quits (~ix@213.205.241.31) (Read error: Connection reset by peer)
04:32:40 × azimut quits (~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection)
04:34:12 azimut joins (~azimut@gateway/tor-sasl/azimut)
04:36:37 ix joins (~ix@213.205.241.31)
04:41:04 × waleee quits (~waleee@2001:9b0:21c:4000:5bf9:6515:c030:57b7) (Ping timeout: 248 seconds)
04:46:15 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 255 seconds)
04:57:21 × ec quits (~ec@gateway/tor-sasl/ec) (Remote host closed the connection)
04:57:50 ec joins (~ec@gateway/tor-sasl/ec)
05:04:52 mechap_ joins (~mechap@user/mechap)
05:06:07 × polyphem_ quits (~rod@2a02:810d:840:8754:224e:f6ff:fe5e:bc17) (Ping timeout: 248 seconds)
05:06:31 × grnman_ quits (~michaelsc@c-66-176-3-51.hsd1.fl.comcast.net) (Ping timeout: 268 seconds)
05:07:44 × mechap quits (~mechap@user/mechap) (Ping timeout: 248 seconds)
05:09:24 × jwiegley_ quits (~jwiegley@76-234-69-149.lightspeed.frokca.sbcglobal.net) (Quit: ZNC - http://znc.in)
05:09:24 × johnw quits (~johnw@76-234-69-149.lightspeed.frokca.sbcglobal.net) (Quit: ZNC - http://znc.in)
05:11:48 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
05:14:16 zmt00 joins (~zmt00@user/zmt00)
05:44:50 × troydm quits (~troydm@user/troydm) (Ping timeout: 246 seconds)
05:45:32 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 255 seconds)
05:47:04 Lycurgus joins (~juan@user/Lycurgus)
05:56:48 mbuf joins (~Shakthi@49.204.129.184)
06:01:19 × tzh quits (~tzh@c-24-21-73-154.hsd1.or.comcast.net) (Quit: zzz)
06:11:52 <Jade[m]1> `liftIO (STM.readTVarIO listVar >>= forM_ . (reverse $ zip [0..])` something like this?
06:12:10 <Inst> btw, question
06:12:19 <Jade[m]1> * `liftIO (STM.readTVarIO listVar >>= forM_ . (reverse $ zip [0..]) $ ...` something like this?
06:12:23 <Inst> if I manually check a list's length via a pattern match, is this O(1) or O(n)?
06:12:39 <Jade[m]1> O(n)
06:13:11 <Jade[m]1> if you mean... (full message at <https://libera.ems.host/_matrix/media/v3/download/libera.chat/9d8499dc9b01ba9f0922911c19cf2684a3e0283e>)
06:13:49 <Jade[m]1> * if you mean... (full message at <https://libera.ems.host/_matrix/media/v3/download/libera.chat/5199fda87689eba68481c826553467a206767ee5>)
06:14:35 <Jade[m]1> * if you mean... (full message at <https://libera.ems.host/_matrix/media/v3/download/libera.chat/de7c70fec03d3a2afbfc22fd198451b8c29c160d>)
06:17:27 <Inst> i mean, u [_,_,_,_] = True
06:17:34 <Inst> so it's a manual check vs length 4
06:17:37 <Inst> still O(n)?
06:20:36 <jackdk> It's bounded above by a constant function
06:21:38 takuan joins (~takuan@178-116-218-225.access.telenet.be)
06:24:07 <Inst> i don't understand, I guess it's still O(n)?
06:24:29 <Inst> isSixCards [_,_,_,_,_,_] = True; isSixCards _ = False
06:25:05 mrcsno joins (~mrcsno@user/mrcsno)
06:25:27 <Inst> if this doesn't work, do you think changing my State monad record to include a length field can improve performance?
06:32:39 falafel joins (~falafel@12.237.33.2)
06:44:57 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
06:46:05 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
06:47:21 <mauke> the check itself is O(1)
06:49:15 × mixfix41 quits (~sdenynine@user/mixfix41) (Ping timeout: 260 seconds)
06:53:52 × machinedgod quits (~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 248 seconds)
06:58:23 bgs joins (~bgs@212-85-160-171.dynamic.telemach.net)
06:59:07 <Inst> holy shit, so I have O(1) length for lists, but only for specific lengths?
06:59:52 <monochrom> Haha the wonder of O.
07:01:41 × azimut quits (~azimut@gateway/tor-sasl/azimut) (Ping timeout: 255 seconds)
07:03:45 <mauke> yes. that's O(specific_length), which is O(1)
07:04:09 <mauke> assuming the spine of the list is sufficiently evaluated, of course
07:04:31 × segfaultfizzbuzz quits (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 248 seconds)
07:04:33 <monochrom> Related: Every natural number is finite, but the whole set is infinite.
07:05:16 <monochrom> More strongly, there is no upper bound.
07:05:45 <Inst> or rather, O(1) checking for every particular length, which I suppose is probably equivalent
07:06:04 <Inst> but it's useful to know since lists haev the drawback of being terrible at random access and having nasty length
07:06:10 <Inst> since I have a specific length I want to check, well
07:06:12 <Inst> thanks for the help
07:09:53 segfaultfizzbuzz joins (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
07:10:32 johnw joins (~johnw@76-234-69-149.lightspeed.frokca.sbcglobal.net)
07:10:55 jwiegley joins (~jwiegley@76-234-69-149.lightspeed.frokca.sbcglobal.net)
07:13:45 npmania1 joins (~Thunderbi@45.8.223.209)
07:14:50 Luj joins (~Luj@2a01:e0a:5f9:9681:5880:c9ff:fe9f:3dfb)
07:15:11 × npmania quits (~Thunderbi@91.193.7.62) (Ping timeout: 248 seconds)
07:15:14 × Guest391 quits (~talismani@2601:200:c000:f7a0::5321) (Ping timeout: 252 seconds)
07:16:48 tomboy64 joins (~tomboy64@user/tomboy64)
07:17:17 npmania joins (~Thunderbi@45.8.223.254)
07:18:25 × npmania1 quits (~Thunderbi@45.8.223.209) (Ping timeout: 260 seconds)
07:21:31 elevenkb joins (~elevenkb@105.224.34.36)
07:23:34 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
07:27:21 × segfaultfizzbuzz quits (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 255 seconds)
07:32:54 × falafel quits (~falafel@12.237.33.2) (Remote host closed the connection)
07:33:13 falafel joins (~falafel@12.237.33.2)
07:34:36 adanwan_ joins (~adanwan@gateway/tor-sasl/adanwan)
07:34:59 × adanwan quits (~adanwan@gateway/tor-sasl/adanwan) (Ping timeout: 255 seconds)
07:34:59 × jpds quits (~jpds@gateway/tor-sasl/jpds) (Ping timeout: 255 seconds)
07:35:26 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Ping timeout: 255 seconds)
07:37:08 × npmania quits (~Thunderbi@45.8.223.254) (Ping timeout: 255 seconds)
07:37:46 jpds joins (~jpds@gateway/tor-sasl/jpds)
07:37:59 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
07:39:08 npmania joins (~Thunderbi@45.8.223.254)
07:39:59 harveypwca joins (~harveypwc@2601:246:c180:a570:3828:d8:e523:3f67)
07:41:55 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
07:43:26 manwithluck joins (~manwithlu@2406:da14:b37:1300:8c42:7d16:8950:6c74)
07:44:00 × falafel quits (~falafel@12.237.33.2) (Ping timeout: 255 seconds)
07:45:34 lisbeths joins (uid135845@id-135845.lymington.irccloud.com)
07:52:34 × monochrom quits (trebla@216.138.220.146) (Quit: NO CARRIER)
07:52:45 cheater_ joins (~Username@user/cheater)
07:55:11 × cheater quits (~Username@user/cheater) (Ping timeout: 248 seconds)
07:55:21 cheater_ is now known as cheater
07:56:00 segfaultfizzbuzz joins (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
07:57:57 × eggplantade quits (~Eggplanta@104-55-37-220.lightspeed.sntcca.sbcglobal.net) (Remote host closed the connection)
07:58:59 monochrom joins (trebla@216.138.220.146)
08:00:25 × segfaultfizzbuzz quits (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 268 seconds)
08:01:27 × jinsun quits (~jinsun@user/jinsun) (Ping timeout: 255 seconds)
08:05:07 jinsun joins (~jinsun@user/jinsun)
08:06:11 RootWeiller joins (~rootweill@dynamic-186-154-32-12.dynamic.etb.net.co)
08:14:22 segfaultfizzbuzz joins (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
08:15:30 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 255 seconds)
08:24:07 kupi joins (uid212005@id-212005.hampstead.irccloud.com)
08:26:08 × segfaultfizzbuzz quits (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 248 seconds)
08:31:42 acidjnk_new joins (~acidjnk@p200300d6e715c474301fac3f480ef3eb.dip0.t-ipconnect.de)
08:32:47 trev_ joins (~trev@109-252-35-99.nat.spd-mgts.ru)
08:34:50 gnalzo joins (~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
08:42:31 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
08:53:45 <tomsmeding> Inst: they're basically 'data [a] = a : [a] | []'
08:54:08 <tomsmeding> checking length on that is not going to be able to do anything more efficient than just traversing the linked list and seeing when the [] comes
08:54:10 <Inst> that's what i show everyone when they claim "I hate Haskell, what is this whole recursion thing?"
08:54:25 <Inst> yup, thanks, that was the answer i was expecting
08:54:41 <Inst> it'd fail faster, but that's about it
08:54:50 <tomsmeding> if it's longer than 6, you mean?
08:54:51 <tomsmeding> yeah
08:55:13 segfaultfizzbuzz joins (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
08:55:24 <Inst> if it's shorter than 6
08:55:33 <Inst> anything not 6, i.e, [] shows up too early, or too late
08:56:49 <tomsmeding> Inst: well if it's longer than 6, then you'll know by the time you see the 7th element
08:57:07 <tomsmeding> you'll know the situation in time min(6, length list)
08:57:29 <tomsmeding> note that this doesn't work if you write 'length l == 6', then it'll traverse the whole list always
08:58:26 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0)
08:58:36 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
08:59:30 × segfaultfizzbuzz quits (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 255 seconds)
09:00:11 × ericjmorey[m] quits (~ericjmore@2001:470:69fc:105::7afc) (Quit: You have been kicked for being idle)
09:00:46 × ix quits (~ix@213.205.241.31) (Read error: Connection reset by peer)
09:03:06 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0) (Ping timeout: 255 seconds)
09:05:55 gurkenglas joins (~gurkengla@dynamic-046-114-176-169.46.114.pool.telefonica.de)
09:06:01 <Inst> slight improvement, i guess, sigh, i'm annoyed as all hell because the jsons that take 24 hours to output on some other software that took 6 months to work seem to have developed major bugs
09:06:29 <Inst> and this piece of software, I decided to try to rewrite it, to no avail
09:07:11 <Inst> i got advice from a pro haskeller to change it from forConcurrently forkIO concurrency to par-based parallelism, but I'm not getting any speed up :(
09:14:33 Tuplanolla joins (~Tuplanoll@91-159-68-152.elisa-laajakaista.fi)
09:16:16 × bgamari quits (~bgamari@2a06:a000:b00d::2) (Ping timeout: 248 seconds)
09:18:17 bgamari joins (~bgamari@64.223.130.214)
09:25:09 Guest2606 joins (~talismani@2601:200:c000:f7a0::5321)
09:27:27 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection)
09:28:19 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
09:45:15 × Lycurgus quits (~juan@user/Lycurgus) (Ping timeout: 268 seconds)
09:52:36 segfaultfizzbuzz joins (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
09:53:13 × califax quits (~califax@user/califx) (Remote host closed the connection)
09:54:40 califax joins (~califax@user/califx)
09:56:52 wootehfoot joins (~wootehfoo@user/wootehfoot)
09:57:12 × segfaultfizzbuzz quits (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 255 seconds)
09:59:35 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
10:01:36 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 255 seconds)
10:05:02 × lisbeths quits (uid135845@id-135845.lymington.irccloud.com) (Quit: Connection closed for inactivity)
10:06:54 RootWeiller parts (~rootweill@dynamic-186-154-32-12.dynamic.etb.net.co) (Leaving)
10:08:46 mei joins (~mei@user/mei)
10:11:56 × Guest2606 quits (~talismani@2601:200:c000:f7a0::5321) (Ping timeout: 246 seconds)
10:12:16 jakalx joins (~jakalx@base.jakalx.net)
10:13:51 <tomsmeding> https://play.haskell.org has ghc 9.6.1-rc1 now :)
10:15:07 × freeside quits (~mengwong@103.252.202.85) (Ping timeout: 248 seconds)
10:15:45 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
10:17:00 freeside joins (~mengwong@103.252.202.85)
10:17:58 ix joins (~ix@213.205.241.31)
10:20:15 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 248 seconds)
10:20:17 × ix quits (~ix@213.205.241.31) (Read error: Connection reset by peer)
10:21:59 × Sgeo quits (~Sgeo@user/sgeo) (Read error: Connection reset by peer)
10:23:18 × aweinstock quits (~aweinstoc@cpe-74-76-189-75.nycap.res.rr.com) (Ping timeout: 255 seconds)
10:24:44 segfaultfizzbuzz joins (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
10:25:40 <Inst> almost there, could always be more late
10:26:06 <Inst> you can't switch underlying (or wrapping) monads with monad transformers, right? Reader to Writer is absurd, but IO to identity? I suppose that's unliftIO?
10:29:10 × segfaultfizzbuzz quits (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 260 seconds)
10:34:16 Midjak joins (~Midjak@82.66.147.146)
10:38:56 × shriekingnoise quits (~shrieking@186.137.175.87) (Ping timeout: 248 seconds)
10:38:58 × elevenkb quits (~elevenkb@105.224.34.36) (Ping timeout: 260 seconds)
10:43:27 gmg joins (~user@user/gehmehgeh)
10:49:24 × Midjak quits (~Midjak@82.66.147.146) (Ping timeout: 255 seconds)
10:51:20 mmhat joins (~mmh@p200300f1c70de8ffee086bfffe095315.dip0.t-ipconnect.de)
10:52:01 L29Ah parts (~L29Ah@wikipedia/L29Ah) ()
10:52:05 × mmhat quits (~mmh@p200300f1c70de8ffee086bfffe095315.dip0.t-ipconnect.de) (Client Quit)
10:53:11 × bgamari quits (~bgamari@64.223.130.214) (Ping timeout: 260 seconds)
10:53:58 × mrcsno quits (~mrcsno@user/mrcsno) (Quit: WeeChat 3.5)
10:55:45 bgamari joins (~bgamari@64.223.158.161)
11:00:43 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0)
11:05:03 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0) (Ping timeout: 255 seconds)
11:08:12 mncheck joins (~mncheck@193.224.205.254)
11:08:22 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
11:12:10 segfaultfizzbuzz joins (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
11:13:53 Axman6 joins (~Axman6@user/axman6)
11:14:42 Guest7532 joins (~talismani@2601:200:c000:f7a0::5321)
11:16:16 × segfaultfizzbuzz quits (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 248 seconds)
11:17:14 ix joins (~ix@213.205.241.31)
11:17:42 × califax quits (~califax@user/califx) (Remote host closed the connection)
11:18:08 califax joins (~califax@user/califx)
11:19:02 × harveypwca quits (~harveypwc@2601:246:c180:a570:3828:d8:e523:3f67) (Quit: Leaving)
11:25:20 × ix quits (~ix@213.205.241.31) (Ping timeout: 248 seconds)
11:28:28 Inst_ joins (~Inst@2601:6c4:4081:54f0:4dc:ae3f:dfd:1774)
11:28:32 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 248 seconds)
11:28:32 × gnalzo quits (~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Ping timeout: 248 seconds)
11:29:29 × econo quits (uid147250@user/econo) (Quit: Connection closed for inactivity)
11:29:53 × Inst quits (~Inst@2601:6c4:4081:54f0:e1bb:9a51:4c8c:9c0a) (Killed (NickServ (GHOST command used by Inst_!~Inst@2601:6c4:4081:54f0:4dc:ae3f:dfd:1774)))
11:29:54 Inst_ is now known as Inst
11:38:35 × gurkenglas quits (~gurkengla@dynamic-046-114-176-169.46.114.pool.telefonica.de) (Ping timeout: 264 seconds)
11:38:52 × foul_owl quits (~kerry@71.212.143.88) (Ping timeout: 252 seconds)
11:40:16 × mechap_ quits (~mechap@user/mechap) (Ping timeout: 248 seconds)
11:41:31 gnalzo joins (~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
11:42:10 mechap_ joins (~mechap@user/mechap)
11:43:47 <jackdk> see `class MFunctor` in package `mmorph`
11:43:55 segfaultfizzbuzz joins (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
11:48:35 × segfaultfizzbuzz quits (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 268 seconds)
11:48:49 ix joins (~ix@213.205.241.31)
11:54:39 foul_owl joins (~kerry@157.97.134.61)
11:57:02 × ubert quits (~Thunderbi@p548c9fde.dip0.t-ipconnect.de) (Remote host closed the connection)
12:03:03 __monty__ joins (~toonn@user/toonn)
12:12:11 grnman_ joins (~michaelsc@c-66-176-3-51.hsd1.fl.comcast.net)
12:15:41 × Angelz quits (Angelz@Angelz.oddprotocol.org) (Ping timeout: 256 seconds)
12:21:47 × jinsl quits (~jinsl@2408:8207:2558:e50:211:32ff:fec8:6aea) (Ping timeout: 246 seconds)
12:21:52 jinsl- joins (~jinsl@2408:8207:2556:f740:211:32ff:fec8:6aea)
12:26:20 × sammelweis quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Quit: No Ping reply in 180 seconds.)
12:26:57 Monster196883 joins (~hp@103.15.228.66)
12:27:28 sammelweis joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
12:30:12 × vglfr quits (~vglfr@145.224.100.65) (Ping timeout: 255 seconds)
12:30:15 Midjak joins (~Midjak@82.66.147.146)
12:30:55 × remedan quits (~remedan@ip-94-112-0-18.bb.vodafone.cz) (Ping timeout: 246 seconds)
12:31:28 × Monster196883 quits (~hp@103.15.228.66) (Ping timeout: 248 seconds)
12:33:22 jero98772 joins (~jero98772@2800:484:1d80:d8ce:efcc:cbb3:7f2a:6dff)
12:33:33 Lycurgus joins (~juan@98.4.112.204)
12:33:33 × Lycurgus quits (~juan@98.4.112.204) (Changing host)
12:33:33 Lycurgus joins (~juan@user/Lycurgus)
12:34:26 segfaultfizzbuzz joins (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
12:36:06 vglfr joins (~vglfr@145.224.100.65)
12:38:56 × segfaultfizzbuzz quits (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 248 seconds)
12:42:44 × bgs quits (~bgs@212-85-160-171.dynamic.telemach.net) (Remote host closed the connection)
12:46:20 Monster196883 joins (~hp@103.15.228.66)
12:48:31 × Lycurgus quits (~juan@user/Lycurgus) (Quit: Exeunt: personae.ai-integration.biz)
12:51:21 <dminuoso_> Inst: You cant do something like IO to Identity (at least not safely)
12:51:32 <dminuoso_> Or well, I guess you can:
12:51:35 <dminuoso_> % :t unsafePerformIO
12:51:35 <yahb2> <interactive>:1:1: error: Variable not in scope: unsafePerformIO
12:51:44 <dminuoso_> unsafePerformIO :: IO ~> Identity
12:51:46 <dminuoso_> Roughly.
12:57:35 × mbuf quits (~Shakthi@49.204.129.184) (Ping timeout: 248 seconds)
12:58:30 mbuf joins (~Shakthi@49.207.178.186)
13:00:37 remedan joins (~remedan@ip-94-112-0-18.bb.vodafone.cz)
13:01:24 Angelz joins (Angelz@Angelz.oddprotocol.org)
13:06:41 × mechap_ quits (~mechap@user/mechap) (Quit: WeeChat 3.8)
13:08:20 × jmdaemon quits (~jmdaemon@user/jmdaemon) (Ping timeout: 255 seconds)
13:08:33 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
13:09:27 mechap joins (~mechap@user/mechap)
13:09:47 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
13:12:00 × ix quits (~ix@213.205.241.31) (Ping timeout: 248 seconds)
13:15:00 × wootehfoot quits (~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
13:24:06 segfaultfizzbuzz joins (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
13:25:18 azimut joins (~azimut@gateway/tor-sasl/azimut)
13:25:43 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
13:26:56 freeside_ joins (~mengwong@103.252.202.85)
13:27:52 × freeside quits (~mengwong@103.252.202.85) (Ping timeout: 268 seconds)
13:28:15 × Monster196883 quits (~hp@103.15.228.66) (Ping timeout: 260 seconds)
13:29:06 × segfaultfizzbuzz quits (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 268 seconds)
13:31:33 × gnalzo quits (~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 3.8)
13:31:43 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 248 seconds)
13:32:23 CiaoSen joins (~Jura@p200300c9570e91002a3a4dfffe84dbd5.dip0.t-ipconnect.de)
13:45:16 Ashkan joins (~Ashkan@a119011.upc-a.chello.nl)
13:53:59 hammdist joins (~hammdist@67.169.114.135)
13:56:04 wootehfoot joins (~wootehfoo@user/wootehfoot)
13:56:52 × pavonia quits (~user@user/siracusa) (Quit: Bye!)
13:59:22 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
13:59:37 psydroid is now known as psydroid[m]
14:00:59 × CiaoSen quits (~Jura@p200300c9570e91002a3a4dfffe84dbd5.dip0.t-ipconnect.de) (Ping timeout: 255 seconds)
14:04:06 psydroid[m] is now known as psydroid
14:06:23 × acidjnk_new quits (~acidjnk@p200300d6e715c474301fac3f480ef3eb.dip0.t-ipconnect.de) (Ping timeout: 248 seconds)
14:10:20 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
14:20:37 L29Ah joins (~L29Ah@wikipedia/L29Ah)
14:20:42 × bgamari quits (~bgamari@64.223.158.161) (Quit: ZNC 1.8.2 - https://znc.in)
14:21:20 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 255 seconds)
14:26:13 machinedgod joins (~machinedg@d198-53-218-113.abhsia.telus.net)
14:30:41 bgamari joins (~bgamari@2a06:a000:b00d::2)
14:31:38 CiaoSen joins (~Jura@p200300c9570e91002a3a4dfffe84dbd5.dip0.t-ipconnect.de)
14:36:26 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
14:40:01 [itchyjunk] joins (~itchyjunk@user/itchyjunk/x-7353470)
14:45:08 × grnman_ quits (~michaelsc@c-66-176-3-51.hsd1.fl.comcast.net) (Ping timeout: 252 seconds)
14:47:26 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 255 seconds)
14:50:26 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
14:51:24 × perrierjouet quits (~perrier-j@modemcable048.127-56-74.mc.videotron.ca) (Quit: WeeChat 3.8)
14:52:53 perrierjouet joins (~perrier-j@modemcable048.127-56-74.mc.videotron.ca)
14:54:11 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
14:55:19 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
15:00:37 × earthy quits (~arthurvl@2a02:a469:f5e2:1:ba27:ebff:fea0:40b0) (Quit: WeeChat 2.3)
15:04:23 bontaq joins (~user@ool-45779fe5.dyn.optonline.net)
15:04:32 × dcoutts_ quits (~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net) (Ping timeout: 248 seconds)
15:04:46 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Read error: Connection reset by peer)
15:08:34 segfaultfizzbuzz joins (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
15:15:21 × shapr quits (~user@68.54.166.125) (Ping timeout: 255 seconds)
15:23:27 emmanuelux joins (~emmanuelu@user/emmanuelux)
15:23:52 × kupi quits (uid212005@id-212005.hampstead.irccloud.com) (Quit: Connection closed for inactivity)
15:28:17 dcoutts_ joins (~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net)
15:28:33 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
15:33:51 mvk joins (~mvk@2607:fea8:5caa:ac00::67db)
15:33:53 × mvk quits (~mvk@2607:fea8:5caa:ac00::67db) (Client Quit)
15:36:20 × Ashkan quits (~Ashkan@a119011.upc-a.chello.nl) (Quit: Client closed)
15:37:12 wroathe joins (~wroathe@207-153-38-140.fttp.usinternet.com)
15:37:12 × wroathe quits (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
15:37:12 wroathe joins (~wroathe@user/wroathe)
15:38:25 × mbuf quits (~Shakthi@49.207.178.186) (Quit: Leaving)
15:42:32 gnalzo joins (~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
15:43:13 coot joins (~coot@2a02:a310:e241:1b00:ec1a:e9df:79ac:66ba)
15:55:35 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 260 seconds)
15:56:12 Ashkan joins (~Ashkan@a119011.upc-a.chello.nl)
15:56:49 <Ashkan> I'm having serious trouble understanding and resolving a "constraint is smaller than head" situation https://paste.tomsmeding.com/kjvf1mee
15:57:56 <c_wraith> the full explanation is long. the short explanation is don't do that. Types should opt in to belonging to a class, not be enrolled despite their wishes.
15:58:03 <c_wraith> ... yes, types have wishes
15:58:04 <Ashkan> I want to say `give C1 m` (`m :: * -> *` ) then `C2 m` can be deduced/instanced/instantiated (don't know the correct term)
15:58:44 <Ashkan> In Scala, this was very easy:D  I understand instances are global in haskell hence some restrictions apply but I don't get what's wrong here
15:59:03 <c_wraith> Well, the error message tells you exactly how to make it go away
15:59:11 <c_wraith> but it won't work the way you want
15:59:17 <int-e> UndecidableInstances isn't really that scary. What is scary though, is the thought of adding another `Ash` instance because that will be overlapping.
15:59:42 <int-e> So I think, f2 should just be a function of type Yas m => m ()
16:00:05 × MangoIV[m] quits (~mangoivma@2001:470:69fc:105::2:8417) (Quit: You have been kicked for being idle)
16:00:17 int-e is using, too many commas.
16:00:18 <Ashkan> I understand `UndecidableInstances` generally should *not* be solution except in rare cases you know what you are doing, I most definitely do not qualify:D
16:00:34 <c_wraith> UndecidableInstances is fine
16:00:39 MangoIV[m] joins (~mangoivma@2001:470:69fc:105::2:8417)
16:00:44 <c_wraith> The problem is that the entire goal is wrong
16:00:47 × azimut quits (~azimut@gateway/tor-sasl/azimut) (Ping timeout: 255 seconds)
16:01:10 <c_wraith> You should not opt a type into being an instance of a class just because it's an instance of another class.
16:01:14 <Ashkan> Okay, help me understand. I wish to say : give C1 m , I can construct a C2 m
16:01:21 <c_wraith> Don't say that
16:01:36 <c_wraith> say "if you want a C2 m, you can create it trivially with this helper"
16:01:56 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 246 seconds)
16:02:28 <geekosaur> the typeclass machinery does not work in the case of "if I have X then I can Y, otherwise here's how you can Y"
16:02:30 <c_wraith> Being a member of a class should basically always be opt-in
16:02:52 <c_wraith> (I'll forgive Typeable because of how important it is that only the compiler can create instances)
16:03:19 <Ashkan> c_wraith but `C2` is a typeclass. I can't return an instance from a function : `C1 m => () -> C2 m`
16:03:47 <c_wraith> you can write code such that `instance C2 m` is a sufficient definition
16:04:04 <c_wraith> well. not quite. `instance C2 M`
16:04:06 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0)
16:04:46 <c_wraith> or take another route and go with `instance C2 M where f2 = defaultF2`
16:04:59 <int-e> Providing an instance for a newtype wrapper is also an option. Or default implementations if there's only one "superclass" like C1.
16:05:22 <Ashkan> I have a feeling my Scala background is confusing me ... okay in Scala I could trivially code the following fact : "if you prove to me C1 m then I can prove back C2 m` and then I can use that fact `C2` in the scope that follows.
16:05:23 <int-e> (This is attractive, I think, when the class has more than one method.)
16:05:53 <int-e> Do you need the type class at all?
16:05:59 <c_wraith> Ashkan: then why does C2 exist at all?
16:06:20 × segfaultfizzbuzz quits (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 260 seconds)
16:07:17 <Ashkan> Maybe if I provide the concrete use-case : `instance (CMonadIO m, R.MonadReader (TVar (M.Map Int s)) m => Host m GameId s`
16:07:47 <int-e> `class Yas m where f1 :: m ()` is not so different from `f1_M :: M ()` for each instance (which you can pass around as a parameter where functions are polymorphic in m), except you get a mostly-guarantee that there's only one f1_M for each type M.
16:08:23 <Ashkan> It is supposed to say : if `m` can provide a `TVar` of a map and if `m` and be lifted to `IO` then `m` can host games of type `s`, identified by `GameId` (which is a `newtype` over `Int`)
16:08:35 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0) (Ping timeout: 256 seconds)
16:09:09 <c_wraith> Ashkan: that really doesn't look like something that belongs in a class at all
16:11:05 <Ashkan> `Yasz and `Ash` where intentionally stripped down to get to the gist (`C1 m => C2 m` is erroring out). In my actual use case `C2` is the useful class (the `Host`) which provides quite a few non-trivial methods. I want to say if you give me some stuff on `m`, then I can make a game host out of it
16:11:52 <c_wraith> Do you already have multiple different implementations that you want to write code that works interchangeably between?
16:12:09 <Ashkan> c_wraith why not ? it is exactly like, say, `MonadReader`. I'm simply expressing the abstract nature of "Game hosting" in my app via a type class. No ?
16:14:04 <Ashkan> c_wraith that is an altogether different and orthogonal concern. But interestingly enough, actually Yes !
16:14:04 <Ashkan> I have an in-memory game host which does not provide persistency (you lose the state if you disconnect, no "save"ing)
16:14:05 <Ashkan> And another, totally different, game hosting that uses Postgres and can provide persistency
16:14:23 <Ashkan> A game-server could be spun with with either of the Host-ing types
16:14:37 <c_wraith> honestly, this sounds like you want a record of functions
16:16:00 <Ashkan> c_wraith I'm totally on-board to learn a better way of expressing my use-case +1 but that said, still don't understand what's *wrong* with the way I'm trying to do it right now (except that it is erroring out the way I code it:D  )
16:16:02 <c_wraith> You want varying behavior, but aren't interested in program-wide coherence
16:16:07 razetime joins (~Thunderbi@117.193.6.69)
16:17:26 <Ashkan> I want varying behaviour yes, which is exactly ad-hoc polymorphism, which is exactly why we have type-classes in Haskell <-- this is my understanding. Wrong ?
16:18:40 <Ashkan> That other part "program-wide coherence" I'm not sure I understand. I want "coherence" all over my program, sure, but I think you mean something more concrete, like a rule or something ?
16:18:48 <c_wraith> varying behavior is why we have first-class functions
16:21:07 polyphem_ joins (~rod@2a02:810d:840:8754:e5c4:fa80:2cc4:f0a8)
16:21:10 <Ashkan> Yeah that too but by that logic the whole tag-less final is wrong then. Why have different types that implement the same class in different way ? just pass functions
16:21:38 <c_wraith> tagless final is not a very good way to do things practically, no
16:21:48 <c_wraith> it has some real issues in the face of coherence
16:22:45 <c_wraith> though at least tagless final doesn't try to build hierarchies, it just adds new bits of functionality independently
16:24:16 <c_wraith> Ultimately the problem with you're trying to do is that you're trying to opt *all* types into some class.
16:24:19 tzh joins (~tzh@c-24-21-73-154.hsd1.wa.comcast.net)
16:25:01 <c_wraith> That's not what the type class system is for. It's for when each type has a *different* implementation
16:25:46 <c_wraith> If your entire class implementation is in terms of another class, just use that other class
16:26:42 <Ashkan> honestly I'm not knowledgeable enough to make an argument against/pro it all by myself. What I can see is that quite a lot of competent programmers in both Scala and Haskell community see no issue with it but some (equally qualified) do see me issues with it.
16:26:42 <Ashkan> But that is a bit off-topic. My problem I think is much simpler than that:
16:26:43 <Ashkan> What is wrong with trying to encode services of a component in an abstract way using a class ? maybe help me understand this first then I can the bigger picture ?
16:27:51 <c_wraith> Well, the problem GHC is complaining about is that you're trying to declare an implementation for all types. That's just a function, so why are you creating a class for it? You probably assume you can override it trivially for specific types, but that's not how type classes work. So that's why GHC rejects it by default.
16:29:19 <c_wraith> If you try to go down that path, GHC will be telling you to enable Overlapping or Incoherent instances soon
16:29:28 <c_wraith> And both of those can break a program badly if misapplied
16:30:00 <c_wraith> It's far simpler to just allow types to opt-in to classes instead of forcing a global instance
16:30:10 <Ashkan> so `C1 m => C2 m` is essentially wrong , no matter how `C1` and `C2` are complicated or it makes sense in the domain ?
16:30:16 <c_wraith> correct
16:30:34 <c_wraith> that's just not compatible with how type classes work
16:30:52 <Ashkan> I don't understand why :-?
16:31:48 <Ashkan> okay, help me understand this: How come `class C1 m => C2 m` is good but `instance C1 m => C2 m` is not ?
16:31:56 <c_wraith> `instance C1 m => C2 m` is saying "all types have an instance of C2 that requires an instance of C1"
16:32:11 <c_wraith> that's backwards from what you think it's saying
16:32:42 <c_wraith> It's saying "this instance exists for all types"
16:33:11 <c_wraith> classes, on the other hand, just are saying "If you make a type an instance of one, you also need to make it an instance of the other"
16:33:25 <c_wraith> One is opt-in.
16:33:32 <c_wraith> The other one just applies to everything
16:33:52 <hpc> maybe this can help clarify it, and why you might not want type classes here at all
16:34:02 <Ashkan> okay, bear with me here (thanks by the way for your patience), so `class C1 m =>  C2 m` is saying any `m` that is a `C2` must also be a `C1`, right ?
16:34:27 × Xe quits (~cadey@tailscale/xe) (Remote host closed the connection)
16:34:29 <c_wraith> Ashkan: yes, that's the meaning in the class definition
16:35:30 × wootehfoot quits (~wootehfoo@user/wootehfoot) (Ping timeout: 252 seconds)
16:35:35 <hpc> say you have class Game g where ..., data GameType = Memory | Pgsql | Mysql | File | ..., and newGame :: Game g => GameType -> g
16:35:52 <hpc> newGame has to be valid for every combination of GameType and g
16:36:09 <Ashkan> Alright, good. So you put this constraint `C1 m => ...` so later instances of `C2` can rely on the fact that `m` is `C1` and can use the methods provided by `C1`, right ?
16:36:17 <hpc> so if you have instance Game FileGame where ..., you need (newGame Pgsql :: FileGame) to make sense
16:36:27 <hpc> which doesn't really work
16:36:49 <hpc> an example in base where it's really tempting to use type classes is file handles
16:37:00 <c_wraith> Ashkan: if you put a constraint on a class definition, it allows you to use things from that constraint in instances of that class, yes
16:37:06 <hpc> they can be file-backed, they can be stdin/out/err, or network sockets, or who knows what
16:37:18 <hpc> but they all fall under Handle, with this implementation - https://hackage.haskell.org/package/base-4.18.0.0/docs/src/GHC.IO.Handle.Types.html#Handle
16:37:47 <hpc> because no matter what the implementation is, they're still all handles and you can genuinely treat them all exactly the same
16:37:53 <hpc> as opposed to say, numbers
16:37:56 <Ashkan> Now what is meant by `instance <some-constraint> => C2 m` ?
16:38:19 <hpc> where you're not mixing Word8 and Rational no matter how hard you try
16:38:31 <c_wraith> Ashkan: it means "for all types m, m is an instance of C2. The implementation assumes there is an instance of C1 for m as well, and it's a compile error if there isn't"
16:39:11 <Ashkan> (reading hpc s messages now:D  my brain can't follow both at the same time)
16:39:32 <hpc> (heh, feel free to save mine for later)
16:40:21 <hpc> (might as well get a better understanding of type classes even if you end up doing something completely different)
16:40:44 Xe joins (~cadey@tailscale/xe)
16:40:56 <Ashkan> c_wraith I have a feeling this "for all types `m`" is somehow key here but I can't see how this way you put it is any different than the way I think it is working
16:41:39 <c_wraith> Ashkan: you think it's saying "If there is an instance of C1 m, then there's an instance of C2 m". It's actually saying "there is an instance of C2 m"
16:41:51 Albina_Pavlovna joins (~Albina_Pa@2603-7000-1203-4d7c-846d-1927-68d6-5999.res6.spectrum.com)
16:42:24 dhil joins (~dhil@80.208.56.181.static.fibianet.dk)
16:42:35 <geekosaur> "there is an instance of C2 m. but it requires a C1 m; if it doesn't have one, it will fail"
16:42:48 <Ashkan> c_wraith Yes. I'm literally reading `a => b` as "a gives b"
16:42:54 <geekosaur> this leaves no room for an alternative C2 m instance
16:43:06 <c_wraith> Ashkan: yes, that's what's wrong. that's not what it's saying.
16:43:35 <c_wraith> Ashkan: It's saying "b, and also a is required"
16:44:04 <Ashkan> okay, so "C1 m => C2 m" means "all *m* should have an instance of C2 and this requires and instance of C1 to be there" ?
16:44:26 <c_wraith> no, it's saying "all m *do* have an instance of C2, and this is it. also, it requires C1"
16:44:28 <geekosaur> yes. with no alternative; the C1 has to exist
16:46:32 <Ashkan> okay I'm seeing the light : "C1 m => C2 m". The "C2 m" is in fact kinda independent of "C1 =>" in the sense that is does not define a dependency. The "C2 m" part is saying `m` is a `C2`, period ! (for all `m`) but the "C1 =>" part is *adding* a condition : that `C1 m` should also hold. correct ?
16:46:45 <c_wraith> yes
16:46:50 <c_wraith> that's exactly it
16:48:38 <Ashkan> very counter-intuitive syntax:D  okay. So how is this interfering with wha I'm trying to say here ?
16:48:38 <Ashkan> oh ! I see ... I'm forcing every possible `m` to somehow satisfy this impossible demand. right ?
16:48:53 <c_wraith> That's half of it, yes.
16:49:07 <c_wraith> The other half is that it's preventing adding any other instance of the class
16:49:24 <c_wraith> that's the coherence part
16:49:49 <Ashkan> Okay lets stay on this half that I seem to begin to understand. I understand now that this is not whatI want to say. Okay. But why is this a compiler error ?
16:50:44 <c_wraith> I mean... specifically it's a compile error because Haskell is very conservative with making sure instances don't loop the type checker
16:50:46 <Ashkan> Why Haskell need the `C1 m` to be *smaller* that `C2 m` ? what does it even mean *smaller* ? I assume it means wrapped in fewer type constructors ?
16:51:12 <c_wraith> Smaller in that there are fewer types that match
16:51:36 <c_wraith> Like, to look at a different example: instance (Show a, Show b) => Show (a, b)
16:51:50 <Ashkan> I understand why `C1 m => C2 m` is not what I want to say , I don't understand why it's an error both on the conceptual and technical level
16:51:53 <c_wraith> There are fewer types that match (a, b) than there are that match a or b
16:52:08 <c_wraith> so (a, b) is smaller than the constraint types
16:52:11 × Albina_Pavlovna quits (~Albina_Pa@2603-7000-1203-4d7c-846d-1927-68d6-5999.res6.spectrum.com) (Quit: ZZZzzz…)
16:52:58 <c_wraith> Anyway. Haskell is very conservative in its rules for what instances are allowed, by default.
16:53:17 <Ashkan> c_wraith(agina, most appreciate your patience) if you would be kind to help me understand why `C1 m => C2 m` is conceptually wrong for all C1,C2 and `m` s ?
16:53:30 <c_wraith> UndecidableInstances very specifically just to disable that check.
16:53:59 <c_wraith> *is* just to disable...
16:54:06 <int-e> it's not *wrong*, disobeying that rule can just make type-checking fail to terminate
16:54:57 <int-e> In this isolated case it won't. But it's easy to run into loops, and even easier when the constraint is *bigger* than the right-hand side.
16:56:09 <Ashkan> > There are fewer types that match (a, b) than there are that match a or b
16:56:10 <Ashkan> I have the exact opposite intuition. It's the polymorphic type `(a,b)` a bigger type than any `a` and `b` ? I do *not* mean it has more values, I understand we are not on term level, I mean say you have three basic types so `a = { Int, String, some-other-type }` and same with `b`. No ?
16:56:10 <lambdabot> error:
16:56:11 <lambdabot> Data constructor not in scope:
16:56:11 <lambdabot> There
16:56:30 <c_wraith> Yeah.. Getting the compile error is really not a problem. Haskell by the specification is quite conservative around this. Allowing GHC to be more liberal isn't an intrinsic problem.
16:56:51 <c_wraith> The bigger problem is that you're really not actually communicating what you mean
16:57:44 <geekosaur> (a,b) is the cartesian product of all types with all types. it's a very large instance head
16:58:08 <geekosaur> Show a and Show b both limit this
16:58:47 <int-e> Ashkan: it's a syntactic criterion... both a and b are syntactically smaller than the type (a,b).
16:59:51 <Ashkan> int-e because `a` and `b` are not wrapped but `(a,b)` (although `*`) but has a `(,)` in it ?
16:59:58 <int-e> The syntax is relevant because the type checker operates on these types symbolically.
17:00:34 <Ashkan> so e.g. `Int` and `String` is smaller than `Map Int String` ?
17:01:05 <int-e> a is a proper sub-(type-expression) of (a,b)
17:01:32 <Ashkan> "sub-(type-expression)" is that a thing:D  ?
17:01:33 <Jade[m]1> Ashkan: depends on your notion of 'smaller'
17:01:45 <Ashkan> or you just made it up to ease the conversation ?
17:02:45 <Ashkan> Jade[m]1 I mean regarding my error `instance C1 m => C2 m` (error : constraint is no  smaller than instance head)
17:05:10 <int-e> Ashkan: I say type-expression to stress the fact that this is syntactic; an expression describing a type. And the sub- part applies to the expression. The English language doesn't concisely disambiguate that from an expression describing a sub-type... so I ended up with those parentheses.
17:05:24 Albina_Pavlovna joins (~Albina_Pa@2603-7000-1203-4d7c-846d-1927-68d6-5999.res6.spectrum.com)
17:05:49 <int-e> Ashkan: but honestly, understanding the precise definition of when an instance head is smaller than the instance is probably not worth your time.
17:06:26 <Ashkan> @int-e I'm trying to understand the error both on technical and conceptual level
17:06:26 <lambdabot> Unknown command, try @list
17:06:42 <Ashkan> I was hoping the technical level would be more precise and easier to graps
17:07:40 <Ashkan> Okay I understand what smaller means here. But why does GHC need the `C1 m` to be smaller than `C2 m` ?
17:08:00 <int-e> Pragmatically... it's okay to leave it at this: It's a crude termination criterion for type checking (crude because it triggers in many cases where type checking will still terminate; "conservative" if you want to be PC); you can override it with UndecidableInstances when it comes up.
17:09:07 <Ashkan> okay,  then what is *conceptually* wrong with `instance C1 m => C2 m` ?
17:09:15 <int-e> Nothing.
17:09:48 <int-e> Well. Except that this indicates that C2 is useless, but that has nothing to do with the error.
17:10:05 × califax quits (~califax@user/califx) (Ping timeout: 255 seconds)
17:10:14 <Ashkan> > C2 is useless
17:10:15 <Ashkan> help me understand why
17:10:16 <lambdabot> error:
17:10:16 <lambdabot> • Data constructor not in scope: C2 :: t0 -> t1 -> t
17:10:16 <lambdabot> • Perhaps you meant variable ‘_2’ (imported from Control.Lens)error:
17:10:33 <int-e> There's no other instance C2 can have without causing an overlap.
17:10:40 <int-e> So why don't you just use C1 instead?
17:11:25 <Ashkan> > There's no other instance C2 can have without causing an overlap.
17:11:25 <Ashkan> this is exactly what I don't get
17:11:26 <lambdabot> <hint>:1:18: error: parse error on input ‘instance’
17:11:28 califax joins (~califax@user/califx)
17:11:33 <int-e> (yes, you can allow overlapping instances... but that's a road to *actually* scary territory.)
17:12:00 <Ashkan> (O'm not gonna, specially when an actual Haskeller is telling me not to)
17:12:01 <int-e> Ashkan: when selecting an instance, the context doesn't matter, it just looks at the `instance C2 m` part.
17:12:26 acidjnk_new joins (~acidjnk@p200300d6e715c442a472905c59e58702.dip0.t-ipconnect.de)
17:12:49 <int-e> and 'm' will match *any* type (of kind * -> * in your case) at all.
17:13:08 × Xe quits (~cadey@tailscale/xe) (Remote host closed the connection)
17:14:14 <Ashkan> Oh I see ... I'm effectively saying "*all* `m` should be an instance of `C1` *and* `C2`" and then define what "instance of C2" means solely in terms of being an instance of `C1` which is (not an error yet) but redundant ?
17:14:53 hammdist parts (~hammdist@67.169.114.135) ()
17:15:34 <Ashkan> So better way is to define whatever `C2` class is providing as simple bundle of functions with a `C1 m =>` requirements
17:16:06 <int-e> You're saying that any type that is an instance of C1 is also an instance of C2. But after defining that instance you also can't (without overlapping instances, some people think those are fine) have a type that's an instance of C2 but not of C1.
17:16:45 <int-e> So ignoring that escape hatch (as I prefer to do), C1 and C2 have the same instances, so they should be the same class.
17:17:52 <int-e> That doesn't mean that the functions that C2 provides have to be members of C1; they can be functions of type C1 m => ... instead.
17:18:10 azimut joins (~azimut@gateway/tor-sasl/azimut)
17:18:14 <int-e> As you said.
17:19:27 <Ashkan> Okay I think I'm getting this part. `C1 m => C2 m` leaves no way for an `m` to not be a `C1`. So all `m` is now both `C1` and `C2` which essentially means `C2` is not doing much. This has none or very little to do with the GHC error.
17:19:49 × razetime quits (~Thunderbi@117.193.6.69) (Remote host closed the connection)
17:20:23 <int-e> Yeah. "overlapping instances" is the keyword. And you'll find the Haskell community divided on whether those are benign or harmful.
17:21:22 <int-e> The unambiguously scary territory are "incoherent instances".
17:21:39 <geekosaur> the actual error here was "no smaller than the instance head" though
17:22:18 <int-e> Yes. Which, as agreed, has nothing to do with overlapping instances.
17:22:27 <Ashkan> Okay. I got this part (thanks you) and the warning (overlapping instances).
17:22:27 <Ashkan> How do I express what I want to say ?
17:22:28 <Ashkan> "if `C1 m`, then `C2 m`"
17:23:02 <geekosaur> typeclasses are not the tool for that; they don't support it
17:23:16 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
17:23:49 <geekosaur> (there's an evil "ifcxt" package that lets you do some of it, but it's a complicated way of just passing a record of functions instead)
17:24:47 <Ashkan> in Scala I could say `implicit fromC1[M: C1]: C2[M]` which reads : give me the instance for `C1 M` and I can give back the instance for `C2 M` (which is opt-in by definition)
17:24:54 <int-e> the common workaround is to have a newtype wrapper, newtype WrappedC1 m a = WrapC1 { unwrapC1 :: m a }, and then you can have an instance C1 m => C2 (WrappedC1 m) without causing excessive overlap
17:25:58 <int-e> And as an extension to GHC (DerivingVia?) there's a mechanism for deriving an instance of C2 via that newtype.
17:26:13 <int-e> s/to GHC/in GHC/
17:26:39 × dcoutts_ quits (~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net) (Ping timeout: 255 seconds)
17:27:09 Xe joins (~cadey@tailscale/xe)
17:27:36 <int-e> > (Sum 23 <> Sum 42, Product 23 <> Product 42) -- using instances Num a => Monoid (Sum a) and Num a => Monoid (Product a)
17:27:37 <lambdabot> (Sum {getSum = 65},Product {getProduct = 966})
17:29:21 <int-e> "if `C1 m`, then `C2 m`" -- there's `class C2 m => C1 m where ...` of course, but that probably won't satisfy you.
17:29:27 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 255 seconds)
17:30:04 <Ashkan> hmmm ... so in principle Haskell does not support  "if `C1 m` then `C2 m`". How should I approach problems of this kind then ? problem being :
17:30:05 <Ashkan> I have a `C2 m (m :: * -> *)` which abstracts over some behaviour (just like `MonadReader` or any monad honestly) and there is more : if you help me a little bit by `C1 m =>` then I can build an instance of `C2 m` for you
17:30:10 <int-e> (because it's an *obligation* to provide a C2 instance whenever you make a C1 instance)
17:31:15 <Ashkan> int-e the `class C1 m => C2 m` is saying something different (I just learned that a few messages above). I don't want to tie `C2` and `C1` like this.
17:32:34 <int-e> Ashkan: As I said, it won't satisfy you. It does express the implication you want though (note that you didn't copy what I wrote; I had C1 and C2 swapped)
17:33:52 × CiaoSen quits (~Jura@p200300c9570e91002a3a4dfffe84dbd5.dip0.t-ipconnect.de) (Ping timeout: 248 seconds)
17:34:18 <Ashkan> int-e the "*class* C1 m => C2 m" I understand you and is not what I want. The "*instance* wrap-black-magic" I also understand (kind) and I see as a hint that I'm doing something wrong:D
17:35:35 <Ashkan> lets make it concrete. I want to say: give me `MonadIO m` and I can give back a `C2 m`. `C2` is no way related or constrained by `MonadIO`.
17:36:19 <int-e> The wrapping... it's not really black magic... I mean, if you know what a newtype is, it shouldn't be hard to wrap your head around it (pun fully intended).
17:37:10 <int-e> Ashkan: well I still think that C2 probably shouldn't exist in that scenario.
17:38:09 <Ashkan> int-e I know what a `newtype` is in the practical sense (I'm actively using it in my small project). I'm not sure wrapping things in `newtype` just so I can say it the `instance ...` way is the way to go
17:38:31 <Ashkan> I have a feeling there should be a more idiomatic way to achieve what I want to say. maybe not ...
17:40:18 <Jade[m]1> Ashkan: A lot of things are just that
17:40:23 × mechap quits (~mechap@user/mechap) (Ping timeout: 256 seconds)
17:41:51 <Ashkan> int-e > well I still think that C2 probably shouldn't exist in that scenario.
17:41:51 <Ashkan> Care to elaborate why ? perhaps offer and alternative ? this way I can learn something deeper perhaps
17:41:59 mechap joins (~mechap@user/mechap)
17:42:00 × Guest7532 quits (~talismani@2601:200:c000:f7a0::5321) (Ping timeout: 260 seconds)
17:42:00 × sammelweis quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Quit: No Ping reply in 180 seconds.)
17:43:10 <geekosaur> what does C2 offer over C1?
17:43:19 sammelweis joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
17:47:08 <Ashkan> geekosaur Actually that's exactly what it seems I can't properly communicate to you guys. You all seem to suggest `C2` is somewhat redundant. This is not the case. `C2` is something very specific to the domain of my project https://paste.tomsmeding.com/oQ1epvWG
17:48:12 <Ashkan> there is a concept in my project, a `Host m k s` which can *host* a bunch of `s`s identified by `k`s
17:49:52 <geekosaur> I suspected that (and am not sure why int-e didn't, tbh)
17:50:30 <geekosaur> but to me this feels like OOP think, which typeclasses aren't
17:51:08 <Ashkan> its just that being a `Host` has abs. no requirements of any kind. Any `m` can host `s`s by `k`s as long as it can provide the instance.
17:51:09 <Ashkan> Now that said, if some `m` meets certain requirements , then it can be made a host.
17:51:30 <int-e> geekosaur: I may have had my suspicions, but I reduced them to "probably".
17:51:35 CiaoSen joins (~Jura@p200300c9570e91002a3a4dfffe84dbd5.dip0.t-ipconnect.de)
17:51:54 <int-e> ste.tomsmeding.com/oQ1epvWG
17:51:58 <int-e> grr
17:52:24 <Ashkan> E.g  if  from `(CMonadIO m, R.MonadReader (TVar (M.Map Int s))`  a `Host m GameId` could be constructed. How do I express that in Haskell ?
17:53:24 cheater_ joins (~Username@user/cheater)
17:53:57 <Ashkan>  -- Or -- how do I model the this fact (a type `m` can host, given certain conditions) in a Haskell-approved way, if not via type-classes ?
17:54:20 <int-e> I wonder how many of those troubles go away with `data Host m k s = Host { create :: s -> m k, read :: k -> m s, ... }`
17:54:22 <geekosaur> in general you don't, becaquse the typechecker is not allowed to assume that anything with that shape is necessarily a Host. which is why you need to opt-in rather than opt-out
17:54:51 <int-e> and possibly two type families to express the m -> k s relation if that's somehow crucial.
17:55:11 <geekosaur> this again feels very OOPish to me; a Host in particular seems like it's a `data` not a `class`
17:55:20 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
17:55:37 <int-e> sure, there is that
17:55:44 × cheater quits (~Username@user/cheater) (Ping timeout: 248 seconds)
17:55:51 cheater_ is now known as cheater
17:57:17 <int-e> But if the goal *is* to mimic OO... to encapsulate behaviors... I think the record approach will cause less friction overall. Is it the right design? I don't know, it may be, though in many cases it won't be :-P
17:57:36 <Ashkan> int-e this is the "record" way people are suggesting, right ? a record of functions ...
17:57:55 <int-e> I don't know, I didn't see that part of the discussion.
17:58:05 <int-e> (It's likely though.)
18:00:04 <Ashkan> > this again feels very OOPish to me; a Host in particular seems like it's a `data` not a `class`
18:00:04 <Ashkan> This is *exactly* what I can't seem to understand. Perhaps I'm not thinking the Haskell way ... to me this is text-book case of ad-hoc polymorphism and type-classes. That Haskell can't express this cleanly is a different topic. I'm trying to find the blind spot in my thinking ...
18:00:06 <lambdabot> <hint>:1:35: error: parse error on input ‘;’
18:00:38 × dsrt^ quits (~dsrt@c-24-30-76-89.hsd1.ga.comcast.net) (Remote host closed the connection)
18:00:47 × whatsupdoc quits (uid509081@id-509081.hampstead.irccloud.com) (Quit: Connection closed for inactivity)
18:02:10 <Ashkan> The goal is to learn proper Haskell with the prospect of landing a job after years of Scala:D
18:04:22 <Jade[m]1> Ashkan: What instances do you plan to write for host?
18:04:32 <Jade[m]1> What other types are hosts?
18:04:40 shriekingnoise joins (~shrieking@186.137.175.87)
18:05:05 <Ashkan> Alright let me take a different perspective, indulge me here:
18:05:06 <Ashkan> 1) I am hell-bound to express this the tagless-final way. I have a concept, a set of behaviours I call `Host`ing. Any `m` can host give it can implement the methods.
18:05:06 <Ashkan> 2) As a helper lib (or whatever), if `m` satisfies some constraints then it can host and the lib implements the instance.
18:05:07 <Ashkan> How do I archive this in Haskell without type classes ? possible ?
18:05:41 <monochrom> Tagless-final uses a type class.
18:05:59 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0)
18:06:04 × vglfr quits (~vglfr@145.224.100.65) (Remote host closed the connection)
18:06:53 × CiaoSen quits (~Jura@p200300c9570e91002a3a4dfffe84dbd5.dip0.t-ipconnect.de) (Ping timeout: 246 seconds)
18:07:14 × califax quits (~califax@user/califx) (Ping timeout: 255 seconds)
18:07:30 <monochrom> It is also living somewhere in between OO and FP (in particular it looks like OO if you don't look carefully), which is more commonly known as "programming to an interface".
18:07:56 <Jade[m]1> Ashkan: That is what typeclasses are for indeed
18:08:02 <Jade[m]1> but maybe you need to seperate the typeclass from the actual data
18:08:08 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 255 seconds)
18:08:20 califax joins (~califax@user/califx)
18:08:35 <Jade[m]1> because in oop you have these things coupled together, which you don't in fp
18:08:47 <Ashkan> Jade[m]1 I will answer but first here me this:
18:08:48 <Ashkan> The *whole* point of `Host` as a type class is inversion of control, the DI. I don't care how or how. I'm just expressing the what it means to be host. Its up to users of this to implement the hosting behaviour in their `m`s
18:08:48 <Ashkan> Now the answer : there are 3: one that can host by encapsulating a `TVar` of a `Map` of proper types. Another one is a Yesod `Handler` who can host if it can provide some other stuff and a instance that can host given a database connection
18:09:00 <int-e> "tagless-final" should definitely have been mentioned way earlier in this discussion
18:09:02 × ec quits (~ec@gateway/tor-sasl/ec) (Ping timeout: 255 seconds)
18:10:39 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0) (Ping timeout: 248 seconds)
18:10:57 ec joins (~ec@gateway/tor-sasl/ec)
18:11:08 <Ashkan> int-e it indeed was, but the kind soul who was helping me at the time suddenly brought up something that could not defend or condemn. The kind that divides people over things:D
18:11:13 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
18:11:30 vglfr joins (~vglfr@145.224.100.65)
18:11:34 × vglfr quits (~vglfr@145.224.100.65) (Remote host closed the connection)
18:12:02 vglfr joins (~vglfr@145.224.100.65)
18:12:14 × vglfr quits (~vglfr@145.224.100.65) (Remote host closed the connection)
18:14:31 <Ashkan> Jade[m]1 essentially *any* `m` can host provided they implement the interface (instance the type class, this is not OOP, there is an exact 1-1 relation between the OOP ways and Haskell ways here):
18:14:31 <Ashkan> 1- given a `TVar` of proper type, it can be wrapped around and turned into a datatype that can host (I have coded this already)
18:14:32 <Ashkan> 2- exactly as above, if a Yesod handler can produce a proper `TVar` it can host (I have coded this already)
18:14:32 <Ashkan> 3-given a database connection ,wrapping it in a proper `m` and creating a `newtype` , this can also host
18:14:36 <int-e> Anyway, if the class has to stay I'd wrap up the various ways to instantiate them in their own newtypes (or datatypes), eliminating the overlap between those instances.
18:14:40 × jinsl- quits (~jinsl@2408:8207:2556:f740:211:32ff:fec8:6aea) (Ping timeout: 260 seconds)
18:17:05 <Ashkan> I do understand there might be other ways to achieve the same *outcome* (to abstract away the varying part) but I don't see what's wrong with my approach. Or why it feels so OOP-ish to you guys. I'm emphasising in order to learn proper Haskell, not that I disagree with you guys or anything. More like : help me understand why I'm wrong
18:18:46 <monochrom> Because even tagless-final is not always necessary.
18:18:56 × califax quits (~califax@user/califx) (Ping timeout: 255 seconds)
18:19:18 <Ashkan> int-e
18:19:18 <Ashkan> > Anyway, if the class has to stay I'd wrap up the various ways to instantiate them in their own newtypes (or datatypes), eliminating the overlap between those instances.
18:19:19 <Ashkan> I think this is key here. I am trying to wrap it new types but as you can see the `Host` has 3 type params `m :: *->*, s and k` which makes me not sure which one is the trouble here. It should be `m` but `newtye`ing it did not help with the error.
18:19:20 <lambdabot> <hint>:1:7: error: parse error on input ‘,’
18:19:48 jinsl joins (~jinsl@123.120.166.36)
18:20:27 × polyphem_ quits (~rod@2a02:810d:840:8754:e5c4:fa80:2cc4:f0a8) (Ping timeout: 248 seconds)
18:20:33 califax joins (~califax@user/califx)
18:21:22 polyphem_ joins (~rod@2a02:810d:840:8754:224e:f6ff:fe5e:bc17)
18:21:24 <Ashkan> this is the whole thing https://paste.tomsmeding.com/LmaKlJyQ
18:21:39 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 255 seconds)
18:22:35 × mechap quits (~mechap@user/mechap) (Ping timeout: 260 seconds)
18:23:25 <Ashkan> fixed some error https://paste.tomsmeding.com/SBJZfPF0
18:23:50 wroathe joins (~wroathe@207-153-38-140.fttp.usinternet.com)
18:23:50 × wroathe quits (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
18:23:50 wroathe joins (~wroathe@user/wroathe)
18:24:22 mechap joins (~mechap@user/mechap)
18:25:36 vglfr joins (~vglfr@145.224.100.65)
18:26:09 econo joins (uid147250@user/econo)
18:27:10 × Ashkan quits (~Ashkan@a119011.upc-a.chello.nl) (Quit: Client closed)
18:30:02 × mechap quits (~mechap@user/mechap) (Ping timeout: 268 seconds)
18:31:39 krei-se joins (~quassel@p5087440b.dip0.t-ipconnect.de)
18:31:41 mechap joins (~mechap@user/mechap)
18:38:30 Ashkan joins (~Ashkan@a119011.upc-a.chello.nl)
18:40:10 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
18:42:23 enoq joins (~enoq@2a05:1141:1f5:5600:b9c9:721a:599:bfe7)
18:42:31 dcoutts_ joins (~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net)
18:43:02 × Ashkan quits (~Ashkan@a119011.upc-a.chello.nl) (Client Quit)
18:44:00 × abrar quits (~abrar@static-108-2-152-54.phlapa.fios.verizon.net) (Ping timeout: 265 seconds)
18:45:00 segfaultfizzbuzz joins (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
18:49:33 × machinedgod quits (~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 255 seconds)
18:53:06 Sciencentistguy9 joins (~sciencent@hacksoc/ordinary-member)
18:53:25 berberman_ joins (~berberman@user/berberman)
18:54:03 × berberman quits (~berberman@user/berberman) (Ping timeout: 248 seconds)
18:55:59 × Sciencentistguy quits (~sciencent@hacksoc/ordinary-member) (Ping timeout: 264 seconds)
18:56:00 Sciencentistguy9 is now known as Sciencentistguy
18:56:03 aweinstock joins (~aweinstoc@cpe-74-76-189-75.nycap.res.rr.com)
18:57:48 zer0bitz joins (~zer0bitz@2001:2003:f443:d600:11d4:814d:b4b3:885c)
18:59:28 × segfaultfizzbuzz quits (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 252 seconds)
19:00:34 × dcoutts_ quits (~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net) (Ping timeout: 252 seconds)
19:05:56 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0)
19:12:20 × mncheck quits (~mncheck@193.224.205.254) (Ping timeout: 246 seconds)
19:13:36 × jinsl quits (~jinsl@123.120.166.36) (Ping timeout: 248 seconds)
19:13:46 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 252 seconds)
19:14:22 jinsl joins (~jinsl@123.120.184.53)
19:17:55 harveypwca joins (~harveypwc@2601:246:c180:a570:3828:d8:e523:3f67)
19:19:27 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 248 seconds)
19:25:14 sagax joins (~sagax_nb@user/sagax)
19:27:20 × califax quits (~califax@user/califx) (Ping timeout: 255 seconds)
19:28:01 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
19:30:05 califax joins (~califax@user/califx)
19:30:23 × jinsun quits (~jinsun@user/jinsun) (Read error: Connection reset by peer)
19:32:12 × dhil quits (~dhil@80.208.56.181.static.fibianet.dk) (Read error: Connection reset by peer)
19:32:56 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 268 seconds)
19:34:01 mixfix41 joins (~sdenynine@user/mixfix41)
19:37:05 lxi joins (~quassel@2a02:2f08:4d1c:400:fee5:4f99:b3f4:888d)
19:39:15 segfaultfizzbuzz joins (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
19:41:42 waleee joins (~waleee@2001:9b0:21c:4000:5bf9:6515:c030:57b7)
19:43:48 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
19:47:24 wroathe joins (~wroathe@50.205.197.50)
19:47:24 × wroathe quits (~wroathe@50.205.197.50) (Changing host)
19:47:24 wroathe joins (~wroathe@user/wroathe)
19:48:30 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 255 seconds)
19:50:03 pavonia joins (~user@user/siracusa)
19:53:35 × segfaultfizzbuzz quits (~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 260 seconds)
19:55:11 × krei-se quits (~quassel@p5087440b.dip0.t-ipconnect.de) (Quit: https://quassel-irc.org - Chat comfortably. Anywhere.)
20:01:24 Ashkan joins (~Ashkan@a119011.upc-a.chello.nl)
20:03:50 × Albina_Pavlovna quits (~Albina_Pa@2603-7000-1203-4d7c-846d-1927-68d6-5999.res6.spectrum.com) (Quit: ZZZzzz…)
20:09:33 × Ashkan quits (~Ashkan@a119011.upc-a.chello.nl) (Quit: Client closed)
20:13:25 × takuan quits (~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection)
20:17:11 <juri_> is there a no-op for Spec?
20:19:41 <mauke> pure ()?
20:21:29 <Hecate> probably pure () yeah
20:25:07 jmdaemon joins (~jmdaemon@user/jmdaemon)
20:27:59 krei-se joins (~krei-se@p5087440b.dip0.t-ipconnect.de)
20:32:21 <juri_> thanks.
20:32:46 × biberu quits (~biberu@user/biberu) (Read error: Connection reset by peer)
20:36:33 biberu joins (~biberu@user/biberu)
20:38:19 ix joins (~ix@213.205.241.31)
20:41:20 Sgeo joins (~Sgeo@user/sgeo)
20:43:04 machinedgod joins (~machinedg@d198-53-218-113.abhsia.telus.net)
20:48:00 × gnalzo quits (~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Ping timeout: 248 seconds)
20:50:10 gnalzo joins (~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
20:50:34 cheater_ joins (~Username@user/cheater)
20:52:01 mauke_ joins (~mauke@user/mauke)
20:53:20 × cheater quits (~Username@user/cheater) (Ping timeout: 248 seconds)
20:53:20 × mauke quits (~mauke@user/mauke) (Ping timeout: 248 seconds)
20:53:20 mauke_ is now known as mauke
20:53:21 cheater_ is now known as cheater
20:55:39 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
21:00:19 dcoutts_ joins (~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net)
21:01:41 × harveypwca quits (~harveypwc@2601:246:c180:a570:3828:d8:e523:3f67) (Quit: Leaving)
21:01:53 Guest|26 joins (~Guest|26@aftr-62-216-209-1.dynamic.mnet-online.de)
21:02:00 × Guest|26 quits (~Guest|26@aftr-62-216-209-1.dynamic.mnet-online.de) (Client Quit)
21:02:17 × gmg quits (~user@user/gehmehgeh) (Ping timeout: 255 seconds)
21:02:50 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0) (Remote host closed the connection)
21:03:30 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0)
21:03:38 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Ping timeout: 255 seconds)
21:04:37 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
21:04:57 gmg joins (~user@user/gehmehgeh)
21:16:25 Ashkan joins (~Ashkan@a119011.upc-a.chello.nl)
21:18:52 × Ashkan quits (~Ashkan@a119011.upc-a.chello.nl) (Client Quit)
21:26:29 <Inst> question about a claim an acquaintance / friend made
21:26:34 <Inst> how bad are fizzled sparks?
21:27:00 <Inst> I did a refactor that improved program performance by about 10%, but changed my spark conversion rate from 80% to 50-60%
21:27:03 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 255 seconds)
21:27:10 <Inst> wondering if it's possible to reclaim all the fizzled sparks
21:28:35 × bontaq quits (~user@ool-45779fe5.dyn.optonline.net) (Remote host closed the connection)
21:28:52 Guest38 joins (~Guest38@pool-96-245-193-224.phlapa.fios.verizon.net)
21:29:54 ubert joins (~Thunderbi@p200300ecdf2947664c2eb563067a71e8.dip0.t-ipconnect.de)
21:32:05 × anpad quits (~pandeyan@user/anpad) (Quit: ZNC 1.8.2 - https://znc.in)
21:34:18 <monochrom> This is why you take empirical measurements to see how much benefit/cost you get, as opposed to talking about it philosophically.
21:34:53 anpad joins (~pandeyan@user/anpad)
21:35:18 <monochrom> At least until you develop a model that is time-proven to accurately predict empirical measurements.
21:35:29 <Inst> someone else claimed here that they were expecting 100% conversion rates
21:36:05 <monochrom> IOW the scientific method, as opposed to the internet-crowd-talk method.
21:36:08 <Inst> if it's possible to prevent the sparks from getting GCed or fizzled
21:36:23 × Guest38 quits (~Guest38@pool-96-245-193-224.phlapa.fios.verizon.net) (Quit: Client closed)
21:36:25 <Inst> would see a nice 70-100% performance improvement
21:41:50 × ix quits (~ix@213.205.241.31) (Read error: Connection reset by peer)
21:46:26 Ashkan joins (~Ashkan@a119011.upc-a.chello.nl)
21:46:50 <Ashkan> I put it up on SO if anyone is interested https://stackoverflow.com/questions/75638862/how-do-i-conditionally-declare-an-instance
21:47:31 ix joins (~ix@213.205.241.31)
21:48:09 <monochrom> You will have no luck "translating" Scala "classes" to Haskell classes. They are not even related.
21:48:46 <hpc> it's sheer unfortunate coincidence that they use the same word
21:48:52 <hpc> like how "gift" means "poison" in german
21:49:01 <monochrom> At most you may have some luck translating Scala/Java interfaces/traits to Haskell classes, but even that requires rethinking and rewriting.
21:49:49 <Ashkan> Guys please, I know that:D  what did I do to suggest I'm confusing OOP class with Haskell type classes:)
21:50:27 <darkling> Mentioning Scala in the question. :)
21:50:33 × gnalzo quits (~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 3.8)
21:50:45 <[exa]> Ashkan: I guess a bit of extensions might help to at least solve that error (FlexibleInstances?)
21:50:45 <monochrom> A productive comparison (pun intended, just you wait) is between Java's Comparable<T> interface with Haskell's Ord class. It's a really good example showing you how they solve the same problem but they have to shoehorn it differently in different languages.
21:51:35 wootehfoot joins (~wootehfoo@user/wootehfoot)
21:51:36 cheater_ joins (~Username@user/cheater)
21:52:03 <monochrom> I didn't even saying anything about OOP. Look at my wording again. Only Scala and Haskell.
21:52:22 <monochrom> So I am not even assuming that you would use Scala for OOP.
21:53:03 × cheater quits (~Username@user/cheater) (Ping timeout: 255 seconds)
21:53:12 cheater_ is now known as cheater
21:53:35 × azimut quits (~azimut@gateway/tor-sasl/azimut) (Ping timeout: 255 seconds)
21:54:28 <monochrom> The question you posted is blessed in that it specifically says here is a Scala example how to do it in Haskell. So we can focus unambiguously on Scala and Haskell, and forget more undefined notions such as "OO" and "FP" that we don't need (probably never needed).
21:54:53 × ix quits (~ix@213.205.241.31) (Read error: Connection reset by peer)
21:55:55 <monochrom> At any rate "given A m then instance B m" is probably just never done in Haskell.
21:56:29 merijn joins (~merijn@86-86-29-250.fixed.kpn.net)
21:57:29 <Ashkan> Yeah, Scala line was there exactly to keep it focused on the desired effect which is to achieve something akin to "conditional" instance declaration. Actually I kinda understand that is not possible in Haskell so perhaps the better question is : how do I achieve the same effect ?
21:57:29 <monochrom> For example you can take hint from the practice in the standard library that it has an explicit "instance Ord Int" and also an "instance Eq Int", as opposed to a "general" "instance Ord a => Eq a" even though it would look "intuitive".
21:58:11 <monochrom> The long story is that if you really know the rules about instance declarations then "instance X a => Y a" does not mean what you want.
21:59:28 <Ashkan> Good point about the std lib
21:59:29 <Ashkan> Actually I understand the "long story" very well by now. What I don't know yet is how to achieve the desired effect.
21:59:51 <Inst> curious, I've been sort of interested in the scripting possibilities of Haskell
21:59:51 <Ashkan> I can only think that type classes (and instances) are not the way to go about this then ...
22:00:00 × ubert quits (~Thunderbi@p200300ecdf2947664c2eb563067a71e8.dip0.t-ipconnect.de) (Ping timeout: 248 seconds)
22:00:07 <monochrom> OK, now look at "class Eq a => Ord a".
22:00:13 <Inst> oh, busy, I'll pull off
22:00:18 ubert joins (~Thunderbi@p548c9fde.dip0.t-ipconnect.de)
22:01:10 <Ashkan> "class A a => B a" also expresses a different thing than what I mean. It says "B a" implies (requires) "A a" which is *not* the case with my situation
22:01:14 <monochrom> And try to make your own type X and write your "instance Ord X" and deliberately forget to write an "instance Eq X".
22:01:33 × merijn quits (~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 268 seconds)
22:01:56 <monochrom> Oh that's easy, if "class A => B" is the wrong direction, then change it to "class B => A".
22:02:10 <[exa]> Ashkan: I guess you read that one wrong, the usual reading is "if A a, then we can also have B a where these conditions apply ... (instance body)"
22:02:15 <monochrom> One of them ought to be the right direction, no? There are only two things to try.
22:03:00 <Ashkan> "A" and "B" sare totally 100% unrelated at the class level in my case. At the instance level (implementation) I want to say : give me an "A m" and I can give back a "B m"
22:03:11 <monochrom> Imagine you're at an oral exam and the examiner poses a yes/no question and says "you have two chances". Can you even lose?
22:03:21 ix joins (~ix@213.205.241.31)
22:03:22 <Ashkan> B doesn't even know about A (nor should it) at the class level
22:03:59 <monochrom> If they are so unrelated then why "an instance of B could be made only for those m s that are instances of A" is even a thing?
22:04:08 Cale joins (~cale@cpe80d04ade0a03-cm80d04ade0a01.cpe.net.cable.rogers.com)
22:04:49 <monochrom> Look at "class Eq a => Ord a". It says exactly "instances of Ord can be made only for instances of Eq".
22:04:55 <Ashkan> Actually you are right, very bad wording on my part. Better wording:
22:04:56 <Ashkan> *one* way to construct a `B m` is to provide an `A m`
22:04:58 azimut joins (~azimut@gateway/tor-sasl/azimut)
22:05:01 <monochrom> And it is precisely because they are closedly related.
22:05:01 <Ashkan> only one way, not the only way.
22:05:09 <[exa]> Ashkan: true
22:05:09 <monochrom> So make up your mind, are they related or not?
22:05:17 jargon joins (~jargon@184.101.86.70)
22:06:30 <monochrom> OK "if I have an instance of B, then I know how to make an instance of A" is usually expressed by a newtype wrapper.
22:06:37 <[exa]> Ashkan: just a very quick extra guess, aren't you trying to ensure something like `not(A a) => not (B a)` ?
22:06:52 <Ashkan> My mind is made up, very clear and problem statement very precise. However the typeclass machinery is not the answer.
22:07:03 std_mutex[m] joins (~stdmutexm@2001:470:69fc:105::1:4534)
22:07:06 <monochrom> A standard library example is the Product newtype wrapper that says "if you have Num, then we know one way to make Monoid".
22:07:45 <[exa]> Ashkan: technically the typeclass machinery is a complete programming language, so it would be pretty weird that it wouldn't do (perhaps impractical tho)
22:07:47 <monochrom> In particular it doesn't go "instance Num a => Monoid a".
22:08:01 <monochrom> Instead it goes "instance Num a => Monoid (Product a)"
22:08:51 <monochrom> And beautifully we also have a second way! "instance Num a => Monoid (Sum a)" for another newtype wrapper Sum. And it behaves differently too!
22:09:00 <Ashkan> Yeah the only way is the newtype wrapper but I explicitly don't want to go that way. Reason is in actuality I have a multi param type class and I ended up with a very boated piece of ugly code just to make it pass the paterson-small check (the error is explained here
22:09:00 <Ashkan> https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/instances.html#instance-termination-rules)
22:09:55 <Ashkan> [exa] no . but monochrom was right, my wording of my question was very misleading. Fixed now.
22:10:07 <[exa]> Ashkan: btw c'mon, there's no shame in UndecidableInstances :]
22:10:47 <monochrom> UndecidableInstances still doesn't make "instance X a => Y a" compile.
22:10:57 <monochrom> or usable. I forgot which.
22:11:11 <Ashkan> [exa] don't do this to a true Haskell enthusiast:D  I am really trying hard to see the light here:D
22:12:57 <Ashkan> monochrom See in my actual case (not over simplified snippets I post here or in that SO question) the classes involved have 3 to four parameters each and although I could make it compile in the end (using `newtype`) it is clear to me this is not the way to go about it
22:13:16 <jackdk> Declare the newtype wrapper and use `-XDerivingVia` on the types that can have that instance in that way.
22:13:32 <monochrom> Perhaps the classes were ill-designed in the first place.
22:13:38 <int-e> oh wow are we still on this topic
22:14:12 <monochrom> Even the OO people have learned what's wrong with hierarchies.
22:14:47 <int-e> . o O ( this is no longer stereo, this is more of a chorus )
22:14:55 × dcoutts_ quits (~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net) (Ping timeout: 248 seconds)
22:14:59 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 260 seconds)
22:15:20 <[exa]> Ashkan: btw do you know prolog?
22:15:43 <Ashkan> jackdk that indeed seems indispensable since without it I need to defined `Functor`, `Monad` etc for the newtype. But unfortunately that is not the problem here. Problem is sheer number of type parameters in various positions that need `newtyp`ing is too much and the resulting code is very ugly and looks very not-elegant.
22:15:43 <geekosaur> @quote antiphony
22:15:43 <lambdabot> No quotes match. Just try something else.
22:16:17 <monochrom> You can always go back to the low-tech having-both "instance Ord Int" and "instance Eq Int" way. Then no newtype wrapper.
22:17:00 <monochrom> Given an Ord instance, we all know how to make an Eq instance "automatically", it's "x == y = x>=y && x<=y". And no one does that.
22:17:30 <monochrom> So just write your ungeneralized instances and be done.
22:17:34 <monochrom> KISS.
22:18:05 <Ashkan> monochrom the centric class `Host m id game` (can host multiple `game`s identified by `id`) is sound and well put. But perhaps to try to express it using classes and instances was wrong.
22:19:29 dcoutts_ joins (~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net)
22:36:17 × enoq quits (~enoq@2a05:1141:1f5:5600:b9c9:721a:599:bfe7) (Quit: enoq)
22:36:28 × gmg quits (~user@user/gehmehgeh) (Quit: Leaving)
22:46:02 × trev_ quits (~trev@109-252-35-99.nat.spd-mgts.ru) (Remote host closed the connection)
22:47:48 × cjay quits (cjay@nerdbox.nerd2nerd.org) (Ping timeout: 268 seconds)
22:52:21 andrewboltachev joins (~andrey@178.141.127.119)
22:53:58 <andrewboltachev> Hello! I'm writing cata using recursion-schemes. How can I implement Show typeclass for "fixed" version of the type to show an error? e.g. go x = (error . show) x
22:54:25 cjay joins (cjay@nerdbox.nerd2nerd.org)
22:57:03 Guest8825 joins (~talismani@76.133.152.122)
23:01:20 × Midjak quits (~Midjak@82.66.147.146) (Quit: This computer has gone to sleep)
23:04:24 wroathe joins (~wroathe@207-153-38-140.fttp.usinternet.com)
23:04:24 × wroathe quits (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
23:04:24 wroathe joins (~wroathe@user/wroathe)
23:05:34 × wootehfoot quits (~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
23:07:33 × Ashkan quits (~Ashkan@a119011.upc-a.chello.nl) (Quit: Client closed)
23:15:56 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 255 seconds)
23:19:15 × coot quits (~coot@2a02:a310:e241:1b00:ec1a:e9df:79ac:66ba) (Ping timeout: 256 seconds)
23:20:23 gurkenglas joins (~gurkengla@dynamic-046-114-178-136.46.114.pool.telefonica.de)
23:21:11 × sammelweis quits (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Quit: No Ping reply in 180 seconds.)
23:22:33 sammelweis joins (~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
23:30:40 × Batzy quits (~quassel@user/batzy) (Ping timeout: 246 seconds)
23:38:50 beteigeuze joins (~Thunderbi@bl14-81-220.dsl.telepac.pt)
23:39:06 × jargon quits (~jargon@184.101.86.70) (Remote host closed the connection)
23:40:56 × __monty__ quits (~toonn@user/toonn) (Quit: leaving)
23:43:11 × hiredman quits (~hiredman@frontier1.downey.family) (Quit: Lost terminal)
23:46:06 × gurkenglas quits (~gurkengla@dynamic-046-114-178-136.46.114.pool.telefonica.de) (Ping timeout: 255 seconds)
23:54:46 × codaraxis___ quits (~codaraxis@user/codaraxis) (Quit: Leaving)

All times are in UTC on 2023-03-04.