Home liberachat/#haskell: Logs Calendar

Logs on 2023-10-20 (liberachat/#haskell)

00:03:20 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
00:06:13 emmanuelux joins (~emmanuelu@user/emmanuelux)
00:12:04 × emmanuelux quits (~emmanuelu@user/emmanuelux) (Quit: au revoir)
00:18:04 notzmv joins (~zmv@user/notzmv)
00:23:02 × pointlessslippe1 quits (~pointless@212.82.82.3) (Ping timeout: 255 seconds)
00:28:13 × ystael quits (~ystael@user/ystael) (Ping timeout: 255 seconds)
00:32:01 × ddellacosta quits (~ddellacos@ool-44c738de.dyn.optonline.net) (Ping timeout: 260 seconds)
00:32:45 ddellacosta joins (~ddellacos@ool-44c738de.dyn.optonline.net)
00:39:59 × myxos quits (~myxos@cpe-65-28-251-121.cinci.res.rr.com) (Remote host closed the connection)
00:42:52 pointlessslippe1 joins (~pointless@212.82.82.3)
00:43:04 L29Ah joins (~L29Ah@wikipedia/L29Ah)
00:47:12 machinedgod joins (~machinedg@d198-53-218-113.abhsia.telus.net)
00:49:44 myxos joins (~myxos@cpe-65-28-251-121.cinci.res.rr.com)
00:52:44 × Pozyomka quits (~pyon@user/pyon) (Quit: Pozyomka, my beloved: https://i.imgur.com/BMmVfTq.png)
00:58:23 Lord_of_Life_ joins (~Lord@user/lord-of-life/x-2819915)
00:59:02 × Lord_of_Life quits (~Lord@user/lord-of-life/x-2819915) (Ping timeout: 255 seconds)
00:59:46 Lord_of_Life_ is now known as Lord_of_Life
01:00:38 × Vajb quits (~Vajb@207.61.167.122) (Read error: Connection reset by peer)
01:01:28 Vajb joins (~Vajb@207.61.167.122)
01:05:51 × Vajb quits (~Vajb@207.61.167.122) (Ping timeout: 260 seconds)
01:12:12 × otto_s quits (~user@p5de2fa05.dip0.t-ipconnect.de) (Ping timeout: 240 seconds)
01:13:58 otto_s joins (~user@p5b0443cb.dip0.t-ipconnect.de)
01:31:05 × infinity0 quits (~infinity0@pwned.gg) (Ping timeout: 240 seconds)
01:38:27 Alleria joins (~JohnGalt@user/alleria)
01:57:24 bilegeek joins (~bilegeek@2600:1008:b092:8609:420e:1a54:5cd5:c60f)
02:00:07 × myxos quits (~myxos@cpe-65-28-251-121.cinci.res.rr.com) (Remote host closed the connection)
02:02:27 × Ranhir quits (~Ranhir@157.97.53.139) (Quit: KVIrc 5.0.0 Aria http://www.kvirc.net/)
02:04:40 × td_ quits (~td@i53870930.versanet.de) (Ping timeout: 258 seconds)
02:06:30 td_ joins (~td@i5387093B.versanet.de)
02:13:45 Ranhir joins (~Ranhir@157.97.53.139)
02:14:44 × xff0x quits (~xff0x@ai101218.d.east.v6connect.net) (Ping timeout: 255 seconds)
02:15:22 × waleee quits (~waleee@2001:9b0:21c:e600:f2f3:f744:435d:137c) (Ping timeout: 272 seconds)
02:22:13 × thegeekinside quits (~thegeekin@189.180.124.118) (Ping timeout: 255 seconds)
02:27:55 finn_elija joins (~finn_elij@user/finn-elija/x-0085643)
02:27:55 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
02:27:55 finn_elija is now known as FinnElija
02:30:16 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:a042:5d7c:7cf4:626d) (Remote host closed the connection)
02:30:32 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:e1a3:648c:fb34:72ec)
02:30:36 × machinedgod quits (~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 248 seconds)
02:31:22 × Alleria quits (~JohnGalt@user/alleria) (Quit: Textual IRC Client: www.textualapp.com)
02:48:18 × ddellacosta quits (~ddellacos@ool-44c738de.dyn.optonline.net) (Ping timeout: 255 seconds)
02:49:59 ddellacosta joins (~ddellacos@ool-44c738de.dyn.optonline.net)
02:50:32 × [itchyjunk] quits (~itchyjunk@user/itchyjunk/x-7353470) (Remote host closed the connection)
02:52:09 × sabino quits (~sabino@user/sabino) (Quit: Lambda _ -> x)
02:52:36 × pretty_dumm_guy quits (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5)
02:59:31 sm joins (~sm@plaintextaccounting/sm)
03:00:03 × sm quits (~sm@plaintextaccounting/sm) (Client Quit)
03:02:43 xff0x joins (~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp)
03:02:47 × td_ quits (~td@i5387093B.versanet.de) (Ping timeout: 255 seconds)
03:04:34 td_ joins (~td@i5387090C.versanet.de)
03:11:29 arahael joins (~arahael@119-18-2-212.771202.syd.nbn.aussiebb.net)
03:14:22 JuanDaugherty joins (~juan@98.4.112.204)
03:17:53 × aforemny quits (~aforemny@2001:9e8:6cc3:2a00:a85b:4589:39bf:9c93) (Ping timeout: 258 seconds)
03:18:32 aforemny joins (~aforemny@2001:9e8:6cea:d00:75b1:1f0b:5b86:9d9f)
03:29:24 thegeekinside joins (~thegeekin@189.180.124.118)
03:31:55 nate2 joins (~nate@c-98-45-169-16.hsd1.ca.comcast.net)
03:36:35 × nate2 quits (~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 240 seconds)
03:44:37 × JuanDaugherty quits (~juan@98.4.112.204) (Quit: DCP disconnect)
03:47:26 Vajb joins (~Vajb@207.61.167.122)
03:51:45 zmt01 joins (~zmt00@user/zmt00)
03:53:32 × ft quits (~ft@p3e9bc680.dip0.t-ipconnect.de) (Ping timeout: 272 seconds)
03:54:48 × zmt00 quits (~zmt00@user/zmt00) (Ping timeout: 272 seconds)
03:54:56 ft joins (~ft@p4fc2a529.dip0.t-ipconnect.de)
03:55:05 infinity0 joins (~infinity0@pwned.gg)
03:55:18 JuanDaugherty joins (~juan@user/JuanDaugherty)
03:56:43 × JuanDaugherty quits (~juan@user/JuanDaugherty) (Client Quit)
04:08:26 JuanDaugherty joins (~juan@user/JuanDaugherty)
04:08:53 _ht joins (~Thunderbi@28-52-174-82.ftth.glasoperator.nl)
04:09:16 × hugo quits (znc@verdigris.lysator.liu.se) (Ping timeout: 248 seconds)
04:13:23 jargon joins (~jargon@174-22-221-150.phnx.qwest.net)
04:14:53 × thegeekinside quits (~thegeekin@189.180.124.118) (Ping timeout: 255 seconds)
04:15:36 × bliminse quits (~bliminse@user/bliminse) (Quit: leaving)
04:19:18 × JuanDaugherty quits (~juan@user/JuanDaugherty) (Quit: JuanDaugherty)
04:19:18 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
04:19:52 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
04:23:34 × phma quits (phma@2001:5b0:210b:f338:ff94:b91f:1e4:46fd) (Read error: Connection reset by peer)
04:24:17 phma joins (~phma@host-67-44-208-191.hnremote.net)
04:24:23 hugo joins (znc@verdigris.lysator.liu.se)
04:26:33 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
04:26:45 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
04:29:14 × ChaiTRex quits (~ChaiTRex@user/chaitrex) (Ping timeout: 256 seconds)
04:31:50 ChaiTRex joins (~ChaiTRex@user/chaitrex)
04:33:53 P1RATEZ joins (piratez@user/p1ratez)
04:37:14 × P1RATEZ quits (piratez@user/p1ratez) (Remote host closed the connection)
04:40:32 × bilegeek quits (~bilegeek@2600:1008:b092:8609:420e:1a54:5cd5:c60f) (Quit: Leaving)
04:42:56 vglfr joins (~vglfr@88.155.170.213)
04:46:26 × Vajb quits (~Vajb@207.61.167.122) (Ping timeout: 258 seconds)
04:48:44 × Fischmiep quits (~Fischmiep@user/Fischmiep) (Ping timeout: 248 seconds)
04:49:17 × L29Ah quits (~L29Ah@wikipedia/L29Ah) (Ping timeout: 248 seconds)
05:00:45 × vglfr quits (~vglfr@88.155.170.213) (Read error: Connection reset by peer)
05:01:06 vglfr joins (vglfr@gateway/vpn/protonvpn/vglfr)
05:01:46 × td_ quits (~td@i5387090C.versanet.de) (Ping timeout: 258 seconds)
05:02:37 td_ joins (~td@i5387091B.versanet.de)
05:03:40 Fischmiep joins (~Fischmiep@user/Fischmiep)
05:07:34 × vglfr quits (vglfr@gateway/vpn/protonvpn/vglfr) (Remote host closed the connection)
05:08:10 vglfr joins (vglfr@gateway/vpn/protonvpn/vglfr)
05:13:26 harveypwca joins (~harveypwc@2601:246:c280:6a90:837d:db39:3eea:f7db)
05:13:53 × vglfr quits (vglfr@gateway/vpn/protonvpn/vglfr) (Remote host closed the connection)
05:14:28 vglfr joins (vglfr@gateway/vpn/protonvpn/vglfr)
05:17:42 takuan joins (~takuan@178-116-218-225.access.telenet.be)
05:21:58 bliminse joins (~bliminse@user/bliminse)
05:28:16 × vglfr quits (vglfr@gateway/vpn/protonvpn/vglfr) (Remote host closed the connection)
05:29:01 vglfr joins (vglfr@gateway/vpn/protonvpn/vglfr)
05:35:08 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 248 seconds)
05:35:25 euleritian joins (~euleritia@dynamic-046-114-203-116.46.114.pool.telefonica.de)
05:45:26 rosco joins (~rosco@yp-150-69.tm.net.my)
05:49:56 × vglfr quits (vglfr@gateway/vpn/protonvpn/vglfr) (Ping timeout: 260 seconds)
05:50:19 vglfr joins (~vglfr@88.155.170.213)
06:01:35 thegeekinside joins (~thegeekin@189.180.124.118)
06:04:41 × dcoutts quits (~duncan@net77-43-75-226.mclink.it) (Remote host closed the connection)
06:06:16 dcoutts joins (~duncan@net77-43-75-226.mclink.it)
06:06:34 × monochrom quits (trebla@216.138.220.146) (Quit: ZNC 1.8.2+deb3build2 - https://znc.in)
06:09:32 × stiell_ quits (~stiell@gateway/tor-sasl/stiell) (Remote host closed the connection)
06:09:59 stiell_ joins (~stiell@gateway/tor-sasl/stiell)
06:12:07 × rosco quits (~rosco@yp-150-69.tm.net.my) (Read error: Connection reset by peer)
06:12:59 × dcoutts quits (~duncan@net77-43-75-226.mclink.it) (Ping timeout: 245 seconds)
06:20:44 Unicorn_Princess joins (~Unicorn_P@user/Unicorn-Princess/x-3540542)
06:23:22 monochrom joins (trebla@216.138.220.146)
06:23:55 dcoutts joins (~duncan@net77-43-75-226.mclink.it)
06:24:21 coot joins (~coot@89-69-206-216.dynamic.chello.pl)
06:24:46 Inst joins (~Inst@120.244.192.250)
06:26:31 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Read error: Connection reset by peer)
06:26:31 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Read error: Connection reset by peer)
06:26:31 × ec quits (~ec@gateway/tor-sasl/ec) (Read error: Connection reset by peer)
06:26:31 × chiselfuse quits (~chiselfus@user/chiselfuse) (Read error: Connection reset by peer)
06:26:57 ec joins (~ec@gateway/tor-sasl/ec)
06:26:58 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
06:27:08 chiselfuse joins (~chiselfus@user/chiselfuse)
06:27:31 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
06:28:23 × euleritian quits (~euleritia@dynamic-046-114-203-116.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
06:28:33 sm joins (~sm@plaintextaccounting/sm)
06:28:40 × dcoutts quits (~duncan@net77-43-75-226.mclink.it) (Ping timeout: 255 seconds)
06:28:45 euleritian joins (~euleritia@77.22.252.56)
06:35:27 × euleritian quits (~euleritia@77.22.252.56) (Ping timeout: 240 seconds)
06:35:47 euleritian joins (~euleritia@dynamic-046-114-203-116.46.114.pool.telefonica.de)
06:43:36 × euleritian quits (~euleritia@dynamic-046-114-203-116.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
06:43:53 euleritian joins (~euleritia@77.22.252.56)
06:47:32 × echoreply quits (~echoreply@2001:19f0:9002:1f3b:5400:ff:fe6f:8b8d) (Quit: WeeChat 2.8)
06:48:51 echoreply joins (~echoreply@45.32.163.16)
06:50:53 × thegeekinside quits (~thegeekin@189.180.124.118) (Ping timeout: 248 seconds)
06:51:16 oo_miguel joins (~Thunderbi@78-11-179-96.static.ip.netia.com.pl)
06:52:42 pretty_dumm_guy joins (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655)
06:52:56 × euleritian quits (~euleritia@77.22.252.56) (Ping timeout: 260 seconds)
06:53:08 euleritian joins (~euleritia@dynamic-046-114-203-116.46.114.pool.telefonica.de)
06:53:33 vpan joins (~vpan@212.117.1.172)
07:01:22 × arahael quits (~arahael@119-18-2-212.771202.syd.nbn.aussiebb.net) (Ping timeout: 258 seconds)
07:10:23 × todi quits (~todi@p4fd1a3e6.dip0.t-ipconnect.de) (Quit: ZNC - https://znc.in)
07:17:09 mastarija joins (~mastarija@141-136-135-70.dsl.iskon.hr)
07:18:28 <mastarija> So, I know I can use the TypeOperators to define e.g. `type (∧) a b = (a, b)`. But is there a way to do the negation, e.g. `type (¬) a = a -> Void`?
07:19:11 <mastarija> This would be unary operator, so GHC complains I'm missing an argument to the ¬ when I try to use it.
07:27:10 idgaen joins (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
07:27:34 × euleritian quits (~euleritia@dynamic-046-114-203-116.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
07:27:51 euleritian joins (~euleritia@77.22.252.56)
07:30:10 danza_ joins (~francesco@151.35.112.73)
07:33:27 nate2 joins (~nate@c-98-45-169-16.hsd1.ca.comcast.net)
07:34:52 × tcard quits (~tcard@2400:4051:5801:7500:cf17:befc:ff82:5303) (Quit: Leaving)
07:36:40 tcard joins (~tcard@2400:4051:5801:7500:cf17:befc:ff82:5303)
07:38:43 × nate2 quits (~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 264 seconds)
07:39:12 <[exa]> mastarija: unary minus is sufficiently scary
07:39:55 <mastarija> Yes :)
07:40:23 <mastarija> But still. You know that hearts whants what heart wants, right? ;)
07:40:25 <[exa]> how is unary minus even declared as an operator? isn't it a completely special case?
07:40:34 <mastarija> Yes, I think it is.
07:40:40 <mastarija> It's just syntax sugar for negate
07:40:56 <[exa]> i've got a bad feeling you'd need to add to the syntax sugar then
07:41:10 <[exa]> but yeah it's ;_;
07:41:24 × Nixkernal_ quits (~Nixkernal@115.16.194.178.dynamic.wline.res.cust.swisscom.ch) (Read error: Connection reset by peer)
07:41:27 <mastarija> Is there a way to do this perhaps? Asking for a friend :)
07:41:34 <mastarija> Something like rebindable syntax?
07:43:04 Nixkernal joins (~Nixkernal@115.16.194.178.dynamic.wline.res.cust.swisscom.ch)
07:47:09 × Inst quits (~Inst@120.244.192.250) (Ping timeout: 245 seconds)
07:48:16 gmg joins (~user@user/gehmehgeh)
07:53:01 × Nixkernal quits (~Nixkernal@115.16.194.178.dynamic.wline.res.cust.swisscom.ch) (Ping timeout: 260 seconds)
07:53:43 × danza_ quits (~francesco@151.35.112.73) (Ping timeout: 264 seconds)
07:54:56 × mastarija quits (~mastarija@141-136-135-70.dsl.iskon.hr) (Quit: Ping timeout (120 seconds))
07:55:53 × wagle quits (~wagle@quassel.wagle.io) (Quit: http://quassel-irc.org - Chat comfortably. Anywhere.)
07:56:37 machinedgod joins (~machinedg@d198-53-218-113.abhsia.telus.net)
07:56:45 Square joins (~Square@user/square)
07:56:46 wagle joins (~wagle@quassel.wagle.io)
07:59:06 × vglfr quits (~vglfr@88.155.170.213) (Remote host closed the connection)
07:59:16 <jackdk> `type Not a = a -> Void`
07:59:45 chele joins (~chele@user/chele)
07:59:51 vglfr joins (~vglfr@88.155.170.213)
07:59:57 Nixkernal joins (~Nixkernal@115.16.194.178.dynamic.wline.res.cust.swisscom.ch)
08:02:49 <mauke> % type (¬) a = a -> Void
08:02:50 <yahb2> <interactive>:19:19: error: ; Not in scope: type constructor or class ‘Void’
08:03:21 <mauke> % data Void; type (¬) a = a -> Void
08:03:21 <yahb2> <no output>
08:03:49 <mauke> % id :: (¬) Int
08:03:49 <yahb2> <interactive>:23:1: error: ; • Couldn't match type ‘Int’ with ‘Void’ ; Expected: (¬) Int ; Actual: Int -> Int ; • In the expression: id :: (¬) Int ; In an equation for ‘...
08:04:08 <mauke> % id :: (¬) Void
08:04:08 <yahb2> <interactive>:25:1: error: ; • No instance for (Show ((¬) Void)) ; arising from a use of ‘Yahb2Defs.limitedPrint’ ; (maybe you haven't applied a function to enough arguments?) ;...
08:04:17 <mauke> % id :: (Void ¬)
08:04:17 <yahb2> <interactive>:27:14: error: parse error on input ‘)’
08:04:21 <mauke> ah
08:05:22 CiaoSen joins (~Jura@2a05:5800:282:6600:664b:f0ff:fe37:9ef)
08:05:52 Inst joins (~Inst@120.244.192.250)
08:06:06 dhruvasagar joins (~dhruvasag@49.207.194.211)
08:10:45 cfricke joins (~cfricke@user/cfricke)
08:15:30 mc47 joins (~mc47@xmonad/TheMC47)
08:17:01 × idgaen quits (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.0.5)
08:18:47 <albet70> is there a article about priority of operator?
08:19:40 <albet70> reverse <$> recv sock 1024 which is eval first?
08:21:29 × tzh quits (~tzh@c-71-193-181-0.hsd1.or.comcast.net) (Quit: zzz)
08:22:39 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:e1a3:648c:fb34:72ec) (Remote host closed the connection)
08:22:50 __monty__ joins (~toonn@user/toonn)
08:25:00 fendor joins (~fendor@2a02:8388:1640:be00:aab:1226:f274:5021)
08:25:21 Jackneill joins (~Jackneill@20014C4E1E0E6F00109B8E55CC0410BC.dsl.pool.telekom.hu)
08:25:23 <dminuoso> albet70: The evaluation order is unspecified in Haskell.
08:26:02 <dminuoso> I dont quite understand your question, however.
08:28:02 <albet70> reverse <$> recv sock 1024 is reverse <$> (recv sock 2014) or (reverse <$> recv) sock 1024?
08:28:16 <ncf> function application has the highest precedence
08:28:23 <ncf> so the former
08:29:34 <dminuoso> albet70: Evaluation order is different from operator precedence.
08:29:40 <dminuoso> Do not conflate these two.
08:30:34 <albet70> sendAll sock =<< reverse <$> recv sock 1024 is?
08:30:47 <dminuoso> albet70: So take a look at their hackage documentation
08:30:50 <dminuoso> Or use ghci with :i
08:30:54 <dminuoso> % :i (=<<)
08:30:54 <yahb2> (=<<) :: Monad m => (a -> m b) -> m a -> m b ; -- Defined in ‘GHC.Base’ ; infixr 1 =<<
08:30:58 <dminuoso> % :i (<$>)
08:30:59 <yahb2> (<$>) :: Functor f => (a -> b) -> f a -> f b ; -- Defined in ‘Data.Functor’ ; infixl 4 <$>
08:31:07 <dminuoso> =<< is right associative, with a precedence of 1
08:31:14 <dminuoso> <$> is left associative, with a predence of 4
08:31:42 <dminuoso> =<< binds more tightly
08:32:49 <mauke> record update is higher than function application
08:32:51 <dminuoso> Sorry my brain is exploding, I mislooked. <$> is of coure tighter because 4 is larger.
08:33:26 <dminuoso> albet70: operator predecence goes from 0 to 9, and function application (the space between a function and its argument) has a predence of 10 (so it binds more tightly than anything else)
08:33:43 <albet70> I can't find operator precedence on hackage, link please?
08:33:46 <dminuoso> And function application is left associative, which is why `foo x y z` associates as `((foo x) y) z`
08:34:04 <dminuoso> albet70: https://hoogle.haskell.org/?hoogle=(%3C$%3E)
08:34:16 <dminuoso> https://hackage.haskell.org/package/base-4.19.0.0/docs/Prelude.html#v:-60--36--62-
08:34:21 <dminuoso> See `infixl 4`
08:36:48 <albet70> I should just use ()
08:37:14 <albet70> () is more easy to use
08:37:19 <dminuoso> If you're unsure, yes, use explicit parenthesis.
08:39:01 <mauke> (recv sock >=> reverse >>> sendAll sock) 1042
08:39:48 <dminuoso> do { buf <- recv dsock; sendAll sock (reverse buf) }
08:39:50 <dminuoso> Im a sucker for simple.
08:40:20 <dminuoso> Its not meaningfully longer, but much easier to read.
08:40:33 <dminuoso> Especially in imperative code
08:41:28 <mauke> do (reverse -> fub) <- recv sock 4210; sendAll sock fub
08:42:28 danse-nr3_ joins (~francesco@151.37.109.164)
08:42:28 <dminuoso> Personally dont like it, because it requires changing reading directions multiple times when trying to follow the data flow *shrugs*
08:42:31 <dminuoso> But thats just me
08:43:21 <albet70> mauke , >>> is new to me, where it's from?
08:43:32 <jackdk> @hoogle (>>>)
08:43:32 <lambdabot> Control.Arrow (>>>) :: Category cat => cat a b -> cat b c -> cat a c
08:43:32 <lambdabot> Control.Category (>>>) :: Category cat => cat a b -> cat b c -> cat a c
08:43:32 <lambdabot> GHC.Desugar (>>>) :: forall arr . Arrow arr => forall a b c . arr a b -> arr b c -> arr a c
08:43:46 <jackdk> Control.Category is the canonical location IIRC
08:45:40 <dminuoso> Its just a generalization of a flipped (.)
08:46:13 <dminuoso> Maybe `do fub <- reverse <- recv sock 4210; ...` should be a thing.
08:46:40 <dminuoso> Seems a bit nicer than `(reverse -> fub) <- rev sock 4210 ...`
08:48:49 <albet70> flipped (.) is cool
08:49:23 hsw joins (~hsw@125-229-105-158.hinet-ip.hinet.net)
08:51:01 × ft quits (~ft@p4fc2a529.dip0.t-ipconnect.de) (Quit: leaving)
08:52:03 × hsw quits (~hsw@125-229-105-158.hinet-ip.hinet.net) (Client Quit)
08:52:32 × econo_ quits (uid147250@id-147250.tinside.irccloud.com) (Quit: Connection closed for inactivity)
08:52:33 × zer0bitz quits (~zer0bitz@user/zer0bitz) ()
08:53:10 <albet70> dminuoso , why you can use two <- in one line?
08:53:34 <dminuoso> You cant, I was just thinking it reads nice.
08:53:55 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:e1a3:648c:fb34:72ec)
08:55:17 <albet70> mauke , not easy to get the operator precedence in this >=>
08:57:47 zer0bitz joins (~zer0bitz@user/zer0bitz)
08:58:20 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:e1a3:648c:fb34:72ec) (Ping timeout: 248 seconds)
08:59:42 arahael joins (~arahael@119-18-2-212.771202.syd.nbn.aussiebb.net)
09:09:38 <albet70> \x -> f x >> g x could this use point free? f >> g?
09:10:15 <probie> @pl \x -> f x >> g x
09:10:15 <lambdabot> liftM2 (>>) f g
09:17:22 <albet70> is liftM2 equal liftA2?
09:18:07 <danse-nr3_> :t (>>)
09:18:08 <lambdabot> Monad m => m a -> m b -> m b
09:18:46 × hugo quits (znc@verdigris.lysator.liu.se) (Ping timeout: 255 seconds)
09:19:34 <dminuoso> albet70: liftM2 is constrained to Monad, liftAt to Applicative.
09:19:37 <dminuoso> Beyond that, yes.
09:20:13 <dminuoso> liftM2 merely exists because it was thought, there might be some Monad-only types that could provide a slightly more optimized version.
09:20:36 <dminuoso> It never really happened, the idea was floated to remove liftM2 - but the idea was forgotten.
09:20:52 <dminuoso> I just use liftA2.
09:21:39 <albet70> yes, I use liftA2 too
09:21:47 × stiell_ quits (~stiell@gateway/tor-sasl/stiell) (Remote host closed the connection)
09:22:11 stiell_ joins (~stiell@gateway/tor-sasl/stiell)
09:23:17 × Square quits (~Square@user/square) (Ping timeout: 246 seconds)
09:24:56 × ubert quits (~Thunderbi@77.119.205.197.wireless.dyn.drei.com) (Ping timeout: 255 seconds)
09:25:01 ubert1 joins (~Thunderbi@77.119.196.197.wireless.dyn.drei.com)
09:25:20 <probie> dminuoso: that sounds plausible, but it's not true. `liftM2` simply predates `Applicative`
09:25:55 <dminuoso> probie: It was discussed on various mailing lists with Simon Marlow a long time ago.
09:26:07 <dminuoso> Oh hold on.
09:26:25 <dminuoso> I might be confusing liftA2 with forM/traverse
09:26:30 × harveypwca quits (~harveypwc@2601:246:c280:6a90:837d:db39:3eea:f7db) (Quit: Leaving)
09:27:18 ubert1 is now known as ubert
09:28:07 <probie> you might still be right - it may not be defined as `liftM2 = liftA2` for the reason you've given, but the reason it exists in the first place is historical
09:29:09 <dminuoso> Fair.
09:36:09 × sm quits (~sm@plaintextaccounting/sm) (Quit: sm)
09:36:23 × Inst quits (~Inst@120.244.192.250) (Ping timeout: 260 seconds)
09:38:01 rosco joins (~rosco@yp-150-69.tm.net.my)
09:39:45 Inst joins (~Inst@120.244.192.250)
09:40:55 hugo joins (znc@verdigris.lysator.liu.se)
09:46:09 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:e1a3:648c:fb34:72ec)
09:52:05 × hugo quits (znc@verdigris.lysator.liu.se) (Ping timeout: 240 seconds)
09:55:09 × Sgeo quits (~Sgeo@user/sgeo) (Read error: Connection reset by peer)
09:59:06 hugo joins (znc@verdigris.lysator.liu.se)
10:01:22 × zer0bitz quits (~zer0bitz@user/zer0bitz) ()
10:05:43 × hugo quits (znc@verdigris.lysator.liu.se) (Ping timeout: 264 seconds)
10:07:11 × xff0x quits (~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp) (Ping timeout: 260 seconds)
10:12:37 × driib5 quits (~driib@vmi931078.contaboserver.net) (Quit: The Lounge - https://thelounge.chat)
10:13:15 driib5 joins (~driib@vmi931078.contaboserver.net)
10:16:29 hugo joins (znc@verdigris.lysator.liu.se)
10:30:51 kuribas joins (~user@ip-188-118-57-242.reverse.destiny.be)
10:32:27 × mc47 quits (~mc47@xmonad/TheMC47) (Remote host closed the connection)
10:38:19 lisbeths joins (uid135845@id-135845.lymington.irccloud.com)
10:41:15 × elkcl quits (~elkcl@broadband-95-84-226-240.ip.moscow.rt.ru) (Ping timeout: 255 seconds)
10:42:00 sm joins (~sm@plaintextaccounting/sm)
10:49:18 × danse-nr3_ quits (~francesco@151.37.109.164) (Ping timeout: 260 seconds)
10:49:22 NinjaTrappeur is now known as picnoir
10:49:50 Guest|99 joins (~Guest|99@152.57.210.157)
10:50:08 × Guest|99 quits (~Guest|99@152.57.210.157) (Client Quit)
10:50:21 [itchyjunk] joins (~itchyjunk@user/itchyjunk/x-7353470)
10:51:21 elkcl joins (~elkcl@broadband-95-84-226-240.ip.moscow.rt.ru)
10:55:43 × arahael quits (~arahael@119-18-2-212.771202.syd.nbn.aussiebb.net) (Ping timeout: 260 seconds)
10:59:24 arahael joins (~arahael@119-18-2-212.771202.syd.nbn.aussiebb.net)
11:04:26 Pickchea joins (~private@user/pickchea)
11:06:59 × euleritian quits (~euleritia@77.22.252.56) (Ping timeout: 255 seconds)
11:08:19 wib_jonas joins (~wib_jonas@business-37-191-60-209.business.broadband.hu)
11:09:06 × fendor quits (~fendor@2a02:8388:1640:be00:aab:1226:f274:5021) (Remote host closed the connection)
11:12:08 euleritian joins (~euleritia@dynamic-046-114-204-225.46.114.pool.telefonica.de)
11:14:57 zer0bitz joins (~zer0bitz@user/zer0bitz)
11:16:57 myxos joins (~myxos@cpe-65-28-251-121.cinci.res.rr.com)
11:21:00 × sm quits (~sm@plaintextaccounting/sm) (Quit: sm)
11:21:07 mikoto-chan joins (~mikoto-ch@ip-212-239-236-59.dsl.scarlet.be)
11:26:29 × CiaoSen quits (~Jura@2a05:5800:282:6600:664b:f0ff:fe37:9ef) (Ping timeout: 246 seconds)
11:26:38 × mikoto-chan quits (~mikoto-ch@ip-212-239-236-59.dsl.scarlet.be) (Ping timeout: 260 seconds)
11:29:27 × arahael quits (~arahael@119-18-2-212.771202.syd.nbn.aussiebb.net) (Ping timeout: 240 seconds)
11:32:38 Vajb joins (~Vajb@207.61.167.122)
11:34:57 nate2 joins (~nate@c-98-45-169-16.hsd1.ca.comcast.net)
11:39:39 × nate2 quits (~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 245 seconds)
11:41:42 <Inst> jesus christ, Nick sounds like he wants to get rid of polymorphic bind.
11:41:43 × euleritian quits (~euleritia@dynamic-046-114-204-225.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
11:42:00 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
11:43:07 <Inst> adding -XMonomorphicBind might be good as a GHC extension, though
11:44:02 <int-e> who where?
11:44:29 <Inst> forget it, someone we don't want to talk about, it's my other daily source of WTFs per minute
11:47:35 × jargon quits (~jargon@174-22-221-150.phnx.qwest.net) (Ping timeout: 255 seconds)
11:49:58 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Quit: = "")
11:55:20 danse-nr3_ joins (~francesco@151.37.109.164)
11:56:11 <kuribas> what's polymorphic bind?
11:56:20 <Inst> <- and >>=
11:57:00 <Inst> I like ideas like -XNamedLambdas, etc.
11:57:12 <kuribas> That's just "bind".
11:57:28 × Unicorn_Princess quits (~Unicorn_P@user/Unicorn-Princess/x-3540542) (Remote host closed the connection)
11:58:01 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 260 seconds)
11:58:06 <kuribas> And yes, it's polymorphic, since it requires a `Monad m` constraint.
11:58:22 <Inst> But it's polymorphic, i.e, bind is defined for a Monad m. A monomorphic bind would be, instead of (>>= :: Monad m => m a -> (a -> m b) -> m b), (>>=? :: Maybe a -> (a -> Maybe b) -> Maybe b)
11:58:45 <kuribas> and get rid of do-notation as well?
11:58:55 euleritian joins (~euleritia@dynamic-046-114-204-225.46.114.pool.telefonica.de)
11:59:13 × Pickchea quits (~private@user/pickchea) (Quit: Leaving)
11:59:40 <kuribas> why would anyone want to do that?
11:59:42 <Inst> Presumably not, because it'd align with his goals. This is really rubbernecking for me.
12:00:11 <Inst> I can accept return as a synonym for id
12:00:35 <Inst> because Haskell's polymorphism is confusing for newbies
12:01:08 califax joins (~califax@user/califx)
12:01:26 <Inst> This is the first time I've had a real yetch response since a doctor gave me an endoscopy without general anesthesia yesterday.
12:01:30 <Inst> :)
12:01:48 CiaoSen joins (~Jura@2a05:5800:282:6600:664b:f0ff:fe37:9ef)
12:02:11 <kuribas> Inst: then write in a dynamic language where you don't worry about types, and neither about runtime errors and good validation?
12:02:39 <Inst> tbh the proper solution is, imo, teach more about Haskell's type system and teach more carefully
12:03:11 <Inst> I can see why someone might want a monomorphic bind even if they're comfortable with Haskell's polymorphism, in order to more specify what's actually going on
12:03:17 <Inst> IIRC, that was why Rust rejected do notation
12:03:45 <kuribas> It sounds like a newbee who doesn't understand the language, but finds it necessary to comment on everything.
12:03:51 <kuribas> Not realising any of the implications.
12:03:59 <int-e> Inst: ...but if you don't want to talk about it then why did you mention it...
12:04:22 <Inst> i mean that others don't want to talk about it, it's mainly rubbernecking value right now
12:04:43 <int-e> Honestly the least you could do is actually link the source. (Or did I miss it in the scrollback?)
12:05:37 <Inst> it's on NH Discord, I took a visit to see what's happening right now, and, ummm
12:05:44 <kuribas> I can't care less about people claiming that haskell or static types are bad, then not showing any understanding of the language or theory.
12:06:34 <kuribas> I am more interested in *actual pain points* and *actual* ways to improve the language.
12:06:43 <Inst> https://media.discordapp.net/attachments/968989726633779215/1164897369595322490/image.png?ex=6544e237&is=65326d37&hm=3112db5ac685c1d5452de3e63d3d72cb61031635f63a7f98564ad73601fc6d1e&=&width=2880&height=1180
12:07:26 <Inst> This is... ummm, way too far for me
12:07:50 <kuribas> Inst: don't let him go near idris, there you can even overload '>>=' and do notation.
12:08:00 <kuribas> Haskell is still fairly conservative in that regards.
12:08:38 <kuribas> "Yesterday I spent ~3hrs with junior TS devs talking about <- and how it is similar to await in JS..."
12:08:43 <kuribas> That's the problem already.
12:08:49 <int-e> Oh I see, he only wants one fuzzy warm thing at a time.
12:09:06 <kuribas> problem 1) talking to junior TS devs about monads.
12:09:16 <kuribas> problem 2) talling them that <- is similar to await.
12:09:37 <int-e> It's a burrito!
12:09:46 <danse-nr3_> Inst, see, you upset kuribas :P
12:09:59 <kuribas> problem 3) being surprised that they are confused
12:09:59 <int-e> (This really is an instance of the monad tutorial fallacy.)
12:10:35 × califax quits (~califax@user/califx) (Remote host closed the connection)
12:10:48 <int-e> Inst: Anyway, thanks for the link, now I know what you were upset about.
12:10:51 califax joins (~califax@user/califx)
12:12:21 <kuribas> danse-nr3_: nah, I just had too much tea.
12:12:42 <Inst> kuribas: well, how would you feel about -XMonomorphicBind as a language extension, i.e, being able to stuff an operator or function next to <- to specify a specific monadic type?
12:12:53 <Inst> others have complained about nested do
12:12:55 <int-e> SCNR: Obviously the reason why you have to 'await' that `var 42` is lazy evaluation.
12:13:20 int-e times himself out.
12:13:21 <kuribas> Inst: I feel it's solving a problem that doesn't exist.
12:16:54 <moni> Yknow, I am exceedingly new to this (thus far I've only just gotten through the chapter on type classes from Haskell From First Principles, and I still have not gotten around to the category-theoretic parts of the language); but even with what little experience I have, I've found that the more I understand the type system, the easier it is for me to reason with the semantics of a given program
12:17:09 × Vajb quits (~Vajb@207.61.167.122) (Ping timeout: 245 seconds)
12:17:51 <kuribas> moni: there are no "category-theoretic parts" ;-)
12:18:01 <danse-nr3_> this neohaskell seems so detached from haskell that advocating for its ideas gets close to trolling
12:18:15 ahri joins (~ahri@164.39.15.195)
12:18:58 <danse-nr3_> i wonder whether it could end like java and javascript, with management thinking they had anything to do with each other
12:19:00 <kuribas> moni: but yeah, that is the idea :)
12:19:43 <Inst> tbh i sort of hope NH fails quickly at this point, because it's so divorced from Haskell, it's more like Nick coming up with weird ideas and field-testing them on the unsuspecting
12:19:55 <moni> I plead "exceedingly-new" in that respect kuribas ;) but yeah, I feel like most people who actively recoil from static typing simply do not understand how the type system works (and therefore don't understand how to reason with haskell code generally)
12:19:58 <Inst> he seems to be tilting toward _ `div` 0 = 0
12:21:39 xff0x joins (~xff0x@2405:6580:b080:900:c8ed:9e9f:452a:3637)
12:22:33 <int-e> moni: You can use concrete monads like IO or Maybe or Reader or State or the list monad without knowing any category theory. All you're missing out on is the naming, that is why it's called a monad.
12:22:58 × connrs quits (~connrs@user/connrs) (Read error: Connection reset by peer)
12:23:04 <kuribas> moni: not only that, they don't recognize how types can make you "more productive", instead of being there just to provide extra constraints.
12:24:07 <moni> int-e: ah that makes sense lol, thanks for the clarification
12:25:10 connrs joins (~connrs@user/connrs)
12:25:39 <Inst> kuribas: why say that types can make you more productive?
12:26:06 <Inst> One example I can think of is "Parse, don't validate"
12:26:15 <kuribas> for example, using typed holes.
12:26:17 <Inst> a dynamically typed language, you can give any function any input
12:26:19 <Inst> ah
12:26:40 <Inst> meaning, you'll have to code behavior if a function gets the wrong input type
12:26:47 <kuribas> And also refactoring dynamic code is a major pain in the **s.
12:27:24 <int-e> yeah, refactoring by chasing type errors tends to just work
12:27:56 <Inst> another thing I notice is that people working in dynamic types tend to be way too tolerant of exceptions
12:28:17 <kuribas> yeah, especially Python
12:28:25 <Inst> they also don't have a habit of trying to think through all possible inputs
12:28:35 <int-e> (static type checking covers all your code; with dynamic types you have to hope that you've covered all cases or get funny runtime behavior (hopefully just an error))
12:28:44 danse-nr3__ joins (~francesco@151.47.100.98)
12:28:50 <Inst> because if you try to do that, there are too many types to think through
12:29:39 × vglfr quits (~vglfr@88.155.170.213) (Read error: Connection reset by peer)
12:31:01 × danse-nr3_ quits (~francesco@151.37.109.164) (Read error: Connection reset by peer)
12:33:55 <int-e> Maybe this makes a good slogan: Every type error you fix is a bug you won't have to chase down later.
12:34:33 <kuribas> For me it's not just that. Types are also a way of expressing problems in an algebraic way.
12:35:06 <kuribas> It's the "algebraic way" of programming that IMO gives you code with low bug count.
12:35:07 <int-e> Absolutely, but I suspect that's hard to get across to somebody who hasn't used types much.
12:35:08 <Rembane> And documenting the expressed problems in a way that a computer can check.
12:35:55 <danse-nr3__> yeah it feels basically like embedded proof checking (excluding partial functions)
12:36:26 <int-e> Just like the fact that writing down a type for a function covers a significant part of the function's specification... easily said, but I'm not sure I would be convinced if I didn't have the first-hand experience.
12:37:06 <int-e> (refuting the idea that writing down type signatures is wasted effort)
12:37:52 <kuribas> IMO convincing someone to use types, if they don't already show some interest is impossible.
12:38:11 <Rembane> Indeed, TDD as in Typesomethingsomething is a very nice way of coding imo
12:43:06 <Inst> I wish someone would write an equivalent to Thinking with Types for Haskell98 or Haskell2010
12:43:59 <Rembane> Inst: Which version of Haskell is it written for?
12:44:17 <Inst> 2010 would be better, but implies 0 language extensions
12:44:29 <Inst> I think someone already wrote a paper trying to cover Haskell's type system, but it's not accessible
12:45:02 × euleritian quits (~euleritia@dynamic-046-114-204-225.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
12:45:20 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
12:47:52 × lisbeths quits (uid135845@id-135845.lymington.irccloud.com) (Quit: Connection closed for inactivity)
12:48:02 mikoto-chan joins (~mikoto-ch@ip-212-239-236-59.dsl.scarlet.be)
12:52:23 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
12:53:07 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
12:56:17 × ahri quits (~ahri@164.39.15.195) (Quit: Client closed)
12:57:38 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 260 seconds)
12:58:38 dcoutts joins (~duncan@ip-185-104-136-31.ptr.icomera.net)
12:59:40 euleritian joins (~euleritia@dynamic-046-114-204-225.46.114.pool.telefonica.de)
13:07:36 dcoutts_ joins (~duncan@ip-185-104-136-31.ptr.icomera.net)
13:08:43 × dcoutts quits (~duncan@ip-185-104-136-31.ptr.icomera.net) (Ping timeout: 260 seconds)
13:13:32 × Inst quits (~Inst@120.244.192.250) (Ping timeout: 255 seconds)
13:14:25 × rosco quits (~rosco@yp-150-69.tm.net.my) (Quit: Lost terminal)
13:17:48 L29Ah joins (~L29Ah@wikipedia/L29Ah)
13:24:02 × vpan quits (~vpan@212.117.1.172) (Quit: Leaving.)
13:24:12 vglfr joins (~vglfr@88.155.240.63)
13:26:13 cpressey joins (~cpressey@host-92-10-146-234.as13285.net)
13:29:19 Inst joins (~Inst@120.244.192.250)
13:36:07 × euleritian quits (~euleritia@dynamic-046-114-204-225.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
13:36:24 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
13:38:13 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
13:40:42 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
13:49:18 ahri joins (~ahri@164.39.15.195)
13:50:46 × dcoutts_ quits (~duncan@ip-185-104-136-31.ptr.icomera.net) (Ping timeout: 258 seconds)
13:52:02 × ahri quits (~ahri@164.39.15.195) (Client Quit)
13:52:32 ahri joins (~ahri@164.39.15.195)
13:56:16 × alphacentauri quits (alphacenta@gateway/vpn/protonvpn/alphacentauri) (Quit: WeeChat 4.1.0)
14:00:06 sabino joins (~sabino@user/sabino)
14:06:39 × ahri quits (~ahri@164.39.15.195) (Ping timeout: 248 seconds)
14:08:52 × megaTherion quits (~therion@unix.io) (Quit: ZNC 1.8.2 - https://znc.in)
14:10:02 megaTherion joins (~therion@unix.io)
14:11:53 × megaTherion quits (~therion@unix.io) (Client Quit)
14:13:02 megaTherion joins (~therion@unix.io)
14:16:36 Square joins (~Square@user/square)
14:18:00 econo_ joins (uid147250@id-147250.tinside.irccloud.com)
14:19:20 × megaTherion quits (~therion@unix.io) (Quit: ZNC 1.8.2 - https://znc.in)
14:20:26 megaTherion joins (~therion@unix.io)
14:21:05 thegeekinside joins (~thegeekin@189.180.124.118)
14:23:26 rgw joins (~R@2605:a601:a0df:5600:41e1:fde1:f907:ea46)
14:26:43 × xff0x quits (~xff0x@2405:6580:b080:900:c8ed:9e9f:452a:3637) (Ping timeout: 264 seconds)
14:28:29 xff0x joins (~xff0x@ai101218.d.east.v6connect.net)
14:28:57 gatekempt joins (~gatekempt@user/gatekempt)
14:31:51 ahri joins (~ahri@164.39.15.195)
14:33:28 × ahri quits (~ahri@164.39.15.195) (Client Quit)
14:35:56 × wib_jonas quits (~wib_jonas@business-37-191-60-209.business.broadband.hu) (Quit: Client closed)
14:38:09 danse-nr3__ is trying to read types as if they were documentation. That ought to be the haskell way
14:39:23 × thegeekinside quits (~thegeekin@189.180.124.118) (Ping timeout: 255 seconds)
14:39:29 dcoutts joins (~duncan@167.98.155.156)
14:40:21 × kuribas quits (~user@ip-188-118-57-242.reverse.destiny.be) (Remote host closed the connection)
14:41:24 thegeekinside joins (~thegeekin@189.180.124.118)
14:42:40 mc47 joins (~mc47@xmonad/TheMC47)
14:47:05 <Square> I'm working with "Validation" which is called a Monoidal sibling to Either. I wonder if its intentional its clumsy or if I lack basic knowledge on how to use it. Why doesn't it have practical things like "either" or "maybe" methods like Either resp Maybe has?
14:47:17 <Square> https://hackage.haskell.org/package/either-5.0.2/docs/Data-Either-Validation.html
14:49:37 <danse-nr3__> oh nice, i think i have been looking for this at times
14:49:54 <Square> Like, am I forced to do pattern match to convert "Success" to "Just"
14:51:22 <Rembane> Square: I think their idea is that you should use lenses or optics with this library.
14:52:16 <Square> Rembane, oh ok
14:52:22 sm joins (~sm@plaintextaccounting/sm)
14:52:26 <Rembane> Square: You can also use validationToEither the last thing in a validation and then use the Either functions
14:52:58 <ncf> preview _Success :: Validation e a -> Maybe a
14:53:08 <Square> ncf, nice!
14:56:19 × dcoutts quits (~duncan@167.98.155.156) (Ping timeout: 258 seconds)
15:05:37 phma_ joins (phma@2001:5b0:210f:118:12d5:66dc:e6c4:4af1)
15:06:16 × phma quits (~phma@host-67-44-208-191.hnremote.net) (Read error: Connection reset by peer)
15:09:32 × pavonia quits (~user@user/siracusa) (Quit: Bye!)
15:12:40 × b_jonas quits (~x@89.134.28.176) (Ping timeout: 252 seconds)
15:13:34 b_jonas joins (~x@89.134.28.176)
15:16:12 × cfricke quits (~cfricke@user/cfricke) (Quit: WeeChat 4.0.5)
15:18:40 Unicorn_Princess joins (~Unicorn_P@user/Unicorn-Princess/x-3540542)
15:20:22 <rgw> why convert it to Just? isn't a Right result of a validation already signifying success?
15:20:37 kuribas joins (~user@ip-188-118-57-242.reverse.destiny.be)
15:21:43 yoyofreeman joins (~yoyofreem@176.97.76.178)
15:25:56 <danse-nr3__> good question actually
15:26:19 <danse-nr3__> probably to integrate with other Maybe functions
15:28:55 Pozyomka joins (~pyon@user/pyon)
15:29:24 × chele quits (~chele@user/chele) (Remote host closed the connection)
15:29:51 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
15:30:41 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
15:32:43 × danse-nr3__ quits (~francesco@151.47.100.98) (Ping timeout: 255 seconds)
15:33:20 Tuplanolla joins (~Tuplanoll@91-159-68-236.elisa-laajakaista.fi)
15:35:01 <Square> rgw, Just thought I'd get rid of the Failure info as it plays no role in the context I work. Sure, its one application away, but yeah just wanted to get as ergonomical as possible.
15:36:27 nate2 joins (~nate@c-98-45-169-16.hsd1.ca.comcast.net)
15:37:28 × mikoto-chan quits (~mikoto-ch@ip-212-239-236-59.dsl.scarlet.be) (Ping timeout: 260 seconds)
15:41:12 × vglfr quits (~vglfr@88.155.240.63) (Read error: Connection reset by peer)
15:41:29 × nate2 quits (~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 255 seconds)
15:41:33 vglfr joins (vglfr@gateway/vpn/protonvpn/vglfr)
15:42:10 danse-nr3__ joins (~francesco@151.47.100.98)
15:44:18 <kuribas> WHy is fastCGI so unpopular? Doesn't it make sense to interface with established webservers?
15:46:51 Simikando joins (~Simikando@adsl-dyn158.91-127-59.t-com.sk)
15:47:13 nickiminjaj joins (~nickiminj@188.146.126.78)
15:47:13 × nickiminjaj quits (~nickiminj@188.146.126.78) (Changing host)
15:47:13 nickiminjaj joins (~nickiminj@user/laxhh)
15:49:48 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:e1a3:648c:fb34:72ec) (Remote host closed the connection)
15:50:04 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:e1a3:648c:fb34:72ec)
15:51:14 <geekosaur> maybe just its name? "CGI" sounds like 90s tech
15:51:57 <danse-nr3__> oh gosh haven't heard about CGI (nor fastCGI) in a long time. I thought it was a nice protocol. Maybe the serialization/deserialization is too much overhead and embedding the server in the app became more popular?
15:55:15 <EvanR> ruby on rails killed fastCGI because ruby is so slow fastCGI on top of that was so much worse. So they rewrote how web works to account for how inefficient ruby is
15:55:38 <danse-nr3__> also not sure how CGI would work with persistent connections like websockets
15:55:43 <EvanR> now everyone thinks the web app needs to be integrated with the webserver regardless of language
15:56:19 <kuribas> EvanR: you mean because the fastCGI library was pure Ruby?
15:57:14 × Simikando quits (~Simikando@adsl-dyn158.91-127-59.t-com.sk) (Ping timeout: 255 seconds)
16:00:16 <c_wraith> so... CGI died because it wasn't good at global resource limits, like a database connection pool. It turns out launching a new process for every request just is awkward for performing coordination between requests.
16:00:33 <kuribas> c_wraith: hence... fastCGI?
16:00:48 <kuribas> It doesn't launch a new process for each request.
16:01:39 <geekosaur> fastCGI was the first attempt to make CGI usable. it wasn't good enough
16:02:35 <kuribas> why not?
16:03:16 <c_wraith> amusingly, rails sort of reinvented fastCGI with rack
16:03:32 × sm quits (~sm@plaintextaccounting/sm) (Quit: sm)
16:03:35 <EvanR> fastCGI is still a viable way to set it up, but being web tech the popularity is based entirely on whims and not technicals
16:03:57 <EvanR> the users don't care what you used in the backend as long as it works
16:04:20 <EvanR> the rails scene reinvented a lot of that stuff
16:04:25 <EvanR> then elixir reinvented it again
16:04:31 <EvanR> the story continues
16:05:07 <EvanR> I saw one startup trying to reinvent it all in rust, then later changing their mind (regaining their sanity?)
16:05:14 <c_wraith> staying in-process is an easy way to get a big performance boost
16:05:36 <c_wraith> Not having to serialize and parse the data is an easy win on small requests
16:06:38 × machinedgod quits (~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 260 seconds)
16:07:51 <c_wraith> even in the middle-early days, staying in-process was cool. apache's mod_php ran PHP code directly instead of sending data to an external process.
16:11:02 × EvanR quits (~EvanR@user/evanr) (Remote host closed the connection)
16:11:57 EvanR joins (~EvanR@user/evanr)
16:12:25 wib_jonas joins (~wib_jonas@business-37-191-60-209.business.broadband.hu)
16:12:54 tzh joins (~tzh@c-71-193-181-0.hsd1.or.comcast.net)
16:13:26 Vajb joins (~Vajb@207.61.167.122)
16:14:36 <kuribas> man, http benchmarks are such lies, higher just means it implements less of the spec, IMO...
16:14:51 <SrPx> using PHOAS, is it possible to normalize a term and then stringify the normal form? I see PHOAS usually implements norm as `eval :: Exp t -> t` rather than `eval :: Exp t -> Exp t` so it isn't clear to me how to quote the result. ref https://mail.haskell.org/pipermail/haskell-cafe/2008-November/050768.html
16:15:36 <SrPx> complete file: https://gist.github.com/VictorTaelin/7d3b8b1cd6c400dfd9ff8ade1336f135
16:16:15 × kuribas quits (~user@ip-188-118-57-242.reverse.destiny.be) (Remote host closed the connection)
16:18:21 Simikando joins (~Simikando@adsl-dyn158.91-127-59.t-com.sk)
16:21:44 × Vajb quits (~Vajb@207.61.167.122) (Ping timeout: 245 seconds)
16:22:26 <EvanR> you should be able to stringify any expression, right
16:29:11 danse-nr3_ joins (~francesco@151.43.109.173)
16:29:13 × danse-nr3__ quits (~francesco@151.47.100.98) (Read error: Connection reset by peer)
16:31:27 <SrPx> EvanR: yes, but eval doesn't return an expression, but rather just `t`
16:31:49 <SrPx> so unless I'm missing something obvious there is no way to normalize a λ-term and print its normal form with PHOAS?
16:31:51 phma_ is now known as phma
16:31:55 <SrPx> moved this question to SO https://stackoverflow.com/questions/77332495/is-it-possible-using-phoas-to-evaluate-a-term-to-normal-form-and-then-stringi
16:44:29 × vglfr quits (vglfr@gateway/vpn/protonvpn/vglfr) (Ping timeout: 255 seconds)
16:45:02 waleee joins (~waleee@2001:9b0:21c:e600:f2f3:f744:435d:137c)
16:45:19 vglfr joins (~vglfr@88.155.240.63)
16:47:49 × poscat quits (~poscat@user/poscat) (Quit: Bye)
16:48:05 × CiaoSen quits (~Jura@2a05:5800:282:6600:664b:f0ff:fe37:9ef) (Ping timeout: 255 seconds)
16:52:06 poscat joins (~poscat@user/poscat)
16:53:48 × Simikando quits (~Simikando@adsl-dyn158.91-127-59.t-com.sk) (Ping timeout: 272 seconds)
16:57:19 × cpressey quits (~cpressey@host-92-10-146-234.as13285.net) (Quit: Client closed)
16:59:53 Simikando joins (~Simikando@adsl-dyn158.91-127-59.t-com.sk)
16:59:54 × nickiminjaj quits (~nickiminj@user/laxhh) (Read error: Connection reset by peer)
17:00:40 dcoutts joins (~duncan@212.187.244.65)
17:03:48 × vglfr quits (~vglfr@88.155.240.63) (Ping timeout: 240 seconds)
17:03:58 × thegeekinside quits (~thegeekin@189.180.124.118) (Ping timeout: 258 seconds)
17:04:55 AlexNoo_ joins (~AlexNoo@178.34.162.116)
17:06:55 × dcoutts quits (~duncan@212.187.244.65) (Ping timeout: 264 seconds)
17:07:21 × AlexZenon quits (~alzenon@178.34.161.78) (Ping timeout: 255 seconds)
17:08:34 × AlexNoo quits (~AlexNoo@178.34.161.78) (Ping timeout: 255 seconds)
17:08:47 Vajb joins (~Vajb@207.61.167.122)
17:10:49 × Vajb quits (~Vajb@207.61.167.122) (Read error: Connection reset by peer)
17:10:52 thegeekinside joins (~thegeekin@189.180.124.118)
17:11:01 Vajb joins (~Vajb@207.61.167.122)
17:12:56 × Simikando quits (~Simikando@adsl-dyn158.91-127-59.t-com.sk) (Ping timeout: 255 seconds)
17:14:15 × wib_jonas quits (~wib_jonas@business-37-191-60-209.business.broadband.hu) (Quit: Client closed)
17:15:56 paddymahoney joins (~paddymaho@cpe883d24bcf597-cmbc4dfb741f80.cpe.net.cable.rogers.com)
17:17:22 ft joins (~ft@p4fc2a529.dip0.t-ipconnect.de)
17:17:59 AlexNoo_ is now known as AlexNoo
17:18:23 × danse-nr3_ quits (~francesco@151.43.109.173) (Ping timeout: 260 seconds)
17:20:21 alphacentauri joins (alphacenta@gateway/vpn/protonvpn/alphacentauri)
17:21:10 <exarkun> Anyone have any suggestions for learning Hakyll? The project tutorial isn't doing much for me.
17:21:21 danse-nr3_ joins (~francesco@151.43.109.173)
17:21:44 AlexZenon joins (~alzenon@178.34.162.116)
17:26:58 × danse-nr3_ quits (~francesco@151.43.109.173) (Ping timeout: 258 seconds)
17:30:14 Sgeo joins (~Sgeo@user/sgeo)
17:34:26 × Vajb quits (~Vajb@207.61.167.122) (Ping timeout: 255 seconds)
17:39:12 <[exa]> exarkun: I started learning it and then wrote my own version with a few functions (like directory sourcing) from hakyll + plain pandoc
17:39:32 <[exa]> exarkun: anyway yeah the docs ain't super illustrative, just reading the source helps a lot there
17:43:10 dcoutts joins (~duncan@ip-185-104-136-51.ptr.icomera.net)
17:48:20 × hugo quits (znc@verdigris.lysator.liu.se) (Quit: ZNC 1.8.2 - https://znc.in)
17:51:56 lortabac joins (~lortabac@185.238.219.14)
17:52:54 nickiminjaj joins (~nickiminj@188.146.126.78)
17:52:54 × nickiminjaj quits (~nickiminj@188.146.126.78) (Changing host)
17:52:54 nickiminjaj joins (~nickiminj@user/laxhh)
17:53:56 × alphacentauri quits (alphacenta@gateway/vpn/protonvpn/alphacentauri) (Quit: WeeChat 4.1.0)
17:54:15 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:e1a3:648c:fb34:72ec) (Remote host closed the connection)
17:54:57 qqq joins (~qqq@92.43.167.61)
17:58:59 Guest86 joins (~Guest86@14.139.128.51)
18:02:05 <Guest86> Hi
18:02:15 <Guest86> In haskell, how do we deal with subtypes?
18:02:38 <Guest86> say, `data Day = Mon | Tue ... | Sun`
18:02:59 <Guest86> how would I define `data Weekend = Sat | Sun`?
18:03:10 <EvanR> haskell doesn't have subtypes
18:03:42 <EvanR> but you can define a Weekend type which maps to Day if you want, it just requires applying a function
18:04:38 <EvanR> then granular code which requires a Weekend can have the proper type
18:05:28 <EvanR> to go backwards, Day to Weekend, you can use a "smart constructor" which is a function of type Day -> Maybe Weekend
18:05:29 nucranium joins (~nucranium@2a02:8010:6173:0:7d81:65c5:a598:8bba)
18:05:33 <rgw> wouldn't weekend be [Sat, Sun]?
18:05:59 <Guest86> rgw we can't use it as a type right?
18:06:04 <EvanR> subsets vs subtypes
18:06:27 <EvanR> [Sat, Sun] is a sort of subset
18:06:36 <Inst> What is wrong with
18:06:36 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
18:06:48 euleritian joins (~euleritia@77.22.252.56)
18:06:56 <Inst> data Day = WeekdayDay Weekday | WeekendDay Weekend
18:06:57 <rgw> well, i mean Weekend = Sat | Sun would be either Sat or Sun
18:07:04 × thegeekinside quits (~thegeekin@189.180.124.118) (Ping timeout: 255 seconds)
18:07:08 <Inst> I'm guessing that's the naive solution
18:07:13 thegeekinside joins (~thegeekin@189.180.4.84)
18:07:20 <rgw> that seems more like a function like isWeekday
18:07:24 <EvanR> you can do that but I don't think it'll be generally useful
18:07:41 <EvanR> splitting the Day type up
18:07:52 <Inst> Ergonomics feel terrible.
18:08:00 <rgw> i guess you could implement it as a weekendable
18:08:04 <EvanR> the next feature that comes along might require you split it up again, or worse, in a different way
18:08:24 <EvanR> weekendable type class? That's almost certain even worse
18:08:36 <Inst> but splitting the type afaik is the only way to get total sum types, by not being a sum type
18:08:42 <Guest86> EvanR thanks. I will have to define weekend as `data Weekend = Sat' | Sun'` and then write a function to go from Weekend to Day right?
18:08:50 <EvanR> Inst the first thing I said was "total"
18:09:13 <rgw> why does it even have to be a type?
18:09:15 <EvanR> Guest86, you can use the same constructor names if you want, in a different module
18:10:12 <EvanR> Guest86, yeah you have an embedding function from Weekend to Day which always works. And this gets the classic feature of promoting OOP subclasses to the superclass
18:10:21 <EvanR> just not implicitly
18:11:34 <EvanR> this is all hypothetical I assume, because we might have actual good advice for a concrete problem
18:11:44 <Inst> ummm, where did you say total?
18:11:46 <EvanR> that's totally different
18:11:56 <EvanR> Inst, why do you think it's not total
18:12:13 <Guest86> EvanR we can't define multiple modules in the same file right?
18:12:13 <Inst> I was talking about splitting a type up
18:12:20 <EvanR> Guest86, correct
18:12:22 <Inst> since partial records are notorious, no?
18:12:48 <EvanR> records in sum types has nothing to do with any of this
18:14:01 jargon joins (~jargon@174-22-221-150.phnx.qwest.net)
18:15:02 <Inst> What are the benefits of not having subtyping?
18:15:22 <EvanR> subtyping is very complex to use and implement
18:15:34 <rgw> probably messes with type inference
18:15:40 <Guest86> rgw for an use case, say I want to define a function : `validPartyDates :: [(Int, Day)] -> [(Int, Weekend)]`
18:15:43 <EvanR> or, because no one who really liked it was present when haskell was designed
18:16:47 <rgw> you can't just pattern match on sat and sun?
18:17:31 <EvanR> that type is totally valid, very precisely typed
18:17:46 <EvanR> you will find increasing the precision of your types sometimes results in a lot of work
18:18:02 <EvanR> but if the logic is sound, at least there's that
18:18:06 <rgw> i don't really see the benefit of having a specific weekend type
18:18:10 Simikando joins (~Simikando@adsl-dyn158.91-127-59.t-com.sk)
18:18:24 <EvanR> well, you know Guest86's function only returns weekends from looking at the type
18:18:24 × bastelfreak quits (bastelfrea@libera/staff/VoxPupuli.bastelfreak) (Quit: WeeChat 4.0.0)
18:18:30 machinedgod joins (~machinedg@d198-53-218-113.abhsia.telus.net)
18:18:39 <Guest86> Yeah '=D
18:18:40 <rgw> well, weekenddays
18:19:06 <rgw> not knowing the implementation, weekend would imply to me that it would be two days
18:19:26 <EvanR> the name Day is also the name of the calendar date type in Data.Time
18:19:45 <EvanR> so the names of these types might need review, but as it stands it's correct code
18:20:25 <Inst> you can probably run a filter via (\(_,date) -> date `elem` [Saturday, Sunday]), then map to convert the Days to members of the Weekend datatype
18:20:32 <rgw> validpartydates already tells me it does validification
18:21:01 <Inst> actually, date should be day, but small typo
18:21:28 <Inst> it's actually a bit more convenient since map on 2-tuples gets you access to the second data type
18:21:30 <EvanR> names are good, but packing types, documentation, and whatever else into the variable names is the realm of ruby, python, php
18:21:53 <Inst> because you don't have types to describe your data and functions
18:22:25 <Inst> you can also write the boolean check in point free
18:22:32 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:e1a3:648c:fb34:72ec)
18:22:33 <EvanR> Inst, you're assuming validPartyDates does something specific, filtering out anything that's not a weekend
18:22:44 <EvanR> who knows what valid means here
18:23:07 <Inst> Well, it's Weekend, not (Maybe Weekend)
18:23:08 <moni> Weekend would imply to you that Weekend is 2 days ... unless you're a weirdo (me) who thinks of Friday as part of the weekend
18:23:25 <EvanR> Inst, list can be considered a kind of option type, empty means failure
18:23:28 <rgw> i mean that's valid, maybe weekends differ by region
18:23:38 <rgw> totally not futureproof if we colonize mars
18:23:58 <Inst> yes, Maybe is isomorphic to a lists of up to 1 member
18:24:01 <EvanR> naming aside, the "not subtype" pattern is sound
18:25:33 <Inst> as an example, what else could valid mean?
18:25:40 <Guest86> Is there anywhere I can see examples of handling such cases? That is handling subtypes in haskell way?
18:25:45 <Inst> ah, you're right, it could also consider other exclusions
18:25:54 <Guest86> Int and Integer are both instances of Enum class right?
18:25:58 <Inst> for example, it could have a holiday register involved
18:26:06 <Guest86> and both of them have the same constructors
18:26:06 <geekosaur> or handle long weekends so Monday sometimes counts, etc.
18:26:09 <geekosaur> that
18:26:27 <EvanR> Guest86, numerics is a great place to show how subtypes often don't apply when people think they do
18:26:28 <geekosaur> there's compiler magic involved there
18:26:32 <geekosaur> :t 1
18:26:32 <lambdabot> Num p => p
18:26:40 <geekosaur> :t fromInteger
18:26:41 <lambdabot> Num a => Integer -> a
18:26:55 <Inst> Memorial Day in the United States is always a Monday, right?
18:27:03 <EvanR> Guest86, for example, in many languages you are told that Int is a subtype of Double, but it's not even a subset. Or vice versa
18:27:08 <rgw> is that still technically a weekend though?
18:27:32 <geekosaur> `1` is compiled as `fromInteger (1 :: Integer)` where the `1 :: Integer` is directly compiled in
18:27:42 [exa] still not convinced that human calendar systems are more decidable than halting
18:27:51 <geekosaur> Inst, there are 6 Monday holidays in the US
18:28:02 <rgw> alternatively, every day is a party day
18:28:03 <geekosaur> Memorial Day is one of them
18:28:25 <rgw> how did we get from weekend days to holidays?
18:28:42 <Inst> ? @geekosaur?
18:28:43 <geekosaur> [20 18:25:58] <Inst> for example, it could have a holiday register involved
18:28:48 <Inst> https://www.usa.gov/holidays
18:28:54 <EvanR> Guest86, type classes are a way to say you will accept any type which supports a certain uniform interface. But there are other ways to get the same thing. And this isn't actually a subtyping thing.
18:29:06 <geekosaur> (also that's complicated by the fact that not all of them are given as days off to most people)
18:30:01 <EvanR> so you might be looking for that uniform interface pattern, instead of subtyping. Where in OOP there was an attempt to conflate them
18:30:06 <geekosaur> yes. holidays are complex but there are 6 holidays which by law are placed on Mondays
18:30:16 <Guest86> I will try out my use case with typeclasses and come back here to confirm if my solution is a good way '=D
18:30:25 <monochrom> (And then laws are complicated, too. >:) )
18:30:27 <EvanR> what is the uniform interface to weekends?
18:30:30 <Inst> what is the 6th holiday? I only see 5 federal holidays on monday?
18:30:36 <EvanR> er, days / weekdays
18:30:40 <rgw> that's why i joked weekendable
18:30:44 <EvanR> I think your goals need to be fleshed out
18:30:54 <monochrom> Uniform interface to weekdays: :(
18:30:57 <rgw> it's funny how haskell actually makes you think really hard about this
18:31:05 <monochrom> Uniform interface to weekends: \o/
18:31:34 <EvanR> rgw, the time library is surprisingly cogent on the subject of time keeping, it's kind of a relief
18:31:41 <rgw> but what if a weekday is also pizzaday?
18:31:49 <geekosaur> hm, right, I'm confused
18:31:55 <monochrom> Joke among theoretical physicists: Scheduling a meeting on a Wednesday ruins both weekends. :)
18:32:18 <moni> so real
18:33:59 <Inst> @ geekosaur
18:34:01 <Inst> no, I'm confused
18:34:02 <Inst> https://vivacf.net/us-bank-holidays-list-and-description/
18:34:20 <rgw> who says this is for the us?
18:34:41 × dcoutts quits (~duncan@ip-185-104-136-51.ptr.icomera.net) (Ping timeout: 260 seconds)
18:34:52 <EvanR> the 7 day cycle predates the gregorian and julian calendars
18:34:52 <Inst> nope, indigenous people's day overlaps with columbus day?
18:36:38 <geekosaur> yes. think about it
18:36:57 <geekosaur> it was the start of wiping out North America's indigenous people
18:37:21 <EvanR> validPartyDays = interleave [today ..] [yesterday, yesterday - 1 ..]
18:37:23 <geekosaur> rgw, this started as a side discussion
18:37:29 × nickiminjaj quits (~nickiminj@user/laxhh) (Read error: Connection reset by peer)
18:37:33 <rgw> could have just called it discovery day
18:37:40 <geekosaur> which I set off by pointing out that in the US some weekends extend through Monday
18:37:49 <Inst> ehh, #haskell-offtopic
18:38:03 <Inst> since this is pretty brutal politics
18:38:09 <geekosaur> presumably it'll change in the future; see the history of some of the other holidays on the list
18:38:30 <rgw> isn't that more of a problem that *weekend* doesn't have a specific definition?
18:39:12 <geekosaur> well, yes. isn't there a 4 day work week in at least some parts of europe?
18:39:28 <EvanR> they literally defined Weekend specifically as Sat | Sun
18:39:42 <rgw> doesn't mean it's right
18:39:44 <EvanR> lol
18:39:52 <EvanR> wrong definitions
18:39:59 <[exa]> friday ain't weekend?
18:40:21 <EvanR> we shall not write any haskell code which contradicts the truth
18:40:24 cpressey joins (~cpressey@host-92-10-146-234.as13285.net)
18:40:39 <Inst> How would dependent types factor into this?
18:40:43 <EvanR> lol
18:40:52 <geekosaur> there's a "what programmers get wrong about weekends" hiding somewhere in here
18:41:09 <Inst> I guess, you could also use phantom types
18:41:16 × nucranium quits (~nucranium@2a02:8010:6173:0:7d81:65c5:a598:8bba) (Ping timeout: 248 seconds)
18:41:17 <rgw> "all i wanted to do is to party"
18:41:34 <EvanR> in this channel, it's already the weekend apparently
18:42:29 <Inst> I guess you could use GADTs with phantom typing, i.e, Monday :: Day Weekday
18:42:55 <rgw> we still don't know what the specific application for this is
18:43:32 <rgw> for a general partyday validation i would imagine you'd check for holidays too
18:43:53 <rgw> if it's only weekend days, do you really need to put all this typing in the back?
18:44:05 <monochrom> <monochrom> (And then laws are complicated, too. >:) )
18:45:34 hiyori joins (~hiyori@user/hiyori)
18:45:52 × lortabac quits (~lortabac@185.238.219.14) (Quit: WeeChat 2.8)
18:46:04 <Inst> how would you be able to stuff Day Weekday and Day Weekend into the same list, though?
18:46:33 pavonia joins (~user@user/siracusa)
18:48:08 <EvanR> who cares
18:48:15 <EvanR> don't do that
18:49:21 <EvanR> keep your haskell simple unless the complicated version is actually right and actually helpful
18:50:54 <Inst> I guess I don't understand the need for a Weekday or Weekend type.
18:53:38 × mc47 quits (~mc47@xmonad/TheMC47) (Remote host closed the connection)
18:54:08 <EvanR> it's more of a "can do" than "is needed"
18:54:30 <EvanR> modal logic?
18:57:27 <Inst> But for the stuffing Day Weekday and Day Weekend into the same list, [Either (Day Weekday) (Day Weekend)]
18:57:34 <Inst> woefully unergonomic
18:59:32 <Inst> type a || b = Either a b is slightly better -> [ Day Weekday || Day Weekend ]
18:59:49 <rgw> i wouldn't use either for that
19:00:07 <Inst> What would you use instead?
19:00:09 <EvanR> you can already include any weekday in the same list.... [Weekday]
19:00:20 <rgw> just Day = Weekend | Weekday
19:00:49 <EvanR> no
19:01:13 <monochrom> newtype Day = Day Int >:)
19:01:29 <Inst> Yeah, sorry, I don't really have much experience with typelevel, and I'm suspecting the reason typelevel can often go badly is because it's used by people using it for the novelty factor, not because there's an actual need for its use, hence lack of experience
19:01:40 <monochrom> then just have a lot of smart constructors, smart predicates, and smart pattern synonyms.
19:02:22 <rgw> i stilll fail to see the whole application of this
19:03:25 <monochrom> Without loss of specificity, you can ask: If weekday values and weekend values have different types, how to put both in the same list. The answer is then existential type to cover both. Without loss of generality, an existential type with only finitely many cases is a sum type, so Either was a good example.
19:03:28 <int-e> . o O ( Day = Leap | Standard )
19:04:45 <Inst> I still annoyed someone by asking for data inference removing the need to use data / type / newtype keywords
19:05:24 <Inst> so you could declare Day = Leap | Standard, and GHC would infer that, because you're defining what looks like a sum type, you mean a data declaration
19:05:26 <EvanR> yeah that's pretty annoying
19:05:37 <EvanR> do what I mean not what I say design
19:06:01 <EvanR> newtypes and data types do different things, there's no way to know what you wanted
19:06:27 <EvanR> same for aliases
19:06:31 <Inst> you could have it default to newtype for any Foo a = MkFoo a declaration
19:06:43 <rgw> does that actually matter though?
19:06:54 <EvanR> yes, one is lifted one isn't
19:07:05 <monochrom> Actually I would agree with that with a change: Add one more keyword "autoInferDataOrNewtype" for the auto version.
19:07:27 <rgw> i thought the only differences were that it's more efficient for the compiler to use newtype when you only have one constructor
19:07:42 <monochrom> Because I still want the freedom to say "data X = X Int" and yes I deliberately want X bottom /= bottom.
19:07:48 <EvanR> one is lifted, one isn't
19:08:04 <EvanR> which in some code can lead to a difference of working or freezing up
19:08:30 <Inst> yeah, i know some guy got really pissed off over that, when using newtype broke his attempt to tie the knot on his first project
19:08:50 <Inst> which is why cramming Haskell for 3 months before your first project isn't such a good idea
19:08:58 <EvanR> imagine if that guy also didn't know which thing he was even specifying because you deleted the syntax xD
19:09:03 <monochrom> Well, conversely, there was a time I changed "newtype" to "data" and that broke my recursion. :)
19:09:31 <Inst> EvanR: I was more thinking of it as an additional feature, keeping the traditional data / newtype / type keywords
19:09:37 <Inst> it'd break punning, though
19:09:44 <rgw> weird, the way i've seen newtype explained is it's type but you can use it with classes
19:09:48 <monochrom> So I would agree if both an auto way and a manual way were offered. Don't remove the manual way.
19:09:59 <Inst> i guess i'm thinking too operationally
19:10:26 <Inst> afaik newtype doesn't actually exist at compile-time, it's just a way to tell the compiler to treat values of the type as a separate type
19:10:27 <EvanR> Inst, now you need to take a warning from javascript, where "just make more code do something instead of error" leads to less ability for the compiler to tell you you messed up.
19:10:36 <rgw> and to prefer newtype when you just have one constructor for purely performance reasons
19:10:37 <EvanR> or anything-goes HTML
19:11:04 <geekosaur> newtype is a figment of the typechecker
19:11:29 <EvanR> rgw, if it was purely performance, then it would have just been an optimization and not controllable
19:11:33 <Inst> what do you mean by newtype is unlifted, btw?
19:11:51 <geekosaur> X undefined /= undefined
19:11:56 <rgw> hence why there is the confusion, i'm guessing
19:11:59 <Inst> when you're talking data
19:12:01 <geekosaur> sorry, it == undefined for newtype
19:12:10 <monochrom> Consider "newtype N = N Int" and "data D = D Int". N bottom = bottom, D bottom /= bottom.
19:12:11 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:e1a3:648c:fb34:72ec) (Read error: Connection reset by peer)
19:12:16 <geekosaur> for data, X undefined /= undefined
19:12:24 × cpressey quits (~cpressey@host-92-10-146-234.as13285.net) (Quit: Client closed)
19:12:25 <Inst> yeah, data X a = X a; X undefined /= undefined
19:12:26 <EvanR> Inst, it means not lifted. So you are asking what is lifted right. Int is a lifted type, it's the set of machine ints plus bottom
19:12:42 <monochrom> And then there is something more subtle to tell why "data S = S !Int" is still different from N. >:D
19:12:44 <Inst> is the literal definition of lifted implying that it includes bottom?
19:13:20 <EvanR> an additional bottom on top of whatever was already there
19:13:26 <EvanR> which doesn't happen with newtypes
19:13:33 <monochrom> "lifting" means one more bottom, in mathematical contexts.
19:14:08 <monochrom> there is also a meaning in operational contexts, consistent with the math meaning
19:14:44 <monochrom> Int already has its bottom. D adds one more underneath.
19:14:52 <rgw> so why would you use newtype over data?
19:15:12 <EvanR> when you want to clone a type exactly, but make sure it's a new type
19:15:23 <EvanR> and without any of its instances
19:15:40 <Inst> I tried with ghci, but I couldn't validation of this behavior
19:15:44 <geekosaur> the usual intent is to copy through via GND the original type's instances, then replace one or more of them
19:15:46 <monochrom> When I have "newtype Temperature = T Int" for an easier-to-make-safe temperature type, so I don't need one more bottom.
19:15:49 <Inst> newtype Foo a = MkFoo a
19:15:56 <Inst> undefined is a member of Foo a
19:16:23 <geekosaur> no, undefined is a member of a
19:16:26 <Inst> oh, I'm being stupid
19:16:29 <monochrom> When I have "newtype Parser a = P (String -> [(a, String)])". Dude, I already have enough bottoms from the function space, I don't need one more bottom.
19:16:39 <geekosaur> you cannot habe an undefined in place of a `MkFoo a`
19:16:51 <Inst> ghci is accepting undefined :: Foo a
19:17:21 <EvanR> yeah bottom :: MkFoo a
19:17:28 <EvanR> MkFoo bottom isn't one of them
19:17:33 <monochrom> Conversely, I would be more hard pressed to give a good use case for D.
19:17:36 <Inst> umm, it won't accept MkFoo because it's not a type
19:17:50 <EvanR> oops
19:18:13 <monochrom> I mean, apart from teaching my course in which I don't want to spend time explaining newtype so I stick to data. :)
19:18:35 <geekosaur> if you specify undefined in place of MkFoo 1 it fires as soon as it's touched (it's strict instead of lazy)
19:18:44 × euleritian quits (~euleritia@77.22.252.56) (Read error: Connection reset by peer)
19:18:47 <monochrom> The purpose of the course is not really Haskell, so I couldn't care less about the benefit of newtype.
19:18:56 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
19:19:10 <EvanR> Inst, as an example where undefined won't work, look at Int#
19:19:17 <EvanR> Int# has no bottoms
19:19:24 <Inst> yeah, i know, because it has a...
19:19:33 <EvanR> because it's not lifted
19:19:45 <EvanR> and it's the wrong kind
19:19:58 <monochrom> Yeah "data Int = I# Int#" gives you the sole bottom.
19:20:21 <Inst> hmmm, i can't make a newtype over the prim, right?
19:20:29 <monochrom> In the case of Int, the operational meaning is actually more helpful.
19:20:52 <Inst> newtype's limited to Type
19:21:05 <monochrom> The type Int# does not allow a thunk. The type Int, with a real data constructor, does.
19:21:17 <monochrom> So Int can be lazy, Int# can't.
19:22:45 <EvanR> Inst, I was able to newtype over Int# using UnliftedNewtypes
19:22:55 <monochrom> :D
19:23:01 <Inst> is that 9.8.1?
19:23:05 <monochrom> "There is an extension for that."
19:23:16 <Inst> oh, I misspelled it
19:23:16 <Inst> :(
19:23:22 <EvanR> 9.6.2
19:25:23 <EvanR> semantic elements of Maybe Int... ⊥, Just ⊥, Just 3
19:25:45 <EvanR> semantic elements of newtype N = N Int... ⊥, 3
19:25:55 <EvanR> er, N 3
19:26:00 <monochrom> :)
19:26:39 <Inst> https://media.discordapp.net/attachments/968989726633779215/1165008083156729956/image.png?ex=65454953&is=6532d453&hm=059047262d8d02e0fff185ae26ed7a2d8bef3faee7af963c5f3711b12b287fba&=&width=1018&height=394
19:26:58 <EvanR> :t undefined
19:26:59 <lambdabot> a
19:27:16 <EvanR> uh bring forth the full polykinded signature
19:27:28 <Inst> signature of what?
19:27:31 <EvanR> undefined
19:27:37 <Inst> :k undefined seems to be k
19:27:38 <lambdabot> error: Not in scope: type variable ‘undefined’
19:27:38 <lambdabot> error: Not in scope: type variable ‘seems’
19:27:38 <lambdabot> error: Not in scope: type variable ‘to’
19:27:39 <Inst> which is weird
19:27:52 <Inst> :k undefined
19:27:53 <lambdabot> error: Not in scope: type variable ‘undefined’
19:28:05 <EvanR> :k takes a type
19:28:23 <Inst> yeah, and here undefined is treated as a type variable of kind k
19:28:31 <Inst> at least on ghci
19:28:51 <tomsmeding> % :set -fprint-explicit-kinds -fprint-explicit-runtime-reps -fprint-explicit-foralls
19:28:51 <yahb2> <no output>
19:28:57 <geekosaur> :t undefined
19:28:58 <tomsmeding> % :t undefined -- EvanR
19:28:58 <yahb2> undefined -- EvanR ; :: forall (r :: GHC.Types.RuntimeRep) (a :: TYPE r). ; GHC.Stack.Types.HasCallStack => ; a
19:28:58 <lambdabot> a
19:29:09 <EvanR> thanks
19:29:16 <monochrom> This is where the type system protects you. :)
19:29:34 <tomsmeding> the HasCallStack is actually different though
19:29:48 <tomsmeding> that changed in 9.2
19:30:03 <monochrom> In particular, the levity subsystem.
19:30:42 <monochrom> In "a :: *", the * means lifted types. Your unlifted newtype therefore is incompatible.
19:31:10 × Simikando quits (~Simikando@adsl-dyn158.91-127-59.t-com.sk) (Quit: Leaving)
19:31:14 <Inst> :i Type
19:31:21 <geekosaur> no :i in lambdabot
19:31:27 <geekosaur> it's not ghci
19:31:28 <Inst> % :i
19:31:28 <yahb2> syntax: ':i <thing-you-want-info-about>'
19:31:38 <Inst> % :i Type
19:31:39 <yahb2> <interactive>:1:1: error: Not in scope: ‘Type’
19:31:44 <tomsmeding> % import Data.Kind
19:31:45 <yahb2> <no output>
19:31:47 <Inst> % import GHC.Types
19:31:48 <yahb2> <no output>
19:31:48 <Inst> % :i Type
19:31:49 <yahb2> type Type :: * ; type Type = TYPE LiftedRep ; -- Defined in ‘GHC.Types’
19:32:57 <Inst> by the way, is it irresponsible to point out that Setup.hs can be used to execute arbitrary code?
19:33:17 <tomsmeding> tell me a build system where the build tool cannot be used to execute arbitrary code
19:33:36 <tomsmeding> okay perhaps that's not too hard
19:33:40 <EvanR> blockchain something or other
19:33:45 <tomsmeding> but a lot of systems allow that somehow or other
19:33:51 <tomsmeding> even Rust succumbed with build.rs
19:34:04 <tomsmeding> and I mean, haskell has TemplateHaskell anyhow if you get past Setup.hs
19:35:05 <darkling> That'd be because few applications consist *only* of compiling things in a single language.
19:35:58 <darkling> You have to have extensibility of the build system to cope with those things that aren't just the code.
19:36:16 <EvanR> Inst, software programming types can't realistically be kept ignorant of the vast number of security issues in basically every task they perform. But maybe the real answer is you're in dangerous of insulting the intelligence of whoever reads that warning
19:36:32 <EvanR> danger*
19:36:39 <darkling> Building docs, images for the UI, supporting scripts, ...
19:37:24 <EvanR> any time anyone shares code anywhere, that is arbitrary code
19:37:28 <darkling> (Sorry, pet peeve -- all language-specific build systems are crap. Make is only slightly less crap, in the general case.)
19:37:55 CiaoSen joins (~Jura@2a05:5800:282:6600:664b:f0ff:fe37:9ef)
19:37:56 nate2 joins (~nate@c-98-45-169-16.hsd1.ca.comcast.net)
19:38:48 <monochrom> tomsmeding: I forgot, does Ant count? (The Java build tool.) :)
19:39:49 <tomsmeding> monochrom: why do you ask me? The only times I programmed java were for some uni assignment using the Play framework (shudder) and in Android Studio
19:39:52 <tomsmeding> I know ~0 about java
19:39:53 <darkling> Ant's extensible to arbitrary actions, IIRC.
19:40:13 <darkling> And the only reason ant isn't the bottom of my all-time hated build systems is because maven.
19:40:28 <Inst> nah, just off-handedly, I want to mention that the UserHooks datatype in Cabal's core Cabal package can have IO values injected into them via defaultMainWithHooks (and relatives) IO functions
19:40:39 <monochrom> Its bottom all the way down. :)
19:40:46 <monochrom> Err, It's!
19:40:50 <EvanR> I compiled hello world in java once
19:40:56 <Inst> and consequently it makes more sense to treat it relative to the default values
19:42:34 × nate2 quits (~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 245 seconds)
19:48:12 × __monty__ quits (~toonn@user/toonn) (Ping timeout: 240 seconds)
19:48:41 <Guest86> Hi guys, I have pasted the exact problem I had and my solution for it here https://pastebin.com/iXcpME7m
19:49:36 <Guest86> It is an exercise from chapter 3 of https://github.com/kowainik/learn4haskell
19:50:29 <Guest86> My single line comments are what I wanted to do but couldn't
19:50:51 eggplantade joins (~Eggplanta@104-55-37-220.lightspeed.sntcca.sbcglobal.net)
19:51:21 <EvanR> AcAttack used as constructor name in two types in the same module, can't be done
19:52:19 <dminuoso> darkling: There are no beloved build systems.
19:52:49 <Guest86> Yes. So do I have to define new constructors even though they mean the same thing and make function to convert between them? It seems too much to do for something simple
19:53:10 × xigua quits (~xigua@user/xigua) (Remote host closed the connection)
19:53:36 <dminuoso> Guest86: You could extract commonalities into separate data types.
19:53:45 xigua joins (~xigua@user/xigua)
19:53:56 <dminuoso> Or use a higher kinded data type
19:54:49 <Guest86> Here, `Action` is the union of `KnightAction` and `MonsterAction`. Or atleast, I would like it to be
19:54:54 <dminuoso> Guest86: Or you use the HasX pattern.
19:55:15 <dminuoso> (optics/lens can help with much of such access patterns)
19:55:19 <EvanR> uhg
19:55:30 <EvanR> yes it can get arbitrarily complicated
19:55:46 <dminuoso> Guest86: I personally would probably stop trying to encode too much of game logic into data types.
19:55:47 <ddellacosta> Guest86: consider making data CharacterAction = KnightAction Action | MonsterAction Action, which you can then dispatch on in functions without needing type classes
19:56:17 <ddellacosta> but, lots of ways to slice it
19:56:18 × azimut quits (~azimut@gateway/tor-sasl/azimut) (Ping timeout: 256 seconds)
19:56:51 <EvanR> .oO( make 1 action type only some values of which are relevant to the player or the monster respectively )
19:57:26 <EvanR> but it depends on if you want to get things done, or get into type system geekery
19:57:26 <geekosaur> I suggested that in -beginners
19:57:30 <dminuoso> Guest86: I think its more valuable to have one big action data type in this type of scenarios.
19:58:44 <dminuoso> As long as the actions are, in principle, not breaking, it doesnt seem wrong to just not care about provenance too much.
19:59:04 <dminuoso> Especially because you can control what actions are emitted on the entity side
19:59:41 <dminuoso> Consider: The issuable actions might depend on surrounding conditions (maybe if you are *muted* you cant cast spells, or if you are *confused* you cant attack)
20:00:02 <Guest86> I am doing this just to get accustomed to data, newtype and typeclasses. I just wanted to know if there is a simple way to get things done compared to what I have done
20:00:15 <dminuoso> Guest86: The simple way is what you have done.
20:00:43 nickiminjaj joins (~nickiminj@188.146.126.78)
20:00:43 × nickiminjaj quits (~nickiminj@188.146.126.78) (Changing host)
20:00:43 nickiminjaj joins (~nickiminj@user/laxhh)
20:01:17 <Guest86> Ah, thanks.
20:01:52 <Guest86> I have one part incomplete though, `-- duel :: (Fighter a, Fighter b) => a -> b -> Either a b`
20:02:33 <Guest86> I would like the duel to take a knight and a monster as params but as per current implementation, both have to be of same type
20:03:05 <EvanR> what happens if you uncomment that type signature
20:03:40 <EvanR> well, you're not returning an Either so there's that issue
20:03:54 <EvanR> on 85
20:04:46 __monty__ joins (~toonn@user/toonn)
20:06:05 <EvanR> I see you're swapping the sides of the combatants each recursive loop, so you're going to have a hard time returning the correct type, because you don't know who will when ahead of time
20:06:32 <EvanR> if the monster wins on even or odd loops, you have to return a different Either
20:06:41 <Guest86> Yeah ;(
20:07:40 darkling parts (~darkling@2001-ba8-1f1-f0e6-0-0-0-2.autov6rev.bitfolk.space) (Summoning his cosmic powers, and glowing slightly from his toes...)
20:07:49 darkling joins (~darkling@2001-ba8-1f1-f0e6-0-0-0-2.autov6rev.bitfolk.space)
20:09:18 × myme quits (~myme@2a01:799:d60:e400:ffa9:e6a9:c6a3:3d47) (Quit: WeeChat 4.0.5)
20:09:42 <EvanR> you can probably do something to make it work, but it's not going to be comprehensible by most mortals I'm thinking xD
20:10:09 <EvanR> I'm leaning toward duel taking 2 of the same type instead of two different types
20:10:26 <EvanR> unless you want to rewrite it to not do the swapping
20:11:32 × _ht quits (~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Remote host closed the connection)
20:11:55 <Guest86> by rewriting
20:11:57 <Guest86> data Fighter = MkFighter
20:11:58 <Guest86>   { health  :: Health
20:11:58 <Guest86>   , attack  :: Attack
20:11:59 <Guest86>   , defense :: Defense
20:11:59 <Guest86>   , actions :: [Action]
20:12:00 <Guest86>   }
20:12:00 <Guest86> type Knight  = Fighter
20:12:01 <Guest86> type Monster = Fighter
20:12:01 <Guest86> act x = x { actions = tail $ actions x }
20:12:02 <Guest86> duel :: Fighter -> Fighter -> Fighter
20:12:02 <Guest86> duel x y = case head $ actions x of
20:12:03 <Guest86>   AcAttack       xa -> duel (y { health = health y - (Health xa) }) (act y)
20:12:03 <Guest86>   AcPotion       xa -> duel y (x { health = health x + (Health xa) })
20:12:04 <Guest86>   AcDefenseSpell xa -> duel y (x { defense = defense x + (Defense xa) })
20:12:04 <Guest86>   AcRunAway         -> y
20:12:09 <geekosaur> please use a paste site
20:12:13 <geekosaur> @where paste
20:12:13 <lambdabot> Help us help you: please paste full code, input and/or output at e.g. https://paste.tomsmeding.com
20:12:57 ystael joins (~ystael@user/ystael)
20:13:10 <Guest86> my bad. here it is https://pastebin.com/aRQ4Qs7V
20:13:20 <EvanR> you seem to have lost fighter x in the AcAttack case
20:13:32 <geekosaur> (you got lucky the spambot didn't kline you)
20:14:05 <Guest86> EvanR ah the act y is act x
20:14:24 <Guest86> geekosaur thanks for letting me know '=D
20:15:05 <EvanR> to not do the swapping you can factor out the battle code to a non-recursive function which returns results
20:15:19 <EvanR> then recurse based on that without swapping the positions
20:15:53 <Guest86> it has to go on till the health reaches 0. though I forgot to add that case
20:16:04 <Guest86> so it has to be a recursive function
20:16:28 <EvanR> yes but it doesn't need to swap the order of arguments, as slick as that would be
20:16:41 <EvanR> it's logically problematic
20:17:03 <Guest86> Ah, I got what you mean, I will have to write 2 functions, one makes the first param act and the other makes the second param act
20:17:39 <EvanR> duel fighter1 fighter2 OnesTurn = case doRound fighter1 fighte2 of...
20:17:54 <EvanR> duel fighter1 fighter2 TwosTurn = case doRound fighter2 fighter1 of ...
20:18:27 <Guest86> (y)
20:19:05 <EvanR> I don't think I understand what you said, but certainly there's not one way to do it
20:19:13 × Square quits (~Square@user/square) (Ping timeout: 260 seconds)
20:19:28 <Guest86> for this particular problem, does using typeclasses bring any additional benifit?
20:19:38 <EvanR> personally I doubt it xD
20:19:48 <Guest86> My second solution was simple, far less code too
20:20:08 pixelmonk joins (~pixelmonk@173.46.79.26)
20:20:35 <Guest86> Thanks a lot EvanR and geekosaur
20:20:48 lunalaya42 joins (~kody@user/lunalaya42)
20:21:13 <Guest86> I guess, I will have to try out more examples to get  when to use typeclasses and also the newtype
20:21:39 <Guest86> at this moment, I don't see any benefit of using `newtype` over `data` and `type`
20:22:12 <EvanR> they do 3 different things so it's usually not a bikesheddable choice
20:22:38 <Guest86> I get the difference between data and type
20:23:12 <EvanR> between newtype and data, only data lets you do e.g. data Two a = Two a a
20:23:25 <Guest86> but isnt newtype just a special case of data
20:23:25 × Maxdamantus quits (~Maxdamant@user/maxdamantus) (Ping timeout: 252 seconds)
20:23:40 <EvanR> newtype is only allowed if there is 1 constructor with 1 component
20:24:12 <Guest86> so any usecase where I would have to use newtype instead of data?
20:24:50 <dminuoso> Guest86: newtype isnt quite a special case of data because it has no separate runtime representation
20:24:57 <dminuoso> It's rather different in this respect.
20:25:20 <dminuoso> Consequently a newtype doesnt provide a "layer" when it comes to lazyness
20:25:32 <EvanR> you reach for newtypes when you want to clone a datatype and treat it as a new type for reasons
20:25:49 <EvanR> with the benefit of having zero runtime cost
20:26:31 <dminuoso> Guest86: So for instance is you wrap `Int` with `data` and then do arithmatic, you will probably tank the native computation speed. With newtype it will be just as fast as if you had used Int.
20:26:33 × pixelmonk quits (~pixelmonk@173.46.79.26) (Quit: WeeChat 4.1.0)
20:26:49 <dminuoso> (In reality its a bit more blurry, and there are exceptions to both sides)
20:26:54 <dminuoso> But its a rough approximatino.
20:27:35 <Guest86> just curious, why isn't `data` with a single constructor and a single type internally converted to `newtype`?
20:27:50 <EvanR> that would make Int itself impossible
20:27:52 <geekosaur> didnt we have this discussion earlier?
20:27:54 <EvanR> yeah
20:28:14 <geekosaur> `data X a = X a` has one more bottom than `newtype X a = X a`
20:28:15 <Guest86> my bad. I missed it I guess
20:28:32 <Guest86> what does bottom mean here?
20:28:41 <EvanR> data Int = I# Int# where Int# is an unboxed machine int primitive type
20:28:55 <EvanR> if you automatically make that a newtype, then you can't give Int to polymorphic functions anymore
20:28:55 <geekosaur> a possibly nonterminating computation
20:29:11 <geekosaur> which sounds bad but it also enables laziness
20:29:41 <geekosaur> so for example `Int#` has no bottoms and can't be lazy, but `Int` has a bottom and can be lazy
20:30:08 <geekosaur> `data` adds an additional possible level of laziness over te contained value
20:31:28 <EvanR> Guest86, honestly, maybe scroll up and reread the section on bottoms and newtypes xD
20:31:33 <geekosaur> given `data X = X Int`, you can have laziness at the X level and at the Int level but not at the underlying Int# level
20:33:28 <lunalaya42> Is this an okay place to ask questions about category theory?
20:33:30 pixelmonk joins (~pixelmonk@173.46.79.26)
20:33:35 <dminuoso> lunalaya42: Sure.
20:34:14 <Inst> ...
20:34:42 <geekosaur> Guest86, the relationship between laziness and nontermination is that we can have "infinite" but lazy actions, which therefore can be "interrupted"
20:34:49 <geekosaur> > [0..]
20:34:51 <lambdabot> [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,2...
20:35:37 <geekosaur> when the bot reaches its output limit, it stops demanding values from the infinite sequence of Integers starting with 0, so we don't actually have the infinite loop it would otherwise imply
20:38:38 <EvanR> though the list constructions have 2 components each, the number and the rest of the list, so it can't be a newtype anyway
20:39:05 <EvanR> 0 : (1 : (2 : (3 : ...
20:39:35 <geekosaur> and each colon / list constructor marks a point where laziness is injected into the result
20:39:35 <lunalaya42> Going through Bartosz Milewski's book, what is the usefullness of the universal construction? Specifically the notion of product. Is it better than enumerating all the morphisms?
20:39:36 × takuan quits (~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection)
20:40:46 Pickchea joins (~private@user/pickchea)
20:42:02 <EvanR> I had a hard to identifying anything useful in Bartosz's book, it was like a pile of things that just are
20:42:16 <Inst> which book, anyways?
20:42:42 × __monty__ quits (~toonn@user/toonn) (Quit: leaving)
20:43:32 × pretty_dumm_guy quits (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Ping timeout: 255 seconds)
20:43:35 <Guest86> Thanks a lot geekosaur and EvanR, I went through all the previous conversation as well
20:44:24 <EvanR> https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/
20:45:05 <lunalaya42> That's good to know too, any recommendations? I'm coming from an engineering background, so formal math is a bit rough
20:45:06 <Inst> i mean, iirc, he has multiple books
20:45:23 <EvanR> oh
20:45:23 pretty_dumm_guy joins (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655)
20:45:59 <dolio> Universal constructions are the category theory version of (co)data types.
20:46:17 × Guest86 quits (~Guest86@14.139.128.51) (Quit: Client closed)
20:46:58 <mauke> are you allowed to enumerate all morphisms? what if there are too many?
20:47:02 <Inst> https://github.com/BartoszMilewski/Publications/blob/master/TheDaoOfFP/DaoFP.pdf
20:47:05 <Inst> the other one i'm aware of
20:49:34 <EvanR> oh, is the notion of a product to be compared to the notion of "enumerating" every pair of objects and associated projections. Like the idea of a function that squares a number vs giving a list of all possible squares
20:49:51 <EvanR> recipe vs an infinite number of pies
20:50:47 <EvanR> lunalaya42, have you see any of these youtube-ified talks by conal elliott about compiling functional programs to hardware "via categories" ? Seems more engineeringy
20:52:07 tomsmeding feels that the compiling to categories work is overengineering a bit
20:52:21 <EvanR> https://begriffs.com/posts/2015-06-28-haskell-to-hardware.html
20:52:29 <tomsmeding> why move to categorical combinators when we have a perfectly fine pointful representation: the lambda calculus?
20:53:11 <tomsmeding> certain things get a bit nicer because you have more explicit data flow, but you can do more explicit data flow in the lambda calculus as well if you use a linear type system
20:53:34 <EvanR> lambdas are cool on paper
20:54:00 <dminuoso> lunalaya42: Think of it as just a silly example to practice universal construction, really.
20:54:05 <tomsmeding> I mean, the transformation from lambda calculus to categorical combinators is not work-preserving!
20:54:13 <lunalaya42> mauke: I guess that makes sense, but then I don't see how you retain information. The example he gives is that the product in a poset is the minimum of objects. How does that maintain the information stored in both objects?
20:54:37 <tomsmeding> variable references are O(1) in the lambda calculus but are O(number of variables in scope) in combinators naively, and O(log(number of variables in scope)) in the best case
20:54:40 <dminuoso> Im not sure that universal construction makes much sense if you're not in the business of writing proofs, for instance.
20:54:41 × megaTherion quits (~therion@unix.io) (Quit: ZNC 1.8.2 - https://znc.in)
20:55:08 <EvanR> depending on the transformation you don't have variables?
20:55:18 <EvanR> only combinators
20:55:28 <EvanR> possibly a lot more
20:55:51 <tomsmeding> EvanR: sure, but the point is that I can write a LC program that uses a lot of variables; the program you get if you convert that to categorical combinators will be less efficient
20:56:03 <tomsmeding> because it'll need to encode the environment as a bunch of nested tuples
20:56:13 <tomsmeding> projection of a single element from which is not O(1)
20:57:38 <EvanR> it's possible there are optimizations to perform after the translation
20:57:52 megaTherion joins (~therion@unix.io)
20:58:05 <EvanR> and the actual combinators you pick for all this makes a big difference
20:58:55 <tomsmeding> I guess -- I only read the 'compiling to categories' paper, didn't watch the videos, maybe there's more stuff there
20:59:03 <EvanR> and in their case that optimizer was GHC
20:59:43 <EvanR> er, GHC happens before the categories
20:59:50 <tomsmeding> well, and after
21:00:00 <tomsmeding> if you generate code using it again
21:02:12 × kimiamania4 quits (~b4f4a2ab@user/kimiamania) (Quit: PegeLinux)
21:02:45 kimiamania46 joins (~b4f4a2ab@user/kimiamania)
21:08:04 <dolio> There's no guarantee that things like products in a category have some specific, suboptimal representation that you think might be suggested by a notation for them.
21:08:24 × dhruvasagar quits (~dhruvasag@49.207.194.211) (Ping timeout: 245 seconds)
21:08:24 × johnw quits (~johnw@69.62.242.138) (Quit: ZNC - http://znc.in)
21:08:31 <tomsmeding> that's fair
21:08:53 <tomsmeding> but a roundtrip to haskell would increase work -- that's the setting that I was tacitly assuming
21:09:03 <tomsmeding> not much, to be sure
21:10:11 <EvanR> haskell to categories, back to haskell for a minute, then finally hardware?
21:10:16 <dolio> Like, even if you talk about arbitrary finite products as being built out of binary products A×B, a flat product with efficient projections is a product A×(B×(C×D)), and could be what that nested expression denotes. And you could recognize that the projection to C could be realized directly.
21:11:43 × Jackneill quits (~Jackneill@20014C4E1E0E6F00109B8E55CC0410BC.dsl.pool.telekom.hu) (Ping timeout: 260 seconds)
21:12:42 <dolio> Because A×B just means 'some' choice of products in the cateogry. It doesn't have to be systematically built inductively or something.
21:13:25 <dolio> Or naively.
21:13:35 <tomsmeding> hm, I guess that's fair
21:15:17 <dolio> It's kind of unusual coming from a programming perspective, but that's part of the point of the categorical, 'up to isomorphism' sort of perspective.
21:15:40 × eggplantade quits (~Eggplanta@104-55-37-220.lightspeed.sntcca.sbcglobal.net) (Ping timeout: 252 seconds)
21:18:03 srk_ joins (~sorki@user/srk)
21:18:32 × srk quits (~sorki@user/srk) (Ping timeout: 272 seconds)
21:20:02 <dolio> You can imagine data types work that way, too. Although the lifting in Haskell limits how much flattening you could do while preserving semantics.
21:20:40 monochrom is naughty and invents "the Curry-deCarte isomorphism" to mean merely how GHC often compiles Int->Bool->Char to Int×Bool->Char. >:)
21:20:53 srk_ is now known as srk
21:21:52 monochrom has one last joke. co Carte says: coproduct ergo sum. >:D
21:22:58 × megaTherion quits (~therion@unix.io) (Ping timeout: 272 seconds)
21:23:29 <ncf> gito ergo product
21:23:34 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Ping timeout: 256 seconds)
21:24:07 <EvanR> if we change the assocativity of -> does Int->Bool->Char = Int->BoolxChar... *thinks* yes
21:25:04 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
21:25:29 megaTherion joins (~therion@unix.io)
21:25:43 <EvanR> no
21:25:50 <tomsmeding> no, right? char^(bool^int) != bool^int * char^int = (bool*char)^int
21:26:00 <monochrom> :)
21:26:49 <monochrom> "You may also like: The Yoneda lemma." >:)
21:27:04 <EvanR> so suggestive lisp code (-> Int Bool Char) will have to wait
21:32:06 <monochrom> In Scheme, (defun (f a b) (...)) actually gives you the uncurried version f :: A × B -> C, because (f a) is an error, you have to say like (curry f a) to get the curried version.
21:32:20 × Unicorn_Princess quits (~Unicorn_P@user/Unicorn-Princess/x-3540542) (Remote host closed the connection)
21:33:21 <EvanR> I kind of appreciate that, in lisp context
21:33:22 × gatekempt quits (~gatekempt@user/gatekempt) (Quit: My MacBook has gone to sleep. ZZZzzz…)
21:33:56 <EvanR> sometimes you just want a A × B × C × D -> E
21:39:36 × oo_miguel quits (~Thunderbi@78-11-179-96.static.ip.netia.com.pl) (Ping timeout: 260 seconds)
21:42:17 × pixelmonk quits (~pixelmonk@173.46.79.26) (Quit: WeeChat 4.1.0)
21:42:31 pixelmonk joins (~pixelmonk@173.46.79.26)
21:54:41 × lunalaya42 quits (~kody@user/lunalaya42) (Quit: WeeChat 4.0.4)
21:55:20 Maxdamantus joins (~Maxdamant@user/maxdamantus)
22:00:56 × coot quits (~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
22:02:33 × nickiminjaj quits (~nickiminj@user/laxhh) (Quit: My MacBook has gone to sleep. ZZZzzz…)
22:03:51 bastelfreak joins (bastelfrea@libera/staff/VoxPupuli.bastelfreak)
22:04:24 × bastelfreak quits (bastelfrea@libera/staff/VoxPupuli.bastelfreak) (Client Quit)
22:04:38 bastelfreak joins (bastelfrea@libera/staff/VoxPupuli.bastelfreak)
22:04:59 <_d0t> ohai! How do I force ghc to use specific package database? I tried setting GHC_PACKAGE_PATH, -no-*-package-db options, etc, but my GHC custom build still tries to use the wrong one.
22:05:04 × notzmv quits (~zmv@user/notzmv) (Ping timeout: 245 seconds)
22:05:47 bilegeek joins (~bilegeek@2600:1008:b06b:9a73:e45e:f9df:6e0b:4afb)
22:06:02 × acidjnk_new quits (~acidjnk@p200300d6e72b9391d1b8c4ed720c4872.dip0.t-ipconnect.de) (Ping timeout: 258 seconds)
22:06:31 johnw joins (~johnw@69.62.242.138)
22:12:18 <geekosaur> I'm not sure you can; it has to use the package database that was installed as part of the custom ghc, because it has wired-in references to specific packages
22:12:34 <geekosaur> you can't switch them to a different one
22:12:58 <_d0t> actually, i did strace and it seems to look up the right package database, but then it loads Prelude.hi from a different installation.
22:14:00 <_d0t> oh never mind, i'm a big dummy. The package database points to wrong packages somehow.
22:27:53 × Tuplanolla quits (~Tuplanoll@91-159-68-236.elisa-laajakaista.fi) (Ping timeout: 258 seconds)
22:34:49 vglfr joins (~vglfr@37.73.16.154)
22:40:52 × machinedgod quits (~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 272 seconds)
22:48:34 [_] joins (~itchyjunk@user/itchyjunk/x-7353470)
22:51:56 × [itchyjunk] quits (~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 248 seconds)
23:05:03 Vajb joins (~Vajb@207.61.167.122)
23:09:46 × Pickchea quits (~private@user/pickchea) (Quit: Leaving)
23:11:53 × Vajb quits (~Vajb@207.61.167.122) (Ping timeout: 260 seconds)
23:12:58 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:e1a3:648c:fb34:72ec)
23:17:02 Pickchea joins (~private@user/pickchea)
23:17:08 × Pickchea quits (~private@user/pickchea) (Remote host closed the connection)
23:18:58 nickiminjaj joins (~nickiminj@188.146.126.78)
23:18:58 × nickiminjaj quits (~nickiminj@188.146.126.78) (Changing host)
23:18:58 nickiminjaj joins (~nickiminj@user/laxhh)
23:19:32 × gmg quits (~user@user/gehmehgeh) (Quit: Leaving)
23:23:28 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:e1a3:648c:fb34:72ec) (Ping timeout: 258 seconds)
23:28:09 × nickiminjaj quits (~nickiminj@user/laxhh) (Quit: My MacBook has gone to sleep. ZZZzzz…)
23:38:55 dhruvasagar joins (~dhruvasag@49.207.194.211)
23:39:26 nate2 joins (~nate@c-98-45-169-16.hsd1.ca.comcast.net)
23:43:37 × dhruvasagar quits (~dhruvasag@49.207.194.211) (Ping timeout: 252 seconds)
23:44:10 × nate2 quits (~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 252 seconds)
23:50:02 dhruvasagar joins (~dhruvasag@49.207.194.211)
23:54:58 × dhruvasagar quits (~dhruvasag@49.207.194.211) (Ping timeout: 272 seconds)

All times are in UTC on 2023-10-20.