2023/03/04

2023-03-04 00:01:27 +0100chele(~chele@user/chele) (Remote host closed the connection)
2023-03-04 00:02:24 +0100beteigeuze(~Thunderbi@bl14-81-220.dsl.telepac.pt) (Ping timeout: 248 seconds)
2023-03-04 00:02:52 +0100_xor(~xor@72.49.195.228)
2023-03-04 00:19:33 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex)
2023-03-04 00:20:55 +0100Dykam(Dykam@dykam.nl) (Quit: Dykam)
2023-03-04 00:21:59 +0100Dykam(Dykam@dykam.nl)
2023-03-04 00:22:59 +0100jmdaemon(~jmdaemon@user/jmdaemon) (Ping timeout: 260 seconds)
2023-03-04 00:27:11 +0100zer0bitz(~zer0bitz@2001:2003:f443:d600:f59d:2630:d861:aa7e) (Ping timeout: 260 seconds)
2023-03-04 00:27:27 +0100harveypwca(~harveypwc@2601:246:c180:a570:3828:d8:e523:3f67)
2023-03-04 00:33:45 +0100wootehfoot(~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
2023-03-04 00:43:50 +0100azimut(~azimut@gateway/tor-sasl/azimut) (Ping timeout: 255 seconds)
2023-03-04 00:45:13 +0100azimut(~azimut@gateway/tor-sasl/azimut)
2023-03-04 00:51:45 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
2023-03-04 00:53:16 +0100Albina_Pavlovna(~dekster@2603-7000-1203-4d7c-8c00-75d6-3287-dba1.res6.spectrum.com) (Quit: ZZZzzz…)
2023-03-04 00:55:43 +0100acidjnk_new(~acidjnk@p200300d6e715c407c95a74b02ab5f24e.dip0.t-ipconnect.de) (Ping timeout: 248 seconds)
2023-03-04 01:00:58 +0100finn_elija(~finn_elij@user/finn-elija/x-0085643)
2023-03-04 01:00:58 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
2023-03-04 01:00:58 +0100finn_elijaFinnElija
2023-03-04 01:01:50 +0100Albina_Pavlovna(~Albina_Pa@2603-7000-1203-4d7c-8c00-75d6-3287-dba1.res6.spectrum.com)
2023-03-04 01:04:09 +0100mauke_(~mauke@user/mauke)
2023-03-04 01:04:20 +0100gmg(~user@user/gehmehgeh) (Quit: Leaving)
2023-03-04 01:04:32 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 255 seconds)
2023-03-04 01:05:31 +0100mauke(~mauke@user/mauke) (Ping timeout: 248 seconds)
2023-03-04 01:05:32 +0100mauke_mauke
2023-03-04 01:07:20 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex)
2023-03-04 01:07:54 +0100Tuplanolla(~Tuplanoll@91-159-68-152.elisa-laajakaista.fi) (Quit: Leaving.)
2023-03-04 01:13:59 +0100jpds(~jpds@gateway/tor-sasl/jpds) (Ping timeout: 255 seconds)
2023-03-04 01:14:55 +0100jpds(~jpds@gateway/tor-sasl/jpds)
2023-03-04 01:16:37 +0100teo(~teo@user/teo)
2023-03-04 01:17:20 +0100Albina_Pavlovna(~Albina_Pa@2603-7000-1203-4d7c-8c00-75d6-3287-dba1.res6.spectrum.com) (Quit: bb)
2023-03-04 01:24:41 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 255 seconds)
2023-03-04 01:26:32 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
2023-03-04 01:30:03 +0100jmdaemon(~jmdaemon@user/jmdaemon)
2023-03-04 01:33:48 +0100ix(~ix@46.68.8.176) (Ping timeout: 255 seconds)
2023-03-04 01:35:58 +0100ix(~ix@92.40.200.235.threembb.co.uk)
2023-03-04 01:43:54 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 01:44:01 +0100 <danso> does ghc have an option (like a cli flag) to always import a module, even if nothing from it is used?
2023-03-04 01:44:27 +0100 <danso> i see no reason not to have the stuff from Data.Function and Data.Functor always available
2023-03-04 01:44:37 +0100 <geekosaur> no
2023-03-04 01:44:54 +0100 <geekosaur> you can simulate it in ghci by putting imports in your .ghci file
2023-03-04 01:45:22 +0100 <danso> yeah, i do that for ghci with many modules
2023-03-04 01:46:33 +0100 <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
2023-03-04 01:46:36 +0100_xor(~xor@72.49.195.228) (Quit: exit)
2023-03-04 01:48:32 +0100hugo-(znc@verdigris.lysator.liu.se) (Ping timeout: 248 seconds)
2023-03-04 01:48:32 +0100cheater_(~Username@user/cheater)
2023-03-04 01:49:55 +0100ix(~ix@92.40.200.235.threembb.co.uk) (Ping timeout: 260 seconds)
2023-03-04 01:51:11 +0100cheater(~Username@user/cheater) (Ping timeout: 248 seconds)
2023-03-04 01:51:18 +0100cheater_cheater
2023-03-04 01:51:35 +0100ix(~ix@213.205.241.31)
2023-03-04 01:51:37 +0100 <danso> that makes sense to me. guess i'll just have to wait patiently for & and <&> to be added to the prelude
2023-03-04 01:55:54 +0100hugo(znc@verdigris.lysator.liu.se)
2023-03-04 02:01:49 +0100mauke_(~mauke@user/mauke)
2023-03-04 02:03:33 +0100mauke(~mauke@user/mauke) (Ping timeout: 268 seconds)
2023-03-04 02:03:34 +0100mauke_mauke
2023-03-04 02:08:18 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com)
2023-03-04 02:08:18 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
2023-03-04 02:08:18 +0100wroathe(~wroathe@user/wroathe)
2023-03-04 02:10:53 +0100albet70(~xxx@2400:8902::f03c:92ff:fe60:98d8) (Remote host closed the connection)
2023-03-04 02:13:11 +0100wroathe_(~wroathe@207-153-38-140.fttp.usinternet.com)
2023-03-04 02:14:39 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 268 seconds)
2023-03-04 02:17:00 +0100albet70(~xxx@2400:8902::f03c:92ff:fe60:98d8)
2023-03-04 02:24:20 +0100mncheck(~mncheck@193.224.205.254) (Ping timeout: 252 seconds)
2023-03-04 02:25:49 +0100cheater(~Username@user/cheater) (Read error: Connection reset by peer)
2023-03-04 02:26:33 +0100cheater(~Username@user/cheater)
2023-03-04 02:27:10 +0100Midjak(~Midjak@82.66.147.146) (Quit: This computer has gone to sleep)
2023-03-04 02:46:41 +0100adanwan_(~adanwan@gateway/tor-sasl/adanwan) (Ping timeout: 255 seconds)
2023-03-04 02:46:49 +0100adanwan(~adanwan@gateway/tor-sasl/adanwan)
2023-03-04 02:59:02 +0100azimut(~azimut@gateway/tor-sasl/azimut) (Quit: ZNC - https://znc.in)
2023-03-04 02:59:47 +0100azimut(~azimut@gateway/tor-sasl/azimut)
2023-03-04 03:05:50 +0100gurkenglas(~gurkengla@dynamic-046-114-176-169.46.114.pool.telefonica.de) (Ping timeout: 268 seconds)
2023-03-04 03:05:52 +0100thegeekinside(~thegeekin@189.141.115.134) (Ping timeout: 248 seconds)
2023-03-04 03:08:11 +0100JimL(~quassel@89-162-26-217.fiber.signal.no) (Ping timeout: 248 seconds)
2023-03-04 03:09:24 +0100adanwan(~adanwan@gateway/tor-sasl/adanwan) (Remote host closed the connection)
2023-03-04 03:09:41 +0100adanwan(~adanwan@gateway/tor-sasl/adanwan)
2023-03-04 03:17:25 +0100hpc(~juzz@ip98-169-35-163.dc.dc.cox.net) (Ping timeout: 260 seconds)
2023-03-04 03:19:05 +0100hpc(~juzz@ip98-169-35-163.dc.dc.cox.net)
2023-03-04 03:20:41 +0100Lord_of_Life(~Lord@user/lord-of-life/x-2819915) (Ping timeout: 256 seconds)
2023-03-04 03:21:48 +0100Lord_of_Life(~Lord@user/lord-of-life/x-2819915)
2023-03-04 03:25:41 +0100bontaq(~user@ool-45779fe5.dyn.optonline.net)
2023-03-04 03:39:48 +0100wroathe_(~wroathe@207-153-38-140.fttp.usinternet.com) (Quit: leaving)
2023-03-04 03:54:41 +0100harveypwca(~harveypwc@2601:246:c180:a570:3828:d8:e523:3f67) (Quit: Leaving)
2023-03-04 04:02:13 +0100jero98772(~jero98772@2800:484:1d80:d8ce:efcc:cbb3:7f2a:6dff) (Remote host closed the connection)
2023-03-04 04:05:05 +0100grnman_(~michaelsc@c-66-176-3-51.hsd1.fl.comcast.net)
2023-03-04 04:10:46 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 04:12:32 +0100jero98772(~jero98772@2800:484:1d80:d8ce:efcc:cbb3:7f2a:6dff)
2023-03-04 04:15:11 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 248 seconds)
2023-03-04 04:18:30 +0100vglfr(~vglfr@145.224.100.65) (Ping timeout: 255 seconds)
2023-03-04 04:19:11 +0100Guest391(~talismani@2601:200:c000:f7a0::5321)
2023-03-04 04:20:01 +0100 <Guest391> If I have a variable inside a do-block like `lst <- liftIO $ STM.readTVarIO listVar` which is only used once
2023-03-04 04:20:27 +0100 <Guest391> (say: `forM_ (reverse $ zip [0 ..] lst) $ ...`)
2023-03-04 04:20:41 +0100 <Guest391> how can I inline it so it doesn't take up its own line?
2023-03-04 04:20:43 +0100jero98772(~jero98772@2800:484:1d80:d8ce:efcc:cbb3:7f2a:6dff) (Remote host closed the connection)
2023-03-04 04:22:31 +0100gastus_(~gastus@185.6.123.186)
2023-03-04 04:26:00 +0100gastus(~gastus@185.6.123.181) (Ping timeout: 268 seconds)
2023-03-04 04:33:42 +0100finn_elija(~finn_elij@user/finn-elija/x-0085643)
2023-03-04 04:33:42 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
2023-03-04 04:33:42 +0100finn_elijaFinnElija
2023-03-04 04:35:09 +0100td_(~td@i5387090C.versanet.de) (Ping timeout: 255 seconds)
2023-03-04 04:36:54 +0100td_(~td@i53870919.versanet.de)
2023-03-04 04:47:23 +0100jrm(~jrm@user/jrm) (Quit: ciao)
2023-03-04 04:47:45 +0100jrm(~jrm@user/jrm)
2023-03-04 04:51:27 +0100vglfr(~vglfr@145.224.100.65)
2023-03-04 05:04:50 +0100califax(~califax@user/califx) (Ping timeout: 255 seconds)
2023-03-04 05:06:26 +0100califax(~califax@user/califx)
2023-03-04 05:09:37 +0100euandreh(~Thunderbi@189.6.18.7) (Remote host closed the connection)
2023-03-04 05:18:25 +0100waleee(~waleee@2001:9b0:21c:4000:5bf9:6515:c030:57b7) (Quit: WeeChat 3.8)
2023-03-04 05:19:12 +0100bontaq(~user@ool-45779fe5.dyn.optonline.net) (Ping timeout: 248 seconds)
2023-03-04 05:20:37 +0100waleee(~waleee@2001:9b0:21c:4000:5bf9:6515:c030:57b7)
2023-03-04 05:23:58 +0100ix(~ix@213.205.241.31) (Ping timeout: 268 seconds)
2023-03-04 05:25:25 +0100ix(~ix@213.205.241.31)
2023-03-04 05:30:45 +0100ix(~ix@213.205.241.31) (Read error: Connection reset by peer)
2023-03-04 05:32:40 +0100azimut(~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection)
2023-03-04 05:34:12 +0100azimut(~azimut@gateway/tor-sasl/azimut)
2023-03-04 05:36:37 +0100ix(~ix@213.205.241.31)
2023-03-04 05:41:04 +0100waleee(~waleee@2001:9b0:21c:4000:5bf9:6515:c030:57b7) (Ping timeout: 248 seconds)
2023-03-04 05:46:15 +0100wroathe(~wroathe@user/wroathe) (Ping timeout: 255 seconds)
2023-03-04 05:57:21 +0100ec(~ec@gateway/tor-sasl/ec) (Remote host closed the connection)
2023-03-04 05:57:50 +0100ec(~ec@gateway/tor-sasl/ec)
2023-03-04 06:04:52 +0100mechap_(~mechap@user/mechap)
2023-03-04 06:06:07 +0100polyphem_(~rod@2a02:810d:840:8754:224e:f6ff:fe5e:bc17) (Ping timeout: 248 seconds)
2023-03-04 06:06:31 +0100grnman_(~michaelsc@c-66-176-3-51.hsd1.fl.comcast.net) (Ping timeout: 268 seconds)
2023-03-04 06:07:44 +0100mechap(~mechap@user/mechap) (Ping timeout: 248 seconds)
2023-03-04 06:09:24 +0100jwiegley_(~jwiegley@76-234-69-149.lightspeed.frokca.sbcglobal.net) (Quit: ZNC - http://znc.in)
2023-03-04 06:09:24 +0100johnw(~johnw@76-234-69-149.lightspeed.frokca.sbcglobal.net) (Quit: ZNC - http://znc.in)
2023-03-04 06:11:48 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 06:14:16 +0100zmt00(~zmt00@user/zmt00)
2023-03-04 06:44:50 +0100troydm(~troydm@user/troydm) (Ping timeout: 246 seconds)
2023-03-04 06:45:32 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 255 seconds)
2023-03-04 06:47:04 +0100Lycurgus(~juan@user/Lycurgus)
2023-03-04 06:56:48 +0100mbuf(~Shakthi@49.204.129.184)
2023-03-04 07:01:19 +0100tzh(~tzh@c-24-21-73-154.hsd1.or.comcast.net) (Quit: zzz)
2023-03-04 07:11:52 +0100 <Jade[m]1> `liftIO (STM.readTVarIO listVar >>= forM_ . (reverse $ zip [0..])` something like this?
2023-03-04 07:12:10 +0100 <Inst> btw, question
2023-03-04 07:12:19 +0100 <Jade[m]1> * `liftIO (STM.readTVarIO listVar >>= forM_ . (reverse $ zip [0..]) $ ...` something like this?
2023-03-04 07:12:23 +0100 <Inst> if I manually check a list's length via a pattern match, is this O(1) or O(n)?
2023-03-04 07:12:39 +0100 <Jade[m]1> O(n)
2023-03-04 07:13:11 +0100 <Jade[m]1> if you mean... (full message at <https://libera.ems.host/_matrix/media/v3/download/libera.chat/9d8499dc9b01ba9f0922911c19cf2684a3e0…>)
2023-03-04 07:13:49 +0100 <Jade[m]1> * if you mean... (full message at <https://libera.ems.host/_matrix/media/v3/download/libera.chat/5199fda87689eba68481c826553467a20676…>)
2023-03-04 07:14:35 +0100 <Jade[m]1> * if you mean... (full message at <https://libera.ems.host/_matrix/media/v3/download/libera.chat/de7c70fec03d3a2afbfc22fd198451b8c29c…>)
2023-03-04 07:17:27 +0100 <Inst> i mean, u [_,_,_,_] = True
2023-03-04 07:17:34 +0100 <Inst> so it's a manual check vs length 4
2023-03-04 07:17:37 +0100 <Inst> still O(n)?
2023-03-04 07:20:36 +0100 <jackdk> It's bounded above by a constant function
2023-03-04 07:21:38 +0100takuan(~takuan@178-116-218-225.access.telenet.be)
2023-03-04 07:24:07 +0100 <Inst> i don't understand, I guess it's still O(n)?
2023-03-04 07:24:29 +0100 <Inst> isSixCards [_,_,_,_,_,_] = True; isSixCards _ = False
2023-03-04 07:25:05 +0100mrcsno(~mrcsno@user/mrcsno)
2023-03-04 07:25:27 +0100 <Inst> if this doesn't work, do you think changing my State monad record to include a length field can improve performance?
2023-03-04 07:32:39 +0100falafel(~falafel@12.237.33.2)
2023-03-04 07:44:57 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
2023-03-04 07:46:05 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex)
2023-03-04 07:47:21 +0100 <mauke> the check itself is O(1)
2023-03-04 07:49:15 +0100mixfix41(~sdenynine@user/mixfix41) (Ping timeout: 260 seconds)
2023-03-04 07:53:52 +0100machinedgod(~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 248 seconds)
2023-03-04 07:58:23 +0100bgs(~bgs@212-85-160-171.dynamic.telemach.net)
2023-03-04 07:59:07 +0100 <Inst> holy shit, so I have O(1) length for lists, but only for specific lengths?
2023-03-04 07:59:52 +0100 <monochrom> Haha the wonder of O.
2023-03-04 08:01:41 +0100azimut(~azimut@gateway/tor-sasl/azimut) (Ping timeout: 255 seconds)
2023-03-04 08:03:45 +0100 <mauke> yes. that's O(specific_length), which is O(1)
2023-03-04 08:04:09 +0100 <mauke> assuming the spine of the list is sufficiently evaluated, of course
2023-03-04 08:04:31 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 248 seconds)
2023-03-04 08:04:33 +0100 <monochrom> Related: Every natural number is finite, but the whole set is infinite.
2023-03-04 08:05:16 +0100 <monochrom> More strongly, there is no upper bound.
2023-03-04 08:05:45 +0100 <Inst> or rather, O(1) checking for every particular length, which I suppose is probably equivalent
2023-03-04 08:06:04 +0100 <Inst> but it's useful to know since lists haev the drawback of being terrible at random access and having nasty length
2023-03-04 08:06:10 +0100 <Inst> since I have a specific length I want to check, well
2023-03-04 08:06:12 +0100 <Inst> thanks for the help
2023-03-04 08:09:53 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
2023-03-04 08:10:32 +0100johnw(~johnw@76-234-69-149.lightspeed.frokca.sbcglobal.net)
2023-03-04 08:10:55 +0100jwiegley(~jwiegley@76-234-69-149.lightspeed.frokca.sbcglobal.net)
2023-03-04 08:13:45 +0100npmania1(~Thunderbi@45.8.223.209)
2023-03-04 08:14:50 +0100Luj(~Luj@2a01:e0a:5f9:9681:5880:c9ff:fe9f:3dfb)
2023-03-04 08:15:11 +0100npmania(~Thunderbi@91.193.7.62) (Ping timeout: 248 seconds)
2023-03-04 08:15:14 +0100Guest391(~talismani@2601:200:c000:f7a0::5321) (Ping timeout: 252 seconds)
2023-03-04 08:16:48 +0100tomboy64(~tomboy64@user/tomboy64)
2023-03-04 08:17:17 +0100npmania(~Thunderbi@45.8.223.254)
2023-03-04 08:18:25 +0100npmania1(~Thunderbi@45.8.223.209) (Ping timeout: 260 seconds)
2023-03-04 08:21:31 +0100elevenkb(~elevenkb@105.224.34.36)
2023-03-04 08:23:34 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-03-04 08:27:21 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 255 seconds)
2023-03-04 08:32:54 +0100falafel(~falafel@12.237.33.2) (Remote host closed the connection)
2023-03-04 08:33:13 +0100falafel(~falafel@12.237.33.2)
2023-03-04 08:34:36 +0100adanwan_(~adanwan@gateway/tor-sasl/adanwan)
2023-03-04 08:34:59 +0100adanwan(~adanwan@gateway/tor-sasl/adanwan) (Ping timeout: 255 seconds)
2023-03-04 08:34:59 +0100jpds(~jpds@gateway/tor-sasl/jpds) (Ping timeout: 255 seconds)
2023-03-04 08:35:26 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Ping timeout: 255 seconds)
2023-03-04 08:37:08 +0100npmania(~Thunderbi@45.8.223.254) (Ping timeout: 255 seconds)
2023-03-04 08:37:46 +0100jpds(~jpds@gateway/tor-sasl/jpds)
2023-03-04 08:37:59 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643)
2023-03-04 08:39:08 +0100npmania(~Thunderbi@45.8.223.254)
2023-03-04 08:39:59 +0100harveypwca(~harveypwc@2601:246:c180:a570:3828:d8:e523:3f67)
2023-03-04 08:41:55 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 08:43:26 +0100manwithluck(~manwithlu@2406:da14:b37:1300:8c42:7d16:8950:6c74)
2023-03-04 08:44:00 +0100falafel(~falafel@12.237.33.2) (Ping timeout: 255 seconds)
2023-03-04 08:45:34 +0100lisbeths(uid135845@id-135845.lymington.irccloud.com)
2023-03-04 08:52:34 +0100monochrom(trebla@216.138.220.146) (Quit: NO CARRIER)
2023-03-04 08:52:45 +0100cheater_(~Username@user/cheater)
2023-03-04 08:55:11 +0100cheater(~Username@user/cheater) (Ping timeout: 248 seconds)
2023-03-04 08:55:21 +0100cheater_cheater
2023-03-04 08:56:00 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
2023-03-04 08:57:57 +0100eggplantade(~Eggplanta@104-55-37-220.lightspeed.sntcca.sbcglobal.net) (Remote host closed the connection)
2023-03-04 08:58:59 +0100monochrom(trebla@216.138.220.146)
2023-03-04 09:00:25 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 268 seconds)
2023-03-04 09:01:27 +0100jinsun(~jinsun@user/jinsun) (Ping timeout: 255 seconds)
2023-03-04 09:05:07 +0100jinsun(~jinsun@user/jinsun)
2023-03-04 09:06:11 +0100RootWeiller(~rootweill@dynamic-186-154-32-12.dynamic.etb.net.co)
2023-03-04 09:14:22 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
2023-03-04 09:15:30 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 255 seconds)
2023-03-04 09:24:07 +0100kupi(uid212005@id-212005.hampstead.irccloud.com)
2023-03-04 09:26:08 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 248 seconds)
2023-03-04 09:31:42 +0100acidjnk_new(~acidjnk@p200300d6e715c474301fac3f480ef3eb.dip0.t-ipconnect.de)
2023-03-04 09:32:47 +0100trev_(~trev@109-252-35-99.nat.spd-mgts.ru)
2023-03-04 09:34:50 +0100gnalzo(~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
2023-03-04 09:42:31 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-03-04 09:53:45 +0100 <tomsmeding> Inst: they're basically 'data [a] = a : [a] | []'
2023-03-04 09:54:08 +0100 <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
2023-03-04 09:54:10 +0100 <Inst> that's what i show everyone when they claim "I hate Haskell, what is this whole recursion thing?"
2023-03-04 09:54:25 +0100 <Inst> yup, thanks, that was the answer i was expecting
2023-03-04 09:54:41 +0100 <Inst> it'd fail faster, but that's about it
2023-03-04 09:54:50 +0100 <tomsmeding> if it's longer than 6, you mean?
2023-03-04 09:54:51 +0100 <tomsmeding> yeah
2023-03-04 09:55:13 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
2023-03-04 09:55:24 +0100 <Inst> if it's shorter than 6
2023-03-04 09:55:33 +0100 <Inst> anything not 6, i.e, [] shows up too early, or too late
2023-03-04 09:56:49 +0100 <tomsmeding> Inst: well if it's longer than 6, then you'll know by the time you see the 7th element
2023-03-04 09:57:07 +0100 <tomsmeding> you'll know the situation in time min(6, length list)
2023-03-04 09:57:29 +0100 <tomsmeding> note that this doesn't work if you write 'length l == 6', then it'll traverse the whole list always
2023-03-04 09:58:26 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0)
2023-03-04 09:58:36 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 09:59:30 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 255 seconds)
2023-03-04 10:00:11 +0100ericjmorey[m](~ericjmore@2001:470:69fc:105::7afc) (Quit: You have been kicked for being idle)
2023-03-04 10:00:46 +0100ix(~ix@213.205.241.31) (Read error: Connection reset by peer)
2023-03-04 10:03:06 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0) (Ping timeout: 255 seconds)
2023-03-04 10:05:55 +0100gurkenglas(~gurkengla@dynamic-046-114-176-169.46.114.pool.telefonica.de)
2023-03-04 10:06:01 +0100 <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
2023-03-04 10:06:29 +0100 <Inst> and this piece of software, I decided to try to rewrite it, to no avail
2023-03-04 10:07:11 +0100 <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 :(
2023-03-04 10:14:33 +0100Tuplanolla(~Tuplanoll@91-159-68-152.elisa-laajakaista.fi)
2023-03-04 10:16:16 +0100bgamari(~bgamari@2a06:a000:b00d::2) (Ping timeout: 248 seconds)
2023-03-04 10:18:17 +0100bgamari(~bgamari@64.223.130.214)
2023-03-04 10:25:09 +0100Guest2606(~talismani@2601:200:c000:f7a0::5321)
2023-03-04 10:27:27 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection)
2023-03-04 10:28:19 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643)
2023-03-04 10:45:15 +0100Lycurgus(~juan@user/Lycurgus) (Ping timeout: 268 seconds)
2023-03-04 10:52:36 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
2023-03-04 10:53:13 +0100califax(~califax@user/califx) (Remote host closed the connection)
2023-03-04 10:54:40 +0100califax(~califax@user/califx)
2023-03-04 10:56:52 +0100wootehfoot(~wootehfoo@user/wootehfoot)
2023-03-04 10:57:12 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 255 seconds)
2023-03-04 10:59:35 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-03-04 11:01:36 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 255 seconds)
2023-03-04 11:05:02 +0100lisbeths(uid135845@id-135845.lymington.irccloud.com) (Quit: Connection closed for inactivity)
2023-03-04 11:06:54 +0100RootWeiller(~rootweill@dynamic-186-154-32-12.dynamic.etb.net.co) (Leaving)
2023-03-04 11:08:46 +0100mei(~mei@user/mei)
2023-03-04 11:11:56 +0100Guest2606(~talismani@2601:200:c000:f7a0::5321) (Ping timeout: 246 seconds)
2023-03-04 11:12:16 +0100jakalx(~jakalx@base.jakalx.net)
2023-03-04 11:13:51 +0100 <tomsmeding> https://play.haskell.org has ghc 9.6.1-rc1 now :)
2023-03-04 11:15:07 +0100freeside(~mengwong@103.252.202.85) (Ping timeout: 248 seconds)
2023-03-04 11:15:45 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 11:17:00 +0100freeside(~mengwong@103.252.202.85)
2023-03-04 11:17:58 +0100ix(~ix@213.205.241.31)
2023-03-04 11:20:15 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 248 seconds)
2023-03-04 11:20:17 +0100ix(~ix@213.205.241.31) (Read error: Connection reset by peer)
2023-03-04 11:21:59 +0100Sgeo(~Sgeo@user/sgeo) (Read error: Connection reset by peer)
2023-03-04 11:23:18 +0100aweinstock(~aweinstoc@cpe-74-76-189-75.nycap.res.rr.com) (Ping timeout: 255 seconds)
2023-03-04 11:24:44 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
2023-03-04 11:25:40 +0100 <Inst> almost there, could always be more late
2023-03-04 11:26:06 +0100 <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?
2023-03-04 11:29:10 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 260 seconds)
2023-03-04 11:34:16 +0100Midjak(~Midjak@82.66.147.146)
2023-03-04 11:38:56 +0100shriekingnoise(~shrieking@186.137.175.87) (Ping timeout: 248 seconds)
2023-03-04 11:38:58 +0100elevenkb(~elevenkb@105.224.34.36) (Ping timeout: 260 seconds)
2023-03-04 11:43:27 +0100gmg(~user@user/gehmehgeh)
2023-03-04 11:49:24 +0100Midjak(~Midjak@82.66.147.146) (Ping timeout: 255 seconds)
2023-03-04 11:51:20 +0100mmhat(~mmh@p200300f1c70de8ffee086bfffe095315.dip0.t-ipconnect.de)
2023-03-04 11:52:01 +0100L29Ah(~L29Ah@wikipedia/L29Ah) ()
2023-03-04 11:52:05 +0100mmhat(~mmh@p200300f1c70de8ffee086bfffe095315.dip0.t-ipconnect.de) (Client Quit)
2023-03-04 11:53:11 +0100bgamari(~bgamari@64.223.130.214) (Ping timeout: 260 seconds)
2023-03-04 11:53:58 +0100mrcsno(~mrcsno@user/mrcsno) (Quit: WeeChat 3.5)
2023-03-04 11:55:45 +0100bgamari(~bgamari@64.223.158.161)
2023-03-04 12:00:43 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0)
2023-03-04 12:05:03 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0) (Ping timeout: 255 seconds)
2023-03-04 12:08:12 +0100mncheck(~mncheck@193.224.205.254)
2023-03-04 12:08:22 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 12:12:10 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
2023-03-04 12:13:53 +0100Axman6(~Axman6@user/axman6)
2023-03-04 12:14:42 +0100Guest7532(~talismani@2601:200:c000:f7a0::5321)
2023-03-04 12:16:16 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 248 seconds)
2023-03-04 12:17:14 +0100ix(~ix@213.205.241.31)
2023-03-04 12:17:42 +0100califax(~califax@user/califx) (Remote host closed the connection)
2023-03-04 12:18:08 +0100califax(~califax@user/califx)
2023-03-04 12:19:02 +0100harveypwca(~harveypwc@2601:246:c180:a570:3828:d8:e523:3f67) (Quit: Leaving)
2023-03-04 12:25:20 +0100ix(~ix@213.205.241.31) (Ping timeout: 248 seconds)
2023-03-04 12:28:28 +0100Inst_(~Inst@2601:6c4:4081:54f0:4dc:ae3f:dfd:1774)
2023-03-04 12:28:32 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 248 seconds)
2023-03-04 12:28:32 +0100gnalzo(~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Ping timeout: 248 seconds)
2023-03-04 12:29:29 +0100econo(uid147250@user/econo) (Quit: Connection closed for inactivity)
2023-03-04 12:29:53 +0100Inst(~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)))
2023-03-04 12:29:54 +0100Inst_Inst
2023-03-04 12:38:35 +0100gurkenglas(~gurkengla@dynamic-046-114-176-169.46.114.pool.telefonica.de) (Ping timeout: 264 seconds)
2023-03-04 12:38:52 +0100foul_owl(~kerry@71.212.143.88) (Ping timeout: 252 seconds)
2023-03-04 12:40:16 +0100mechap_(~mechap@user/mechap) (Ping timeout: 248 seconds)
2023-03-04 12:41:31 +0100gnalzo(~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
2023-03-04 12:42:10 +0100mechap_(~mechap@user/mechap)
2023-03-04 12:43:47 +0100 <jackdk> see `class MFunctor` in package `mmorph`
2023-03-04 12:43:55 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
2023-03-04 12:48:35 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 268 seconds)
2023-03-04 12:48:49 +0100ix(~ix@213.205.241.31)
2023-03-04 12:54:39 +0100foul_owl(~kerry@157.97.134.61)
2023-03-04 12:57:02 +0100ubert(~Thunderbi@p548c9fde.dip0.t-ipconnect.de) (Remote host closed the connection)
2023-03-04 13:03:03 +0100__monty__(~toonn@user/toonn)
2023-03-04 13:12:11 +0100grnman_(~michaelsc@c-66-176-3-51.hsd1.fl.comcast.net)
2023-03-04 13:15:41 +0100Angelz(Angelz@Angelz.oddprotocol.org) (Ping timeout: 256 seconds)
2023-03-04 13:21:47 +0100jinsl(~jinsl@2408:8207:2558:e50:211:32ff:fec8:6aea) (Ping timeout: 246 seconds)
2023-03-04 13:21:52 +0100jinsl-(~jinsl@2408:8207:2556:f740:211:32ff:fec8:6aea)
2023-03-04 13:26:20 +0100sammelweis(~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Quit: No Ping reply in 180 seconds.)
2023-03-04 13:26:57 +0100Monster196883(~hp@103.15.228.66)
2023-03-04 13:27:28 +0100sammelweis(~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
2023-03-04 13:30:12 +0100vglfr(~vglfr@145.224.100.65) (Ping timeout: 255 seconds)
2023-03-04 13:30:15 +0100Midjak(~Midjak@82.66.147.146)
2023-03-04 13:30:55 +0100remedan(~remedan@ip-94-112-0-18.bb.vodafone.cz) (Ping timeout: 246 seconds)
2023-03-04 13:31:28 +0100Monster196883(~hp@103.15.228.66) (Ping timeout: 248 seconds)
2023-03-04 13:33:22 +0100jero98772(~jero98772@2800:484:1d80:d8ce:efcc:cbb3:7f2a:6dff)
2023-03-04 13:33:33 +0100Lycurgus(~juan@98.4.112.204)
2023-03-04 13:33:33 +0100Lycurgus(~juan@98.4.112.204) (Changing host)
2023-03-04 13:33:33 +0100Lycurgus(~juan@user/Lycurgus)
2023-03-04 13:34:26 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
2023-03-04 13:36:06 +0100vglfr(~vglfr@145.224.100.65)
2023-03-04 13:38:56 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 248 seconds)
2023-03-04 13:42:44 +0100bgs(~bgs@212-85-160-171.dynamic.telemach.net) (Remote host closed the connection)
2023-03-04 13:46:20 +0100Monster196883(~hp@103.15.228.66)
2023-03-04 13:48:31 +0100Lycurgus(~juan@user/Lycurgus) (Quit: Exeunt: personae.ai-integration.biz)
2023-03-04 13:51:21 +0100 <dminuoso_> Inst: You cant do something like IO to Identity (at least not safely)
2023-03-04 13:51:32 +0100 <dminuoso_> Or well, I guess you can:
2023-03-04 13:51:35 +0100 <dminuoso_> % :t unsafePerformIO
2023-03-04 13:51:35 +0100 <yahb2> <interactive>:1:1: error: Variable not in scope: unsafePerformIO
2023-03-04 13:51:44 +0100 <dminuoso_> unsafePerformIO :: IO ~> Identity
2023-03-04 13:51:46 +0100 <dminuoso_> Roughly.
2023-03-04 13:57:35 +0100mbuf(~Shakthi@49.204.129.184) (Ping timeout: 248 seconds)
2023-03-04 13:58:30 +0100mbuf(~Shakthi@49.207.178.186)
2023-03-04 14:00:37 +0100remedan(~remedan@ip-94-112-0-18.bb.vodafone.cz)
2023-03-04 14:01:24 +0100Angelz(Angelz@Angelz.oddprotocol.org)
2023-03-04 14:06:41 +0100mechap_(~mechap@user/mechap) (Quit: WeeChat 3.8)
2023-03-04 14:08:20 +0100jmdaemon(~jmdaemon@user/jmdaemon) (Ping timeout: 255 seconds)
2023-03-04 14:08:33 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
2023-03-04 14:09:27 +0100mechap(~mechap@user/mechap)
2023-03-04 14:09:47 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex)
2023-03-04 14:12:00 +0100ix(~ix@213.205.241.31) (Ping timeout: 248 seconds)
2023-03-04 14:15:00 +0100wootehfoot(~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
2023-03-04 14:24:06 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
2023-03-04 14:25:18 +0100azimut(~azimut@gateway/tor-sasl/azimut)
2023-03-04 14:25:43 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 14:26:56 +0100freeside_(~mengwong@103.252.202.85)
2023-03-04 14:27:52 +0100freeside(~mengwong@103.252.202.85) (Ping timeout: 268 seconds)
2023-03-04 14:28:15 +0100Monster196883(~hp@103.15.228.66) (Ping timeout: 260 seconds)
2023-03-04 14:29:06 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 268 seconds)
2023-03-04 14:31:33 +0100gnalzo(~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 3.8)
2023-03-04 14:31:43 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 248 seconds)
2023-03-04 14:32:23 +0100CiaoSen(~Jura@p200300c9570e91002a3a4dfffe84dbd5.dip0.t-ipconnect.de)
2023-03-04 14:45:16 +0100Ashkan(~Ashkan@a119011.upc-a.chello.nl)
2023-03-04 14:53:59 +0100hammdist(~hammdist@67.169.114.135)
2023-03-04 14:56:04 +0100wootehfoot(~wootehfoo@user/wootehfoot)
2023-03-04 14:56:52 +0100pavonia(~user@user/siracusa) (Quit: Bye!)
2023-03-04 14:59:22 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-03-04 14:59:37 +0100psydroidpsydroid[m]
2023-03-04 15:00:59 +0100CiaoSen(~Jura@p200300c9570e91002a3a4dfffe84dbd5.dip0.t-ipconnect.de) (Ping timeout: 255 seconds)
2023-03-04 15:04:06 +0100psydroid[m]psydroid
2023-03-04 15:06:23 +0100acidjnk_new(~acidjnk@p200300d6e715c474301fac3f480ef3eb.dip0.t-ipconnect.de) (Ping timeout: 248 seconds)
2023-03-04 15:10:20 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-03-04 15:20:37 +0100L29Ah(~L29Ah@wikipedia/L29Ah)
2023-03-04 15:20:42 +0100bgamari(~bgamari@64.223.158.161) (Quit: ZNC 1.8.2 - https://znc.in)
2023-03-04 15:21:20 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 255 seconds)
2023-03-04 15:26:13 +0100machinedgod(~machinedg@d198-53-218-113.abhsia.telus.net)
2023-03-04 15:30:41 +0100bgamari(~bgamari@2a06:a000:b00d::2)
2023-03-04 15:31:38 +0100CiaoSen(~Jura@p200300c9570e91002a3a4dfffe84dbd5.dip0.t-ipconnect.de)
2023-03-04 15:36:26 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex)
2023-03-04 15:40:01 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470)
2023-03-04 15:45:08 +0100grnman_(~michaelsc@c-66-176-3-51.hsd1.fl.comcast.net) (Ping timeout: 252 seconds)
2023-03-04 15:47:26 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 255 seconds)
2023-03-04 15:50:26 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex)
2023-03-04 15:51:24 +0100perrierjouet(~perrier-j@modemcable048.127-56-74.mc.videotron.ca) (Quit: WeeChat 3.8)
2023-03-04 15:52:53 +0100perrierjouet(~perrier-j@modemcable048.127-56-74.mc.videotron.ca)
2023-03-04 15:54:11 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
2023-03-04 15:55:19 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex)
2023-03-04 16:00:37 +0100earthy(~arthurvl@2a02:a469:f5e2:1:ba27:ebff:fea0:40b0) (Quit: WeeChat 2.3)
2023-03-04 16:04:23 +0100bontaq(~user@ool-45779fe5.dyn.optonline.net)
2023-03-04 16:04:32 +0100dcoutts_(~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net) (Ping timeout: 248 seconds)
2023-03-04 16:04:46 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Read error: Connection reset by peer)
2023-03-04 16:08:34 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
2023-03-04 16:15:21 +0100shapr(~user@68.54.166.125) (Ping timeout: 255 seconds)
2023-03-04 16:23:27 +0100emmanuelux(~emmanuelu@user/emmanuelux)
2023-03-04 16:23:52 +0100kupi(uid212005@id-212005.hampstead.irccloud.com) (Quit: Connection closed for inactivity)
2023-03-04 16:28:17 +0100dcoutts_(~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net)
2023-03-04 16:28:33 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 16:33:51 +0100mvk(~mvk@2607:fea8:5caa:ac00::67db)
2023-03-04 16:33:53 +0100mvk(~mvk@2607:fea8:5caa:ac00::67db) (Client Quit)
2023-03-04 16:36:20 +0100Ashkan(~Ashkan@a119011.upc-a.chello.nl) (Quit: Client closed)
2023-03-04 16:37:12 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com)
2023-03-04 16:37:12 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
2023-03-04 16:37:12 +0100wroathe(~wroathe@user/wroathe)
2023-03-04 16:38:25 +0100mbuf(~Shakthi@49.207.178.186) (Quit: Leaving)
2023-03-04 16:42:32 +0100gnalzo(~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
2023-03-04 16:43:13 +0100coot(~coot@2a02:a310:e241:1b00:ec1a:e9df:79ac:66ba)
2023-03-04 16:55:35 +0100wroathe(~wroathe@user/wroathe) (Ping timeout: 260 seconds)
2023-03-04 16:56:12 +0100Ashkan(~Ashkan@a119011.upc-a.chello.nl)
2023-03-04 16:56:49 +0100 <Ashkan> I'm having serious trouble understanding and resolving a "constraint is smaller than head" situation https://paste.tomsmeding.com/kjvf1mee
2023-03-04 16:57:56 +0100 <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.
2023-03-04 16:58:03 +0100 <c_wraith> ... yes, types have wishes
2023-03-04 16:58:04 +0100 <Ashkan> I want to say `give C1 m` (`m :: * -> *` ) then `C2 m` can be deduced/instanced/instantiated (don't know the correct term)
2023-03-04 16:58:44 +0100 <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
2023-03-04 16:59:03 +0100 <c_wraith> Well, the error message tells you exactly how to make it go away
2023-03-04 16:59:11 +0100 <c_wraith> but it won't work the way you want
2023-03-04 16:59:17 +0100 <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.
2023-03-04 16:59:42 +0100 <int-e> So I think, f2 should just be a function of type Yas m => m ()
2023-03-04 17:00:05 +0100MangoIV[m](~mangoivma@2001:470:69fc:105::2:8417) (Quit: You have been kicked for being idle)
2023-03-04 17:00:17 +0100int-eis using, too many commas.
2023-03-04 17:00:18 +0100 <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
2023-03-04 17:00:34 +0100 <c_wraith> UndecidableInstances is fine
2023-03-04 17:00:39 +0100MangoIV[m](~mangoivma@2001:470:69fc:105::2:8417)
2023-03-04 17:00:44 +0100 <c_wraith> The problem is that the entire goal is wrong
2023-03-04 17:00:47 +0100azimut(~azimut@gateway/tor-sasl/azimut) (Ping timeout: 255 seconds)
2023-03-04 17:01:10 +0100 <c_wraith> You should not opt a type into being an instance of a class just because it's an instance of another class.
2023-03-04 17:01:14 +0100 <Ashkan> Okay, help me understand. I wish to say : give C1 m , I can construct a C2 m
2023-03-04 17:01:21 +0100 <c_wraith> Don't say that
2023-03-04 17:01:36 +0100 <c_wraith> say "if you want a C2 m, you can create it trivially with this helper"
2023-03-04 17:01:56 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 246 seconds)
2023-03-04 17:02:28 +0100 <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"
2023-03-04 17:02:30 +0100 <c_wraith> Being a member of a class should basically always be opt-in
2023-03-04 17:02:52 +0100 <c_wraith> (I'll forgive Typeable because of how important it is that only the compiler can create instances)
2023-03-04 17:03:19 +0100 <Ashkan> c_wraith but `C2` is a typeclass. I can't return an instance from a function : `C1 m => () -> C2 m`
2023-03-04 17:03:47 +0100 <c_wraith> you can write code such that `instance C2 m` is a sufficient definition
2023-03-04 17:04:04 +0100 <c_wraith> well. not quite. `instance C2 M`
2023-03-04 17:04:06 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0)
2023-03-04 17:04:46 +0100 <c_wraith> or take another route and go with `instance C2 M where f2 = defaultF2`
2023-03-04 17:04:59 +0100 <int-e> Providing an instance for a newtype wrapper is also an option. Or default implementations if there's only one "superclass" like C1.
2023-03-04 17:05:22 +0100 <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.
2023-03-04 17:05:23 +0100 <int-e> (This is attractive, I think, when the class has more than one method.)
2023-03-04 17:05:53 +0100 <int-e> Do you need the type class at all?
2023-03-04 17:05:59 +0100 <c_wraith> Ashkan: then why does C2 exist at all?
2023-03-04 17:06:20 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 260 seconds)
2023-03-04 17:07:17 +0100 <Ashkan> Maybe if I provide the concrete use-case : `instance (CMonadIO m, R.MonadReader (TVar (M.Map Int s)) m => Host m GameId s`
2023-03-04 17:07:47 +0100 <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.
2023-03-04 17:08:23 +0100 <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`)
2023-03-04 17:08:35 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0) (Ping timeout: 256 seconds)
2023-03-04 17:09:09 +0100 <c_wraith> Ashkan: that really doesn't look like something that belongs in a class at all
2023-03-04 17:11:05 +0100 <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
2023-03-04 17:11:52 +0100 <c_wraith> Do you already have multiple different implementations that you want to write code that works interchangeably between?
2023-03-04 17:12:09 +0100 <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 ?
2023-03-04 17:14:04 +0100 <Ashkan> c_wraith that is an altogether different and orthogonal concern. But interestingly enough, actually Yes !
2023-03-04 17:14:05 +0100 <Ashkan> And another, totally different, game hosting that uses Postgres and can provide persistency
2023-03-04 17:14:23 +0100 <Ashkan> A game-server could be spun with with either of the Host-ing types
2023-03-04 17:14:37 +0100 <c_wraith> honestly, this sounds like you want a record of functions
2023-03-04 17:16:00 +0100 <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  )
2023-03-04 17:16:02 +0100 <c_wraith> You want varying behavior, but aren't interested in program-wide coherence
2023-03-04 17:16:07 +0100razetime(~Thunderbi@117.193.6.69)
2023-03-04 17:17:26 +0100 <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 ?
2023-03-04 17:18:40 +0100 <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 ?
2023-03-04 17:18:48 +0100 <c_wraith> varying behavior is why we have first-class functions
2023-03-04 17:21:07 +0100polyphem_(~rod@2a02:810d:840:8754:e5c4:fa80:2cc4:f0a8)
2023-03-04 17:21:10 +0100 <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
2023-03-04 17:21:38 +0100 <c_wraith> tagless final is not a very good way to do things practically, no
2023-03-04 17:21:48 +0100 <c_wraith> it has some real issues in the face of coherence
2023-03-04 17:22:45 +0100 <c_wraith> though at least tagless final doesn't try to build hierarchies, it just adds new bits of functionality independently
2023-03-04 17:24:16 +0100 <c_wraith> Ultimately the problem with you're trying to do is that you're trying to opt *all* types into some class.
2023-03-04 17:24:19 +0100tzh(~tzh@c-24-21-73-154.hsd1.wa.comcast.net)
2023-03-04 17:25:01 +0100 <c_wraith> That's not what the type class system is for. It's for when each type has a *different* implementation
2023-03-04 17:25:46 +0100 <c_wraith> If your entire class implementation is in terms of another class, just use that other class
2023-03-04 17:26:42 +0100 <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.
2023-03-04 17:26:42 +0100 <Ashkan> But that is a bit off-topic. My problem I think is much simpler than that:
2023-03-04 17:26:43 +0100 <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 ?
2023-03-04 17:27:51 +0100 <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.
2023-03-04 17:29:19 +0100 <c_wraith> If you try to go down that path, GHC will be telling you to enable Overlapping or Incoherent instances soon
2023-03-04 17:29:28 +0100 <c_wraith> And both of those can break a program badly if misapplied
2023-03-04 17:30:00 +0100 <c_wraith> It's far simpler to just allow types to opt-in to classes instead of forcing a global instance
2023-03-04 17:30:10 +0100 <Ashkan> so `C1 m => C2 m` is essentially wrong , no matter how `C1` and `C2` are complicated or it makes sense in the domain ?
2023-03-04 17:30:16 +0100 <c_wraith> correct
2023-03-04 17:30:34 +0100 <c_wraith> that's just not compatible with how type classes work
2023-03-04 17:30:52 +0100 <Ashkan> I don't understand why :-?
2023-03-04 17:31:48 +0100 <Ashkan> okay, help me understand this: How come `class C1 m => C2 m` is good but `instance C1 m => C2 m` is not ?
2023-03-04 17:31:56 +0100 <c_wraith> `instance C1 m => C2 m` is saying "all types have an instance of C2 that requires an instance of C1"
2023-03-04 17:32:11 +0100 <c_wraith> that's backwards from what you think it's saying
2023-03-04 17:32:42 +0100 <c_wraith> It's saying "this instance exists for all types"
2023-03-04 17:33:11 +0100 <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"
2023-03-04 17:33:25 +0100 <c_wraith> One is opt-in.
2023-03-04 17:33:32 +0100 <c_wraith> The other one just applies to everything
2023-03-04 17:33:52 +0100 <hpc> maybe this can help clarify it, and why you might not want type classes here at all
2023-03-04 17:34:02 +0100 <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 ?
2023-03-04 17:34:27 +0100Xe(~cadey@tailscale/xe) (Remote host closed the connection)
2023-03-04 17:34:29 +0100 <c_wraith> Ashkan: yes, that's the meaning in the class definition
2023-03-04 17:35:30 +0100wootehfoot(~wootehfoo@user/wootehfoot) (Ping timeout: 252 seconds)
2023-03-04 17:35:35 +0100 <hpc> say you have class Game g where ..., data GameType = Memory | Pgsql | Mysql | File | ..., and newGame :: Game g => GameType -> g
2023-03-04 17:35:52 +0100 <hpc> newGame has to be valid for every combination of GameType and g
2023-03-04 17:36:09 +0100 <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 ?
2023-03-04 17:36:17 +0100 <hpc> so if you have instance Game FileGame where ..., you need (newGame Pgsql :: FileGame) to make sense
2023-03-04 17:36:27 +0100 <hpc> which doesn't really work
2023-03-04 17:36:49 +0100 <hpc> an example in base where it's really tempting to use type classes is file handles
2023-03-04 17:37:00 +0100 <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
2023-03-04 17:37:06 +0100 <hpc> they can be file-backed, they can be stdin/out/err, or network sockets, or who knows what
2023-03-04 17:37:18 +0100 <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
2023-03-04 17:37:47 +0100 <hpc> because no matter what the implementation is, they're still all handles and you can genuinely treat them all exactly the same
2023-03-04 17:37:53 +0100 <hpc> as opposed to say, numbers
2023-03-04 17:37:56 +0100 <Ashkan> Now what is meant by `instance <some-constraint> => C2 m` ?
2023-03-04 17:38:19 +0100 <hpc> where you're not mixing Word8 and Rational no matter how hard you try
2023-03-04 17:38:31 +0100 <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"
2023-03-04 17:39:11 +0100 <Ashkan> (reading hpc s messages now:D  my brain can't follow both at the same time)
2023-03-04 17:39:32 +0100 <hpc> (heh, feel free to save mine for later)
2023-03-04 17:40:21 +0100 <hpc> (might as well get a better understanding of type classes even if you end up doing something completely different)
2023-03-04 17:40:44 +0100Xe(~cadey@tailscale/xe)
2023-03-04 17:40:56 +0100 <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
2023-03-04 17:41:39 +0100 <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"
2023-03-04 17:41:51 +0100Albina_Pavlovna(~Albina_Pa@2603-7000-1203-4d7c-846d-1927-68d6-5999.res6.spectrum.com)
2023-03-04 17:42:24 +0100dhil(~dhil@80.208.56.181.static.fibianet.dk)
2023-03-04 17:42:35 +0100 <geekosaur> "there is an instance of C2 m. but it requires a C1 m; if it doesn't have one, it will fail"
2023-03-04 17:42:48 +0100 <Ashkan> c_wraith Yes. I'm literally reading `a => b` as "a gives b"
2023-03-04 17:42:54 +0100 <geekosaur> this leaves no room for an alternative C2 m instance
2023-03-04 17:43:06 +0100 <c_wraith> Ashkan: yes, that's what's wrong. that's not what it's saying.
2023-03-04 17:43:35 +0100 <c_wraith> Ashkan: It's saying "b, and also a is required"
2023-03-04 17:44:04 +0100 <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" ?
2023-03-04 17:44:26 +0100 <c_wraith> no, it's saying "all m *do* have an instance of C2, and this is it. also, it requires C1"
2023-03-04 17:44:28 +0100 <geekosaur> yes. with no alternative; the C1 has to exist
2023-03-04 17:46:32 +0100 <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 ?
2023-03-04 17:46:45 +0100 <c_wraith> yes
2023-03-04 17:46:50 +0100 <c_wraith> that's exactly it
2023-03-04 17:48:38 +0100 <Ashkan> very counter-intuitive syntax:D  okay. So how is this interfering with wha I'm trying to say here ?
2023-03-04 17:48:38 +0100 <Ashkan> oh ! I see ... I'm forcing every possible `m` to somehow satisfy this impossible demand. right ?
2023-03-04 17:48:53 +0100 <c_wraith> That's half of it, yes.
2023-03-04 17:49:07 +0100 <c_wraith> The other half is that it's preventing adding any other instance of the class
2023-03-04 17:49:24 +0100 <c_wraith> that's the coherence part
2023-03-04 17:49:49 +0100 <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 ?
2023-03-04 17:50:44 +0100 <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
2023-03-04 17:50:46 +0100 <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 ?
2023-03-04 17:51:12 +0100 <c_wraith> Smaller in that there are fewer types that match
2023-03-04 17:51:36 +0100 <c_wraith> Like, to look at a different example: instance (Show a, Show b) => Show (a, b)
2023-03-04 17:51:50 +0100 <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
2023-03-04 17:51:53 +0100 <c_wraith> There are fewer types that match (a, b) than there are that match a or b
2023-03-04 17:52:08 +0100 <c_wraith> so (a, b) is smaller than the constraint types
2023-03-04 17:52:11 +0100Albina_Pavlovna(~Albina_Pa@2603-7000-1203-4d7c-846d-1927-68d6-5999.res6.spectrum.com) (Quit: ZZZzzz…)
2023-03-04 17:52:58 +0100 <c_wraith> Anyway. Haskell is very conservative in its rules for what instances are allowed, by default.
2023-03-04 17:53:17 +0100 <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 ?
2023-03-04 17:53:30 +0100 <c_wraith> UndecidableInstances very specifically just to disable that check.
2023-03-04 17:53:59 +0100 <c_wraith> *is* just to disable...
2023-03-04 17:54:06 +0100 <int-e> it's not *wrong*, disobeying that rule can just make type-checking fail to terminate
2023-03-04 17:54:57 +0100 <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.
2023-03-04 17:56:09 +0100 <Ashkan> > There are fewer types that match (a, b) than there are that match a or b
2023-03-04 17:56:10 +0100 <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 ?
2023-03-04 17:56:10 +0100 <lambdabot> error:
2023-03-04 17:56:11 +0100 <lambdabot> Data constructor not in scope:
2023-03-04 17:56:11 +0100 <lambdabot> There
2023-03-04 17:56:30 +0100 <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.
2023-03-04 17:56:51 +0100 <c_wraith> The bigger problem is that you're really not actually communicating what you mean
2023-03-04 17:57:44 +0100 <geekosaur> (a,b) is the cartesian product of all types with all types. it's a very large instance head
2023-03-04 17:58:08 +0100 <geekosaur> Show a and Show b both limit this
2023-03-04 17:58:47 +0100 <int-e> Ashkan: it's a syntactic criterion... both a and b are syntactically smaller than the type (a,b).
2023-03-04 17:59:51 +0100 <Ashkan> int-e because `a` and `b` are not wrapped but `(a,b)` (although `*`) but has a `(,)` in it ?
2023-03-04 17:59:58 +0100 <int-e> The syntax is relevant because the type checker operates on these types symbolically.
2023-03-04 18:00:34 +0100 <Ashkan> so e.g. `Int` and `String` is smaller than `Map Int String` ?
2023-03-04 18:01:05 +0100 <int-e> a is a proper sub-(type-expression) of (a,b)
2023-03-04 18:01:32 +0100 <Ashkan> "sub-(type-expression)" is that a thing:D  ?
2023-03-04 18:01:33 +0100 <Jade[m]1> Ashkan: depends on your notion of 'smaller'
2023-03-04 18:01:45 +0100 <Ashkan> or you just made it up to ease the conversation ?
2023-03-04 18:02:45 +0100 <Ashkan> Jade[m]1 I mean regarding my error `instance C1 m => C2 m` (error : constraint is no  smaller than instance head)
2023-03-04 18:05:10 +0100 <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.
2023-03-04 18:05:24 +0100Albina_Pavlovna(~Albina_Pa@2603-7000-1203-4d7c-846d-1927-68d6-5999.res6.spectrum.com)
2023-03-04 18:05:49 +0100 <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.
2023-03-04 18:06:26 +0100 <Ashkan> @int-e I'm trying to understand the error both on technical and conceptual level
2023-03-04 18:06:26 +0100 <lambdabot> Unknown command, try @list
2023-03-04 18:06:42 +0100 <Ashkan> I was hoping the technical level would be more precise and easier to graps
2023-03-04 18:07:40 +0100 <Ashkan> Okay I understand what smaller means here. But why does GHC need the `C1 m` to be smaller than `C2 m` ?
2023-03-04 18:08:00 +0100 <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.
2023-03-04 18:09:07 +0100 <Ashkan> okay,  then what is *conceptually* wrong with `instance C1 m => C2 m` ?
2023-03-04 18:09:15 +0100 <int-e> Nothing.
2023-03-04 18:09:48 +0100 <int-e> Well. Except that this indicates that C2 is useless, but that has nothing to do with the error.
2023-03-04 18:10:05 +0100califax(~califax@user/califx) (Ping timeout: 255 seconds)
2023-03-04 18:10:14 +0100 <Ashkan> > C2 is useless
2023-03-04 18:10:15 +0100 <Ashkan> help me understand why
2023-03-04 18:10:16 +0100 <lambdabot> error:
2023-03-04 18:10:16 +0100 <lambdabot> • Data constructor not in scope: C2 :: t0 -> t1 -> t
2023-03-04 18:10:16 +0100 <lambdabot> • Perhaps you meant variable ‘_2’ (imported from Control.Lens)error:
2023-03-04 18:10:33 +0100 <int-e> There's no other instance C2 can have without causing an overlap.
2023-03-04 18:10:40 +0100 <int-e> So why don't you just use C1 instead?
2023-03-04 18:11:25 +0100 <Ashkan> > There's no other instance C2 can have without causing an overlap.
2023-03-04 18:11:25 +0100 <Ashkan> this is exactly what I don't get
2023-03-04 18:11:26 +0100 <lambdabot> <hint>:1:18: error: parse error on input ‘instance’
2023-03-04 18:11:28 +0100califax(~califax@user/califx)
2023-03-04 18:11:33 +0100 <int-e> (yes, you can allow overlapping instances... but that's a road to *actually* scary territory.)
2023-03-04 18:12:00 +0100 <Ashkan> (O'm not gonna, specially when an actual Haskeller is telling me not to)
2023-03-04 18:12:01 +0100 <int-e> Ashkan: when selecting an instance, the context doesn't matter, it just looks at the `instance C2 m` part.
2023-03-04 18:12:26 +0100acidjnk_new(~acidjnk@p200300d6e715c442a472905c59e58702.dip0.t-ipconnect.de)
2023-03-04 18:12:49 +0100 <int-e> and 'm' will match *any* type (of kind * -> * in your case) at all.
2023-03-04 18:13:08 +0100Xe(~cadey@tailscale/xe) (Remote host closed the connection)
2023-03-04 18:14:14 +0100 <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 ?
2023-03-04 18:14:53 +0100hammdist(~hammdist@67.169.114.135) ()
2023-03-04 18:15:34 +0100 <Ashkan> So better way is to define whatever `C2` class is providing as simple bundle of functions with a `C1 m =>` requirements
2023-03-04 18:16:06 +0100 <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.
2023-03-04 18:16:45 +0100 <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.
2023-03-04 18:17:52 +0100 <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.
2023-03-04 18:18:10 +0100azimut(~azimut@gateway/tor-sasl/azimut)
2023-03-04 18:18:14 +0100 <int-e> As you said.
2023-03-04 18:19:27 +0100 <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.
2023-03-04 18:19:49 +0100razetime(~Thunderbi@117.193.6.69) (Remote host closed the connection)
2023-03-04 18:20:23 +0100 <int-e> Yeah. "overlapping instances" is the keyword. And you'll find the Haskell community divided on whether those are benign or harmful.
2023-03-04 18:21:22 +0100 <int-e> The unambiguously scary territory are "incoherent instances".
2023-03-04 18:21:39 +0100 <geekosaur> the actual error here was "no smaller than the instance head" though
2023-03-04 18:22:18 +0100 <int-e> Yes. Which, as agreed, has nothing to do with overlapping instances.
2023-03-04 18:22:27 +0100 <Ashkan> Okay. I got this part (thanks you) and the warning (overlapping instances).
2023-03-04 18:22:27 +0100 <Ashkan> How do I express what I want to say ?
2023-03-04 18:22:28 +0100 <Ashkan> "if `C1 m`, then `C2 m`"
2023-03-04 18:23:02 +0100 <geekosaur> typeclasses are not the tool for that; they don't support it
2023-03-04 18:23:16 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 18:23:49 +0100 <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)
2023-03-04 18:24:47 +0100 <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)
2023-03-04 18:24:54 +0100 <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
2023-03-04 18:25:58 +0100 <int-e> And as an extension to GHC (DerivingVia?) there's a mechanism for deriving an instance of C2 via that newtype.
2023-03-04 18:26:13 +0100 <int-e> s/to GHC/in GHC/
2023-03-04 18:26:39 +0100dcoutts_(~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net) (Ping timeout: 255 seconds)
2023-03-04 18:27:09 +0100Xe(~cadey@tailscale/xe)
2023-03-04 18:27:36 +0100 <int-e> > (Sum 23 <> Sum 42, Product 23 <> Product 42) -- using instances Num a => Monoid (Sum a) and Num a => Monoid (Product a)
2023-03-04 18:27:37 +0100 <lambdabot> (Sum {getSum = 65},Product {getProduct = 966})
2023-03-04 18:29:21 +0100 <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.
2023-03-04 18:29:27 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 255 seconds)
2023-03-04 18:30:04 +0100 <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 :
2023-03-04 18:30:05 +0100 <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
2023-03-04 18:30:10 +0100 <int-e> (because it's an *obligation* to provide a C2 instance whenever you make a C1 instance)
2023-03-04 18:31:15 +0100 <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.
2023-03-04 18:32:34 +0100 <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)
2023-03-04 18:33:52 +0100CiaoSen(~Jura@p200300c9570e91002a3a4dfffe84dbd5.dip0.t-ipconnect.de) (Ping timeout: 248 seconds)
2023-03-04 18:34:18 +0100 <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
2023-03-04 18:35:35 +0100 <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`.
2023-03-04 18:36:19 +0100 <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).
2023-03-04 18:37:10 +0100 <int-e> Ashkan: well I still think that C2 probably shouldn't exist in that scenario.
2023-03-04 18:38:09 +0100 <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
2023-03-04 18:38:31 +0100 <Ashkan> I have a feeling there should be a more idiomatic way to achieve what I want to say. maybe not ...
2023-03-04 18:40:18 +0100 <Jade[m]1> Ashkan: A lot of things are just that
2023-03-04 18:40:23 +0100mechap(~mechap@user/mechap) (Ping timeout: 256 seconds)
2023-03-04 18:41:51 +0100 <Ashkan> int-e > well I still think that C2 probably shouldn't exist in that scenario.
2023-03-04 18:41:51 +0100 <Ashkan> Care to elaborate why ? perhaps offer and alternative ? this way I can learn something deeper perhaps
2023-03-04 18:41:59 +0100mechap(~mechap@user/mechap)
2023-03-04 18:42:00 +0100Guest7532(~talismani@2601:200:c000:f7a0::5321) (Ping timeout: 260 seconds)
2023-03-04 18:42:00 +0100sammelweis(~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10) (Quit: No Ping reply in 180 seconds.)
2023-03-04 18:43:10 +0100 <geekosaur> what does C2 offer over C1?
2023-03-04 18:43:19 +0100sammelweis(~quassel@2601:401:8200:2d4c:bd9:d04c:7f69:eb10)
2023-03-04 18:47:08 +0100 <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
2023-03-04 18:48:12 +0100 <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
2023-03-04 18:49:52 +0100 <geekosaur> I suspected that (and am not sure why int-e didn't, tbh)
2023-03-04 18:50:30 +0100 <geekosaur> but to me this feels like OOP think, which typeclasses aren't
2023-03-04 18:51:08 +0100 <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.
2023-03-04 18:51:09 +0100 <Ashkan> Now that said, if some `m` meets certain requirements , then it can be made a host.
2023-03-04 18:51:30 +0100 <int-e> geekosaur: I may have had my suspicions, but I reduced them to "probably".
2023-03-04 18:51:35 +0100CiaoSen(~Jura@p200300c9570e91002a3a4dfffe84dbd5.dip0.t-ipconnect.de)
2023-03-04 18:51:54 +0100 <int-e> ste.tomsmeding.com/oQ1epvWG
2023-03-04 18:51:58 +0100 <int-e> grr
2023-03-04 18:52:24 +0100 <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 ?
2023-03-04 18:53:24 +0100cheater_(~Username@user/cheater)
2023-03-04 18:53:57 +0100 <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 ?
2023-03-04 18:54:20 +0100 <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, ... }`
2023-03-04 18:54:22 +0100 <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
2023-03-04 18:54:51 +0100 <int-e> and possibly two type families to express the m -> k s relation if that's somehow crucial.
2023-03-04 18:55:11 +0100 <geekosaur> this again feels very OOPish to me; a Host in particular seems like it's a `data` not a `class`
2023-03-04 18:55:20 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 18:55:37 +0100 <int-e> sure, there is that
2023-03-04 18:55:44 +0100cheater(~Username@user/cheater) (Ping timeout: 248 seconds)
2023-03-04 18:55:51 +0100cheater_cheater
2023-03-04 18:57:17 +0100 <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
2023-03-04 18:57:36 +0100 <Ashkan> int-e this is the "record" way people are suggesting, right ? a record of functions ...
2023-03-04 18:57:55 +0100 <int-e> I don't know, I didn't see that part of the discussion.
2023-03-04 18:58:05 +0100 <int-e> (It's likely though.)
2023-03-04 19:00:04 +0100 <Ashkan> > this again feels very OOPish to me; a Host in particular seems like it's a `data` not a `class`
2023-03-04 19:00:04 +0100 <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 ...
2023-03-04 19:00:06 +0100 <lambdabot> <hint>:1:35: error: parse error on input ‘;’
2023-03-04 19:00:38 +0100dsrt^(~dsrt@c-24-30-76-89.hsd1.ga.comcast.net) (Remote host closed the connection)
2023-03-04 19:00:47 +0100whatsupdoc(uid509081@id-509081.hampstead.irccloud.com) (Quit: Connection closed for inactivity)
2023-03-04 19:02:10 +0100 <Ashkan> The goal is to learn proper Haskell with the prospect of landing a job after years of Scala:D
2023-03-04 19:04:22 +0100 <Jade[m]1> Ashkan: What instances do you plan to write for host?
2023-03-04 19:04:32 +0100 <Jade[m]1> What other types are hosts?
2023-03-04 19:04:40 +0100shriekingnoise(~shrieking@186.137.175.87)
2023-03-04 19:05:05 +0100 <Ashkan> Alright let me take a different perspective, indulge me here:
2023-03-04 19:05:06 +0100 <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.
2023-03-04 19:05:06 +0100 <Ashkan> 2) As a helper lib (or whatever), if `m` satisfies some constraints then it can host and the lib implements the instance.
2023-03-04 19:05:07 +0100 <Ashkan> How do I archive this in Haskell without type classes ? possible ?
2023-03-04 19:05:41 +0100 <monochrom> Tagless-final uses a type class.
2023-03-04 19:05:59 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0)
2023-03-04 19:06:04 +0100vglfr(~vglfr@145.224.100.65) (Remote host closed the connection)
2023-03-04 19:06:53 +0100CiaoSen(~Jura@p200300c9570e91002a3a4dfffe84dbd5.dip0.t-ipconnect.de) (Ping timeout: 246 seconds)
2023-03-04 19:07:14 +0100califax(~califax@user/califx) (Ping timeout: 255 seconds)
2023-03-04 19:07:30 +0100 <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".
2023-03-04 19:07:56 +0100 <Jade[m]1> Ashkan: That is what typeclasses are for indeed
2023-03-04 19:08:02 +0100 <Jade[m]1> but maybe you need to seperate the typeclass from the actual data
2023-03-04 19:08:08 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 255 seconds)
2023-03-04 19:08:20 +0100califax(~califax@user/califx)
2023-03-04 19:08:35 +0100 <Jade[m]1> because in oop you have these things coupled together, which you don't in fp
2023-03-04 19:08:47 +0100 <Ashkan> Jade[m]1 I will answer but first here me this:
2023-03-04 19:08:48 +0100 <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
2023-03-04 19:08:48 +0100 <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
2023-03-04 19:09:00 +0100 <int-e> "tagless-final" should definitely have been mentioned way earlier in this discussion
2023-03-04 19:09:02 +0100ec(~ec@gateway/tor-sasl/ec) (Ping timeout: 255 seconds)
2023-03-04 19:10:39 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0) (Ping timeout: 248 seconds)
2023-03-04 19:10:57 +0100ec(~ec@gateway/tor-sasl/ec)
2023-03-04 19:11:08 +0100 <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
2023-03-04 19:11:13 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex)
2023-03-04 19:11:30 +0100vglfr(~vglfr@145.224.100.65)
2023-03-04 19:11:34 +0100vglfr(~vglfr@145.224.100.65) (Remote host closed the connection)
2023-03-04 19:12:02 +0100vglfr(~vglfr@145.224.100.65)
2023-03-04 19:12:14 +0100vglfr(~vglfr@145.224.100.65) (Remote host closed the connection)
2023-03-04 19:14:31 +0100 <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):
2023-03-04 19:14:31 +0100 <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)
2023-03-04 19:14:32 +0100 <Ashkan> 2- exactly as above, if a Yesod handler can produce a proper `TVar` it can host (I have coded this already)
2023-03-04 19:14:32 +0100 <Ashkan> 3-given a database connection ,wrapping it in a proper `m` and creating a `newtype` , this can also host
2023-03-04 19:14:36 +0100 <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.
2023-03-04 19:14:40 +0100jinsl-(~jinsl@2408:8207:2556:f740:211:32ff:fec8:6aea) (Ping timeout: 260 seconds)
2023-03-04 19:17:05 +0100 <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
2023-03-04 19:18:46 +0100 <monochrom> Because even tagless-final is not always necessary.
2023-03-04 19:18:56 +0100califax(~califax@user/califx) (Ping timeout: 255 seconds)
2023-03-04 19:19:18 +0100 <Ashkan> int-e
2023-03-04 19:19:18 +0100 <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.
2023-03-04 19:19:19 +0100 <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.
2023-03-04 19:19:20 +0100 <lambdabot> <hint>:1:7: error: parse error on input ‘,’
2023-03-04 19:19:48 +0100jinsl(~jinsl@123.120.166.36)
2023-03-04 19:20:27 +0100polyphem_(~rod@2a02:810d:840:8754:e5c4:fa80:2cc4:f0a8) (Ping timeout: 248 seconds)
2023-03-04 19:20:33 +0100califax(~califax@user/califx)
2023-03-04 19:21:22 +0100polyphem_(~rod@2a02:810d:840:8754:224e:f6ff:fe5e:bc17)
2023-03-04 19:21:24 +0100 <Ashkan> this is the whole thing https://paste.tomsmeding.com/LmaKlJyQ
2023-03-04 19:21:39 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 255 seconds)
2023-03-04 19:22:35 +0100mechap(~mechap@user/mechap) (Ping timeout: 260 seconds)
2023-03-04 19:23:25 +0100 <Ashkan> fixed some error https://paste.tomsmeding.com/SBJZfPF0
2023-03-04 19:23:50 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com)
2023-03-04 19:23:50 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
2023-03-04 19:23:50 +0100wroathe(~wroathe@user/wroathe)
2023-03-04 19:24:22 +0100mechap(~mechap@user/mechap)
2023-03-04 19:25:36 +0100vglfr(~vglfr@145.224.100.65)
2023-03-04 19:26:09 +0100econo(uid147250@user/econo)
2023-03-04 19:27:10 +0100Ashkan(~Ashkan@a119011.upc-a.chello.nl) (Quit: Client closed)
2023-03-04 19:30:02 +0100mechap(~mechap@user/mechap) (Ping timeout: 268 seconds)
2023-03-04 19:31:39 +0100krei-se(~quassel@p5087440b.dip0.t-ipconnect.de)
2023-03-04 19:31:41 +0100mechap(~mechap@user/mechap)
2023-03-04 19:38:30 +0100Ashkan(~Ashkan@a119011.upc-a.chello.nl)
2023-03-04 19:40:10 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 19:42:23 +0100enoq(~enoq@2a05:1141:1f5:5600:b9c9:721a:599:bfe7)
2023-03-04 19:42:31 +0100dcoutts_(~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net)
2023-03-04 19:43:02 +0100Ashkan(~Ashkan@a119011.upc-a.chello.nl) (Client Quit)
2023-03-04 19:44:00 +0100abrar(~abrar@static-108-2-152-54.phlapa.fios.verizon.net) (Ping timeout: 265 seconds)
2023-03-04 19:45:00 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
2023-03-04 19:49:33 +0100machinedgod(~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 255 seconds)
2023-03-04 19:53:06 +0100Sciencentistguy9(~sciencent@hacksoc/ordinary-member)
2023-03-04 19:53:25 +0100berberman_(~berberman@user/berberman)
2023-03-04 19:54:03 +0100berberman(~berberman@user/berberman) (Ping timeout: 248 seconds)
2023-03-04 19:55:59 +0100Sciencentistguy(~sciencent@hacksoc/ordinary-member) (Ping timeout: 264 seconds)
2023-03-04 19:56:00 +0100Sciencentistguy9Sciencentistguy
2023-03-04 19:56:03 +0100aweinstock(~aweinstoc@cpe-74-76-189-75.nycap.res.rr.com)
2023-03-04 19:57:48 +0100zer0bitz(~zer0bitz@2001:2003:f443:d600:11d4:814d:b4b3:885c)
2023-03-04 19:59:28 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 252 seconds)
2023-03-04 20:00:34 +0100dcoutts_(~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net) (Ping timeout: 252 seconds)
2023-03-04 20:05:56 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0)
2023-03-04 20:12:20 +0100mncheck(~mncheck@193.224.205.254) (Ping timeout: 246 seconds)
2023-03-04 20:13:36 +0100jinsl(~jinsl@123.120.166.36) (Ping timeout: 248 seconds)
2023-03-04 20:13:46 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 252 seconds)
2023-03-04 20:14:22 +0100jinsl(~jinsl@123.120.184.53)
2023-03-04 20:17:55 +0100harveypwca(~harveypwc@2601:246:c180:a570:3828:d8:e523:3f67)
2023-03-04 20:19:27 +0100wroathe(~wroathe@user/wroathe) (Ping timeout: 248 seconds)
2023-03-04 20:25:14 +0100sagax(~sagax_nb@user/sagax)
2023-03-04 20:27:20 +0100califax(~califax@user/califx) (Ping timeout: 255 seconds)
2023-03-04 20:28:01 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 20:30:05 +0100califax(~califax@user/califx)
2023-03-04 20:30:23 +0100jinsun(~jinsun@user/jinsun) (Read error: Connection reset by peer)
2023-03-04 20:32:12 +0100dhil(~dhil@80.208.56.181.static.fibianet.dk) (Read error: Connection reset by peer)
2023-03-04 20:32:56 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 268 seconds)
2023-03-04 20:34:01 +0100mixfix41(~sdenynine@user/mixfix41)
2023-03-04 20:37:05 +0100lxi(~quassel@2a02:2f08:4d1c:400:fee5:4f99:b3f4:888d)
2023-03-04 20:39:15 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net)
2023-03-04 20:41:42 +0100waleee(~waleee@2001:9b0:21c:4000:5bf9:6515:c030:57b7)
2023-03-04 20:43:48 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 20:47:24 +0100wroathe(~wroathe@50.205.197.50)
2023-03-04 20:47:24 +0100wroathe(~wroathe@50.205.197.50) (Changing host)
2023-03-04 20:47:24 +0100wroathe(~wroathe@user/wroathe)
2023-03-04 20:48:30 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 255 seconds)
2023-03-04 20:50:03 +0100pavonia(~user@user/siracusa)
2023-03-04 20:53:35 +0100segfaultfizzbuzz(~segfaultf@23-93-74-212.fiber.dynamic.sonic.net) (Ping timeout: 260 seconds)
2023-03-04 20:55:11 +0100krei-se(~quassel@p5087440b.dip0.t-ipconnect.de) (Quit: https://quassel-irc.org - Chat comfortably. Anywhere.)
2023-03-04 21:01:24 +0100Ashkan(~Ashkan@a119011.upc-a.chello.nl)
2023-03-04 21:03:50 +0100Albina_Pavlovna(~Albina_Pa@2603-7000-1203-4d7c-846d-1927-68d6-5999.res6.spectrum.com) (Quit: ZZZzzz…)
2023-03-04 21:09:33 +0100Ashkan(~Ashkan@a119011.upc-a.chello.nl) (Quit: Client closed)
2023-03-04 21:13:25 +0100takuan(~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection)
2023-03-04 21:17:11 +0100 <juri_> is there a no-op for Spec?
2023-03-04 21:19:41 +0100 <mauke> pure ()?
2023-03-04 21:21:29 +0100 <Hecate> probably pure () yeah
2023-03-04 21:25:07 +0100jmdaemon(~jmdaemon@user/jmdaemon)
2023-03-04 21:27:59 +0100krei-se(~krei-se@p5087440b.dip0.t-ipconnect.de)
2023-03-04 21:32:21 +0100 <juri_> thanks.
2023-03-04 21:32:46 +0100biberu(~biberu@user/biberu) (Read error: Connection reset by peer)
2023-03-04 21:36:33 +0100biberu(~biberu@user/biberu)
2023-03-04 21:38:19 +0100ix(~ix@213.205.241.31)
2023-03-04 21:41:20 +0100Sgeo(~Sgeo@user/sgeo)
2023-03-04 21:43:04 +0100machinedgod(~machinedg@d198-53-218-113.abhsia.telus.net)
2023-03-04 21:48:00 +0100gnalzo(~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Ping timeout: 248 seconds)
2023-03-04 21:50:10 +0100gnalzo(~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
2023-03-04 21:50:34 +0100cheater_(~Username@user/cheater)
2023-03-04 21:52:01 +0100mauke_(~mauke@user/mauke)
2023-03-04 21:53:20 +0100cheater(~Username@user/cheater) (Ping timeout: 248 seconds)
2023-03-04 21:53:20 +0100mauke(~mauke@user/mauke) (Ping timeout: 248 seconds)
2023-03-04 21:53:20 +0100mauke_mauke
2023-03-04 21:53:21 +0100cheater_cheater
2023-03-04 21:55:39 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 22:00:19 +0100dcoutts_(~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net)
2023-03-04 22:01:41 +0100harveypwca(~harveypwc@2601:246:c180:a570:3828:d8:e523:3f67) (Quit: Leaving)
2023-03-04 22:01:53 +0100Guest|26(~Guest|26@aftr-62-216-209-1.dynamic.mnet-online.de)
2023-03-04 22:02:00 +0100Guest|26(~Guest|26@aftr-62-216-209-1.dynamic.mnet-online.de) (Client Quit)
2023-03-04 22:02:17 +0100gmg(~user@user/gehmehgeh) (Ping timeout: 255 seconds)
2023-03-04 22:02:50 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0) (Remote host closed the connection)
2023-03-04 22:03:30 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e1f4:8ede:df26:d4a0)
2023-03-04 22:03:38 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Ping timeout: 255 seconds)
2023-03-04 22:04:37 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643)
2023-03-04 22:04:57 +0100gmg(~user@user/gehmehgeh)
2023-03-04 22:16:25 +0100Ashkan(~Ashkan@a119011.upc-a.chello.nl)
2023-03-04 22:18:52 +0100Ashkan(~Ashkan@a119011.upc-a.chello.nl) (Client Quit)
2023-03-04 22:26:29 +0100 <Inst> question about a claim an acquaintance / friend made
2023-03-04 22:26:34 +0100 <Inst> how bad are fizzled sparks?
2023-03-04 22:27:00 +0100 <Inst> I did a refactor that improved program performance by about 10%, but changed my spark conversion rate from 80% to 50-60%
2023-03-04 22:27:03 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 255 seconds)
2023-03-04 22:27:10 +0100 <Inst> wondering if it's possible to reclaim all the fizzled sparks
2023-03-04 22:28:35 +0100bontaq(~user@ool-45779fe5.dyn.optonline.net) (Remote host closed the connection)
2023-03-04 22:28:52 +0100Guest38(~Guest38@pool-96-245-193-224.phlapa.fios.verizon.net)
2023-03-04 22:29:54 +0100ubert(~Thunderbi@p200300ecdf2947664c2eb563067a71e8.dip0.t-ipconnect.de)
2023-03-04 22:32:05 +0100anpad(~pandeyan@user/anpad) (Quit: ZNC 1.8.2 - https://znc.in)
2023-03-04 22:34:18 +0100 <monochrom> This is why you take empirical measurements to see how much benefit/cost you get, as opposed to talking about it philosophically.
2023-03-04 22:34:53 +0100anpad(~pandeyan@user/anpad)
2023-03-04 22:35:18 +0100 <monochrom> At least until you develop a model that is time-proven to accurately predict empirical measurements.
2023-03-04 22:35:29 +0100 <Inst> someone else claimed here that they were expecting 100% conversion rates
2023-03-04 22:36:05 +0100 <monochrom> IOW the scientific method, as opposed to the internet-crowd-talk method.
2023-03-04 22:36:08 +0100 <Inst> if it's possible to prevent the sparks from getting GCed or fizzled
2023-03-04 22:36:23 +0100Guest38(~Guest38@pool-96-245-193-224.phlapa.fios.verizon.net) (Quit: Client closed)
2023-03-04 22:36:25 +0100 <Inst> would see a nice 70-100% performance improvement
2023-03-04 22:41:50 +0100ix(~ix@213.205.241.31) (Read error: Connection reset by peer)
2023-03-04 22:46:26 +0100Ashkan(~Ashkan@a119011.upc-a.chello.nl)
2023-03-04 22:46:50 +0100 <Ashkan> I put it up on SO if anyone is interested https://stackoverflow.com/questions/75638862/how-do-i-conditionally-declare-an-instance
2023-03-04 22:47:31 +0100ix(~ix@213.205.241.31)
2023-03-04 22:48:09 +0100 <monochrom> You will have no luck "translating" Scala "classes" to Haskell classes. They are not even related.
2023-03-04 22:48:46 +0100 <hpc> it's sheer unfortunate coincidence that they use the same word
2023-03-04 22:48:52 +0100 <hpc> like how "gift" means "poison" in german
2023-03-04 22:49:01 +0100 <monochrom> At most you may have some luck translating Scala/Java interfaces/traits to Haskell classes, but even that requires rethinking and rewriting.
2023-03-04 22:49:49 +0100 <Ashkan> Guys please, I know that:D  what did I do to suggest I'm confusing OOP class with Haskell type classes:)
2023-03-04 22:50:27 +0100 <darkling> Mentioning Scala in the question. :)
2023-03-04 22:50:33 +0100gnalzo(~gnalzo@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 3.8)
2023-03-04 22:50:45 +0100 <[exa]> Ashkan: I guess a bit of extensions might help to at least solve that error (FlexibleInstances?)
2023-03-04 22:50:45 +0100 <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.
2023-03-04 22:51:35 +0100wootehfoot(~wootehfoo@user/wootehfoot)
2023-03-04 22:51:36 +0100cheater_(~Username@user/cheater)
2023-03-04 22:52:03 +0100 <monochrom> I didn't even saying anything about OOP. Look at my wording again. Only Scala and Haskell.
2023-03-04 22:52:22 +0100 <monochrom> So I am not even assuming that you would use Scala for OOP.
2023-03-04 22:53:03 +0100cheater(~Username@user/cheater) (Ping timeout: 255 seconds)
2023-03-04 22:53:12 +0100cheater_cheater
2023-03-04 22:53:35 +0100azimut(~azimut@gateway/tor-sasl/azimut) (Ping timeout: 255 seconds)
2023-03-04 22:54:28 +0100 <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).
2023-03-04 22:54:53 +0100ix(~ix@213.205.241.31) (Read error: Connection reset by peer)
2023-03-04 22:55:55 +0100 <monochrom> At any rate "given A m then instance B m" is probably just never done in Haskell.
2023-03-04 22:56:29 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net)
2023-03-04 22:57:29 +0100 <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 ?
2023-03-04 22:57:29 +0100 <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".
2023-03-04 22:58:11 +0100 <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.
2023-03-04 22:59:28 +0100 <Ashkan> Good point about the std lib
2023-03-04 22:59:29 +0100 <Ashkan> Actually I understand the "long story" very well by now. What I don't know yet is how to achieve the desired effect.
2023-03-04 22:59:51 +0100 <Inst> curious, I've been sort of interested in the scripting possibilities of Haskell
2023-03-04 22:59:51 +0100 <Ashkan> I can only think that type classes (and instances) are not the way to go about this then ...
2023-03-04 23:00:00 +0100ubert(~Thunderbi@p200300ecdf2947664c2eb563067a71e8.dip0.t-ipconnect.de) (Ping timeout: 248 seconds)
2023-03-04 23:00:07 +0100 <monochrom> OK, now look at "class Eq a => Ord a".
2023-03-04 23:00:13 +0100 <Inst> oh, busy, I'll pull off
2023-03-04 23:00:18 +0100ubert(~Thunderbi@p548c9fde.dip0.t-ipconnect.de)
2023-03-04 23:01:10 +0100 <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
2023-03-04 23:01:14 +0100 <monochrom> And try to make your own type X and write your "instance Ord X" and deliberately forget to write an "instance Eq X".
2023-03-04 23:01:33 +0100merijn(~merijn@86-86-29-250.fixed.kpn.net) (Ping timeout: 268 seconds)
2023-03-04 23:01:56 +0100 <monochrom> Oh that's easy, if "class A => B" is the wrong direction, then change it to "class B => A".
2023-03-04 23:02:10 +0100 <[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)"
2023-03-04 23:02:15 +0100 <monochrom> One of them ought to be the right direction, no? There are only two things to try.
2023-03-04 23:03:00 +0100 <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"
2023-03-04 23:03:11 +0100 <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?
2023-03-04 23:03:21 +0100ix(~ix@213.205.241.31)
2023-03-04 23:03:22 +0100 <Ashkan> B doesn't even know about A (nor should it) at the class level
2023-03-04 23:03:59 +0100 <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?
2023-03-04 23:04:08 +0100Cale(~cale@cpe80d04ade0a03-cm80d04ade0a01.cpe.net.cable.rogers.com)
2023-03-04 23:04:49 +0100 <monochrom> Look at "class Eq a => Ord a". It says exactly "instances of Ord can be made only for instances of Eq".
2023-03-04 23:04:55 +0100 <Ashkan> Actually you are right, very bad wording on my part. Better wording:
2023-03-04 23:04:56 +0100 <Ashkan> *one* way to construct a `B m` is to provide an `A m`
2023-03-04 23:04:58 +0100azimut(~azimut@gateway/tor-sasl/azimut)
2023-03-04 23:05:01 +0100 <monochrom> And it is precisely because they are closedly related.
2023-03-04 23:05:01 +0100 <Ashkan> only one way, not the only way.
2023-03-04 23:05:09 +0100 <[exa]> Ashkan: true
2023-03-04 23:05:09 +0100 <monochrom> So make up your mind, are they related or not?
2023-03-04 23:05:17 +0100jargon(~jargon@184.101.86.70)
2023-03-04 23:06:30 +0100 <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.
2023-03-04 23:06:37 +0100 <[exa]> Ashkan: just a very quick extra guess, aren't you trying to ensure something like `not(A a) => not (B a)` ?
2023-03-04 23:06:52 +0100 <Ashkan> My mind is made up, very clear and problem statement very precise. However the typeclass machinery is not the answer.
2023-03-04 23:07:03 +0100std_mutex[m](~stdmutexm@2001:470:69fc:105::1:4534)
2023-03-04 23:07:06 +0100 <monochrom> A standard library example is the Product newtype wrapper that says "if you have Num, then we know one way to make Monoid".
2023-03-04 23:07:45 +0100 <[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)
2023-03-04 23:07:47 +0100 <monochrom> In particular it doesn't go "instance Num a => Monoid a".
2023-03-04 23:08:01 +0100 <monochrom> Instead it goes "instance Num a => Monoid (Product a)"
2023-03-04 23:08:51 +0100 <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!
2023-03-04 23:09:00 +0100 <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
2023-03-04 23:09:00 +0100 <Ashkan> https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/instances.html#instance-termination-rules)
2023-03-04 23:09:55 +0100 <Ashkan> [exa] no . but monochrom was right, my wording of my question was very misleading. Fixed now.
2023-03-04 23:10:07 +0100 <[exa]> Ashkan: btw c'mon, there's no shame in UndecidableInstances :]
2023-03-04 23:10:47 +0100 <monochrom> UndecidableInstances still doesn't make "instance X a => Y a" compile.
2023-03-04 23:10:57 +0100 <monochrom> or usable. I forgot which.
2023-03-04 23:11:11 +0100 <Ashkan> [exa] don't do this to a true Haskell enthusiast:D  I am really trying hard to see the light here:D
2023-03-04 23:12:57 +0100 <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
2023-03-04 23:13:16 +0100 <jackdk> Declare the newtype wrapper and use `-XDerivingVia` on the types that can have that instance in that way.
2023-03-04 23:13:32 +0100 <monochrom> Perhaps the classes were ill-designed in the first place.
2023-03-04 23:13:38 +0100 <int-e> oh wow are we still on this topic
2023-03-04 23:14:12 +0100 <monochrom> Even the OO people have learned what's wrong with hierarchies.
2023-03-04 23:14:47 +0100 <int-e> . o O ( this is no longer stereo, this is more of a chorus )
2023-03-04 23:14:55 +0100dcoutts_(~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net) (Ping timeout: 248 seconds)
2023-03-04 23:14:59 +0100wroathe(~wroathe@user/wroathe) (Ping timeout: 260 seconds)
2023-03-04 23:15:20 +0100 <[exa]> Ashkan: btw do you know prolog?
2023-03-04 23:15:43 +0100 <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.
2023-03-04 23:15:43 +0100 <geekosaur> @quote antiphony
2023-03-04 23:15:43 +0100 <lambdabot> No quotes match. Just try something else.
2023-03-04 23:16:17 +0100 <monochrom> You can always go back to the low-tech having-both "instance Ord Int" and "instance Eq Int" way. Then no newtype wrapper.
2023-03-04 23:17:00 +0100 <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.
2023-03-04 23:17:30 +0100 <monochrom> So just write your ungeneralized instances and be done.
2023-03-04 23:17:34 +0100 <monochrom> KISS.
2023-03-04 23:18:05 +0100 <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.
2023-03-04 23:19:29 +0100dcoutts_(~duncan@cpc69403-oxfd27-2-0-cust285.4-3.cable.virginm.net)
2023-03-04 23:36:17 +0100enoq(~enoq@2a05:1141:1f5:5600:b9c9:721a:599:bfe7) (Quit: enoq)
2023-03-04 23:36:28 +0100gmg(~user@user/gehmehgeh) (Quit: Leaving)
2023-03-04 23:46:02 +0100trev_(~trev@109-252-35-99.nat.spd-mgts.ru) (Remote host closed the connection)
2023-03-04 23:47:48 +0100cjay(cjay@nerdbox.nerd2nerd.org) (Ping timeout: 268 seconds)
2023-03-04 23:52:21 +0100andrewboltachev(~andrey@178.141.127.119)
2023-03-04 23:53:58 +0100 <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
2023-03-04 23:54:25 +0100cjay(cjay@nerdbox.nerd2nerd.org)
2023-03-04 23:57:03 +0100Guest8825(~talismani@76.133.152.122)