Home liberachat/#haskell: Logs Calendar

Logs on 2023-11-16 (liberachat/#haskell)

00:01:37 × jmdaemon quits (~jmdaemon@user/jmdaemon) (Quit: ZNC 1.8.2 - https://znc.in)
00:02:04 × acidjnk quits (~acidjnk@p200300d6e72b93446103f524bf4ee276.dip0.t-ipconnect.de) (Read error: Connection reset by peer)
00:04:27 jmdaemon joins (~jmdaemon@user/jmdaemon)
00:05:04 × machinedgod quits (~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 256 seconds)
00:06:25 <ski> there would possibly be methods of `MonadStateT'
00:06:33 <ski> s/there/these/
00:06:47 fun-safe-math joins (~fun-safe-@c-24-21-106-247.hsd1.or.comcast.net)
00:07:35 geekosaur doesn't see what it would be, doesn't MonadState encapsulate the common operations of State and StateT?
00:07:48 <geekosaur> (and RWS and RWST)
00:07:48 <ski> if i have `MonadState s m', i can't get access to "the rest of `m', not including the state parts referencing `s'"
00:09:08 alp_ joins (~alp@static-176-175-7-165.ftth.abo.bbox.fr)
00:12:22 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580)
00:16:31 vilya_ is now known as vilya
00:16:47 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580) (Ping timeout: 268 seconds)
00:19:01 dsrt^ joins (~cd@12.206.76.226)
00:19:15 <ski> if i already have `StateT s m a', i can refer to `m' .. and i can convert to `t m a', given `MonadState s (t m)',`MonadTrans t',`Monad m'
00:19:21 <ski> @type let foo :: (MonadTrans t,Monad m,MonadState s (t m)) => StateT s m a -> t m a; foo (StateT f) = do s <- get; (a,s) <- lift (f s); put s; return a in foo
00:19:23 <lambdabot> (MonadTrans t, MonadState s (t m), Monad m) => StateT s m a -> t m a
00:19:48 <ski> but could one go in the other direction ?
00:23:33 × sawilagar quits (~sawilagar@user/sawilagar) (Ping timeout: 246 seconds)
00:31:14 jinsun joins (~jinsun@user/jinsun)
00:32:49 × fun-safe-math quits (~fun-safe-@c-24-21-106-247.hsd1.or.comcast.net) ()
00:34:30 fun-safe-math joins (~fun-safe-@c-24-21-106-247.hsd1.or.comcast.net)
00:44:17 machinedgod joins (~machinedg@d198-53-218-113.abhsia.telus.net)
00:45:46 × jmdaemon quits (~jmdaemon@user/jmdaemon) (Ping timeout: 268 seconds)
00:51:11 jmdaemon joins (~jmdaemon@user/jmdaemon)
00:53:07 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580)
00:56:06 × alp_ quits (~alp@static-176-175-7-165.ftth.abo.bbox.fr) (Ping timeout: 246 seconds)
01:09:06 × jmdaemon quits (~jmdaemon@user/jmdaemon) (Ping timeout: 256 seconds)
01:09:49 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580) (Ping timeout: 268 seconds)
01:14:06 × Feuermagier quits (~Feuermagi@user/feuermagier) (Ping timeout: 245 seconds)
01:17:30 wroathe joins (~wroathe@207-153-38-140.fttp.usinternet.com)
01:17:30 × wroathe quits (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
01:17:30 wroathe joins (~wroathe@user/wroathe)
01:18:38 emmanuelux_ joins (~emmanuelu@user/emmanuelux)
01:18:55 × emmanuelux_ quits (~emmanuelu@user/emmanuelux) (Remote host closed the connection)
01:19:28 Feuermagier joins (~Feuermagi@user/feuermagier)
01:19:54 × emmanuelux quits (~emmanuelu@user/emmanuelux) (Ping timeout: 246 seconds)
01:29:59 emmanuelux joins (~emmanuelu@user/emmanuelux)
01:38:00 × arahael quits (~arahael@119-18-2-212.771202.syd.nbn.aussiebb.net) (Ping timeout: 256 seconds)
01:43:28 rosco joins (~rosco@175.136.157.149)
01:58:16 × califax quits (~califax@user/califx) (Ping timeout: 264 seconds)
01:59:13 califax joins (~califax@user/califx)
02:00:04 × ec quits (~ec@gateway/tor-sasl/ec) (Ping timeout: 264 seconds)
02:00:18 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection)
02:01:03 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
02:01:20 jmdaemon joins (~jmdaemon@user/jmdaemon)
02:02:02 ec joins (~ec@gateway/tor-sasl/ec)
02:11:37 × otto_s quits (~user@p5b044a1d.dip0.t-ipconnect.de) (Ping timeout: 260 seconds)
02:13:09 otto_s joins (~user@p4ff275a7.dip0.t-ipconnect.de)
02:17:40 × xff0x quits (~xff0x@2405:6580:b080:900:3141:d1c2:46a9:b11c) (Ping timeout: 256 seconds)
02:22:47 × Fangs quits (sid141280@id-141280.hampstead.irccloud.com) (Server closed connection)
02:23:01 Fangs joins (sid141280@id-141280.hampstead.irccloud.com)
02:23:12 × ystael quits (~ystael@user/ystael) (Ping timeout: 268 seconds)
02:24:28 × Square2 quits (~Square4@user/square) (Ping timeout: 256 seconds)
02:31:39 × machinedgod quits (~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 246 seconds)
02:41:03 ystael joins (~ystael@user/ystael)
02:48:00 × Boarders___ quits (sid425905@id-425905.lymington.irccloud.com) (Server closed connection)
02:48:20 Boarders___ joins (sid425905@id-425905.lymington.irccloud.com)
02:52:37 × [itchyjunk] quits (~itchyjunk@user/itchyjunk/x-7353470) (Remote host closed the connection)
02:54:53 kiriakos_ joins (~kiriakos@p57b65bf0.dip0.t-ipconnect.de)
02:54:59 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580)
02:55:38 × kiriakos quits (~kiriakos@p57b647b8.dip0.t-ipconnect.de) (Ping timeout: 256 seconds)
02:55:38 kiriakos_ is now known as kiriakos
03:01:16 × thegman quits (~thegman@072-239-207-086.res.spectrum.com) (Read error: Connection reset by peer)
03:02:28 xff0x joins (~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp)
03:03:05 × degraafk quits (sid71464@id-71464.lymington.irccloud.com) (Server closed connection)
03:03:14 degraafk joins (sid71464@id-71464.lymington.irccloud.com)
03:04:08 × superbil quits (~superbil@1-34-176-171.hinet-ip.hinet.net) (Ping timeout: 256 seconds)
03:07:24 <jackdk> I don't understand what it is you are asking. Also, many clients do markdown-style inline code-quoting, and oldGNU-style `quoting' is quite hard to read when lines jump in and out of monospace. You might argue that this is fundamentally a client problem, and I'd agree, but even GNU doesn't use that quoting style any more.
03:08:45 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
03:08:51 × pretty_dumm_guy quits (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5)
03:15:16 nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net)
03:16:55 × califax quits (~califax@user/califx) (Remote host closed the connection)
03:16:55 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection)
03:16:55 × ec quits (~ec@gateway/tor-sasl/ec) (Read error: Connection reset by peer)
03:17:10 califax joins (~califax@user/califx)
03:17:15 ec joins (~ec@gateway/tor-sasl/ec)
03:17:27 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
03:21:42 × td_ quits (~td@i53870930.versanet.de) (Ping timeout: 256 seconds)
03:23:21 td_ joins (~td@i53870904.versanet.de)
03:25:01 finn_elija joins (~finn_elij@user/finn-elija/x-0085643)
03:25:01 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
03:25:01 finn_elija is now known as FinnElija
03:34:52 × califax quits (~califax@user/califx) (Ping timeout: 264 seconds)
03:36:04 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Ping timeout: 264 seconds)
03:36:40 × chiselfuse quits (~chiselfus@user/chiselfuse) (Ping timeout: 264 seconds)
03:36:40 × adanwan quits (~adanwan@gateway/tor-sasl/adanwan) (Ping timeout: 264 seconds)
03:37:29 × alphastate quits (~alphastat@176.254.244.83) (Ping timeout: 260 seconds)
03:48:27 califax joins (~califax@user/califx)
03:48:28 chiselfuse joins (~chiselfus@user/chiselfuse)
03:48:33 adanwan joins (~adanwan@gateway/tor-sasl/adanwan)
03:49:31 × chiselfuse quits (~chiselfus@user/chiselfuse) (Remote host closed the connection)
03:51:49 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
03:53:32 chiselfuse joins (~chiselfus@user/chiselfuse)
03:54:39 × lexi-lambda quits (sid92601@id-92601.hampstead.irccloud.com) (Server closed connection)
03:54:49 lexi-lambda joins (sid92601@id-92601.hampstead.irccloud.com)
03:58:34 × edr quits (~edr@user/edr) (Quit: Leaving)
03:59:43 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580) (Remote host closed the connection)
04:06:48 × ddellacosta quits (~ddellacos@ool-44c738de.dyn.optonline.net) (Ping timeout: 268 seconds)
04:07:09 pr0ton joins (~pr0ton@176.254.244.83)
04:07:22 ddellacosta joins (~ddellacos@ool-44c738de.dyn.optonline.net)
04:09:41 × aforemny quits (~aforemny@2001:9e8:6cf2:3800:48da:c417:67b:551b) (Ping timeout: 240 seconds)
04:10:26 aforemny joins (~aforemny@2001:9e8:6cd7:8c00:47af:9d09:fce9:5fc4)
04:13:01 × Yumemi quits (~Yumemi@2001:bc8:47a0:1b14::1) (Server closed connection)
04:13:21 Yumemi joins (~Yumemi@chamoin.net)
04:17:29 × yvan-sraka quits (sid419690@id-419690.lymington.irccloud.com) (Server closed connection)
04:17:40 yvan-sraka joins (sid419690@id-419690.lymington.irccloud.com)
04:18:56 × nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 256 seconds)
04:20:59 × ddellacosta quits (~ddellacos@ool-44c738de.dyn.optonline.net) (Ping timeout: 268 seconds)
04:22:36 ddellacosta joins (~ddellacos@ool-44c738de.dyn.optonline.net)
04:25:02 × rosco quits (~rosco@175.136.157.149) (Quit: Lost terminal)
04:25:17 rosco joins (~rosco@175.136.157.149)
04:26:21 Inst joins (~Inst@120.244.192.250)
04:26:47 × nrr______ quits (sid20938@id-20938.lymington.irccloud.com) (Server closed connection)
04:27:04 nrr______ joins (sid20938@id-20938.lymington.irccloud.com)
04:29:42 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 256 seconds)
04:35:15 trev joins (~trev@user/trev)
04:38:51 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711)
04:40:44 × lightandlight quits (sid135476@id-135476.helmsley.irccloud.com) (Server closed connection)
04:40:53 lightandlight joins (sid135476@id-135476.helmsley.irccloud.com)
04:41:09 × Lycurgus quits (~georg@user/Lycurgus) (Server closed connection)
04:41:25 Lycurgus joins (~georg@user/Lycurgus)
04:47:27 × ubert quits (~Thunderbi@178.165.182.252.wireless.dyn.drei.com) (Ping timeout: 246 seconds)
04:50:09 sham joins (~sham@2605:a601:a98c:be00:fdc4:4550:60c7:3408)
04:52:00 × dmj` quits (sid72307@id-72307.hampstead.irccloud.com) (Server closed connection)
04:52:25 dmj` joins (sid72307@id-72307.hampstead.irccloud.com)
04:53:07 wroathe joins (~wroathe@207-153-38-140.fttp.usinternet.com)
04:53:07 × wroathe quits (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
04:53:07 wroathe joins (~wroathe@user/wroathe)
05:03:16 _ht joins (~Thunderbi@28-52-174-82.ftth.glasoperator.nl)
05:05:23 × waleee quits (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 268 seconds)
05:06:47 superbil joins (~superbil@1-34-176-171.hinet-ip.hinet.net)
05:08:02 × emmanuelux quits (~emmanuelu@user/emmanuelux) (Quit: au revoir)
05:12:33 × sham quits (~sham@2605:a601:a98c:be00:fdc4:4550:60c7:3408) (Quit: Ping timeout (120 seconds))
05:17:52 × kiriakos quits (~kiriakos@p57b65bf0.dip0.t-ipconnect.de) (Ping timeout: 256 seconds)
05:18:52 czy joins (~user@180.116.181.15)
05:18:52 stiell joins (~stiell@gateway/tor-sasl/stiell)
05:19:13 kiriakos joins (~kiriakos@p5b03ee49.dip0.t-ipconnect.de)
05:21:50 × Inst quits (~Inst@120.244.192.250) (Ping timeout: 256 seconds)
05:25:23 michalz joins (~michalz@185.246.207.193)
05:30:38 Inst joins (~Inst@120.244.192.250)
05:33:08 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 268 seconds)
05:33:46 chomwitt joins (~chomwitt@2a02:587:7a03:f500:1ac0:4dff:fedb:a3f1)
05:40:32 × Unicorn_Princess quits (~Unicorn_P@user/Unicorn-Princess/x-3540542) (Quit: Leaving)
05:42:40 × czy quits (~user@180.116.181.15) (Remote host closed the connection)
05:48:56 × mhatta quits (~mhatta@www21123ui.sakura.ne.jp) (Server closed connection)
05:49:38 mhatta joins (~mhatta@www21123ui.sakura.ne.jp)
05:55:00 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 246 seconds)
05:55:43 euleritian joins (~euleritia@dynamic-089-204-130-029.89.204.130.pool.telefonica.de)
06:04:51 × AlexZenon quits (~alzenon@178.34.162.228) (Server closed connection)
06:05:09 AlexZenon joins (~alzenon@178.34.162.228)
06:07:40 × euleritian quits (~euleritia@dynamic-089-204-130-029.89.204.130.pool.telefonica.de) (Ping timeout: 268 seconds)
06:09:27 misterfish joins (~misterfis@84-53-85-146.bbserv.nl)
06:11:35 zetef joins (~quassel@95.77.17.251)
06:13:16 × notzmv quits (~zmv@user/notzmv) (Ping timeout: 245 seconds)
06:13:44 × AlexNoo quits (~AlexNoo@178.34.162.228) (Server closed connection)
06:14:07 AlexNoo joins (~AlexNoo@178.34.162.228)
06:16:41 acidjnk joins (~acidjnk@p200300d6e72b9344700ee309897754f9.dip0.t-ipconnect.de)
06:17:37 euleritian joins (~euleritia@dynamic-002-247-248-051.2.247.pool.telefonica.de)
06:19:07 × euleritian quits (~euleritia@dynamic-002-247-248-051.2.247.pool.telefonica.de) (Read error: Connection reset by peer)
06:19:24 euleritian joins (~euleritia@77.22.252.56)
06:22:58 takuan joins (~takuan@178-116-218-225.access.telenet.be)
06:27:34 × euleritian quits (~euleritia@77.22.252.56) (Ping timeout: 256 seconds)
06:28:05 euleritian joins (~euleritia@dynamic-002-247-248-051.2.247.pool.telefonica.de)
06:36:37 × _ht quits (~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Remote host closed the connection)
06:37:56 <dminuoso> bwe: I am here now.
06:43:50 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
06:44:00 × zetef quits (~quassel@95.77.17.251) (Ping timeout: 246 seconds)
06:47:45 × misterfish quits (~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 268 seconds)
06:54:53 xxpor joins (~xxpor@user/xxpor)
06:59:09 zetef joins (~quassel@95.77.17.251)
07:03:00 × nitrix quits (~nitrix@user/nitrix) (Server closed connection)
07:03:19 nitrix joins (~nitrix@user/nitrix)
07:05:16 gmg joins (~user@user/gehmehgeh)
07:10:44 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
07:12:20 × qqq quits (~qqq@92.43.167.61) (Ping timeout: 256 seconds)
07:14:36 sord937 joins (~sord937@gateway/tor-sasl/sord937)
07:15:54 × xxpor quits (~xxpor@user/xxpor) (Quit: WeeChat 4.1.1)
07:29:54 × zetef quits (~quassel@95.77.17.251) (Ping timeout: 256 seconds)
07:36:33 × mc47 quits (~mc47@xmonad/TheMC47) (Remote host closed the connection)
07:46:45 × sord937 quits (~sord937@gateway/tor-sasl/sord937) (Remote host closed the connection)
07:47:00 × thegeekinside quits (~thegeekin@189.180.53.210) (Ping timeout: 246 seconds)
07:47:09 sord937 joins (~sord937@gateway/tor-sasl/sord937)
07:47:19 × euleritian quits (~euleritia@dynamic-002-247-248-051.2.247.pool.telefonica.de) (Read error: Connection reset by peer)
07:47:38 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
07:48:02 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
07:49:02 lortabac joins (~lorenzo@2a01:e0a:541:b8f0:a708:6ef4:b35f:fb63)
07:50:06 × meejah quits (~meejah@rutas.meejah.ca) (Server closed connection)
07:50:15 meejah joins (~meejah@rutas.meejah.ca)
08:00:05 × dsrt^ quits (~cd@12.206.76.226) (Remote host closed the connection)
08:00:34 mc47 joins (~mc47@xmonad/TheMC47)
08:01:57 danza joins (~francesco@151.57.147.208)
08:06:08 qqq joins (~qqq@92.43.167.61)
08:06:52 lhpitn joins (~tn@193.96.224.66)
08:08:53 × jrm quits (~jrm@user/jrm) (Ping timeout: 240 seconds)
08:11:53 misterfish joins (~misterfis@87.215.131.102)
08:14:12 fendor joins (~fendor@2a02:8388:1640:be00:2528:5dc7:a36e:9b87)
08:14:18 × Feuermagier quits (~Feuermagi@user/feuermagier) (Ping timeout: 246 seconds)
08:14:36 Feuermagier joins (~Feuermagi@user/feuermagier)
08:15:37 jrm joins (~jrm@user/jrm)
08:16:14 idgaen joins (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
08:18:00 × mikko quits (~mikko@user/mikko) (Server closed connection)
08:18:22 mikko joins (~mikko@dsl-trebng22-58c1a8-185.dhcp.inet.fi)
08:18:22 × mikko quits (~mikko@dsl-trebng22-58c1a8-185.dhcp.inet.fi) (Changing host)
08:18:22 mikko joins (~mikko@user/mikko)
08:22:06 notzmv joins (~zmv@user/notzmv)
08:28:53 × Inst quits (~Inst@120.244.192.250) (Ping timeout: 268 seconds)
08:30:24 × aku quits (~aku@65.108.245.241) (Server closed connection)
08:30:32 aku joins (~aku@65.108.245.241)
08:32:34 <bwe> dminuoso: ski led me up to this point: https://gist.github.com/benjaminweb/ea91583983f5eceb10549ed25db03ec4
08:34:48 <ski> we left off with `return' not being defined
08:40:39 × minigrim0 quits (~minigrim0@2a01:4f9:6b:3416:68ba:8dff:fe58:a5ea) (Server closed connection)
08:40:59 minigrim0 joins (~minigrim0@2a01:4f9:6b:3416:68ba:8dff:fe58:a5ea)
08:43:04 × Lord_of_Life quits (~Lord@user/lord-of-life/x-2819915) (Ping timeout: 268 seconds)
08:44:40 Lord_of_Life joins (~Lord@user/lord-of-life/x-2819915)
08:44:56 vpan joins (~vpan@mail.elitnet.lt)
08:46:30 <dminuoso> bwe: By the way, somewhat but not entirely tangentially: to use your State, ideally dont manually construct with MkState
08:47:02 <dminuoso> bwe: By the way, somewhat but not entirely tangentially: to use your State, ideally dont manually construct with MkState
08:47:04 <dminuoso> Instead, it's sufficient to define `get :: MyState S S` and `put :: S -> MyState S ()`, and then define your tickS in terms of that.
08:47:30 <dminuoso> Part of the rationale here is to start thinking of this MyState as an abstract effect that you interact with, using `get` and `put` primitives.
08:47:37 <dminuoso> And the internals disappear.
08:47:40 <ski> well, `tick' was intended as a primitive here
08:47:49 <bwe> dminuoso: I've had that intuition just a couple of moments ago, too. I suspect, we did not arrive at that point yesterday.
08:47:56 <ski> (partly for convenience sake)
08:47:59 <bwe> let's do first the return
08:48:20 <bwe> dminuoso: we started with the tick :: Int -> Int
08:48:34 <dminuoso> Right I see.
08:48:34 machinedgod joins (~machinedg@d198-53-218-113.abhsia.telus.net)
08:49:05 <ski> <ski> `return' is supposed to "do nothing, apart from just giving back the argument as result", btw
08:49:30 <ski> <ski> return :: a -> State s a
08:49:30 Inst joins (~Inst@120.244.192.250)
08:49:34 <ski> <ski> in your case
08:50:17 alp_ joins (~alp@2001:861:5e02:eff0:1f45:1768:2920:edd0)
08:51:12 Jackneill joins (~Jackneill@20014C4E1E1AA2009B34AF74A9557C2A.dsl.pool.telekom.hu)
08:52:26 × danza quits (~francesco@151.57.147.208) (Ping timeout: 260 seconds)
08:52:49 <bwe> @type pure
08:52:50 <lambdabot> Applicative f => a -> f a
08:56:06 <bwe> … a function that takes an `a` to produce a `State s a`
08:56:51 <ski> yes
08:57:28 <ski> (you could define `pure = return' in `Applicative', deferring to the real definition of `return' in `Monad' (or the other way around, if you prefer))
08:57:55 <bwe> hm, I wouldn't understand then what I am doing
08:58:18 <bwe> why does the return take an `a` to return a `State s a`?
08:58:38 <bwe> that would be the `Tree Int` in our example
08:58:40 <ski> you have defined `(>>=)' (which your use of `do'-notation expands to calls to). but you have't defined `return' yet
08:58:43 <ski> no
08:58:54 <ski> `(>>=)' isn't about trees. neither is `return'
08:59:09 <ski> @type return
08:59:10 <lambdabot> Monad m => a -> m a
08:59:32 danse-nr3 joins (~danse@151.57.147.208)
08:59:35 <ski> return takes an `a' and computes an `m a', where `m' is a monad, and the `a' there is the "monadic result type"
09:00:04 <ski> (in `enumerateTreeFrom', that monadic result type will actually be `Tree (Int,a)', yes)
09:00:07 <bwe> return for State s a defines how to create a State s a for a proivded a
09:00:26 <ski> in your case, the monad `m' is `State s'. so `return :: a -> m a' becomes `return :: a -> State s a'
09:00:31 <ski> yes
09:00:47 <ski> `return' creates a "trivial" or "no-op" monadic action
09:01:08 <bwe> on type-level I'd do that manually with State s (Tree (Int, a))
09:01:21 <ski> (a monadic action, or more specifically, an `m'-action, is just a value of type `m a', for some type `a' (being referred to here as "monadic result type"))
09:01:40 <ski> bwe : yea, that's what you did in `enumerateTreeFrom'
09:01:51 <bwe> now we want to do it generally, right?
09:01:56 <ski> right
09:02:28 <bwe> but now I do it in the function body, right?
09:02:40 <ski> which function body ?
09:02:49 <bwe> return = …
09:03:06 <ski> yea, you have to provide a defining equation of `return', not just a type signature
09:03:19 __monty__ joins (~toonn@user/toonn)
09:03:20 <ski> return :: a -> State s a
09:03:21 <bwe> I am lost at that transition
09:03:24 <ski> return x = ..x..
09:03:34 <ski> what is the type of `..x..' ?
09:03:42 <bwe> a
09:03:43 <ski> no
09:03:51 <bwe> State s a
09:03:58 <ski> yep. the result type of `return'
09:04:05 <ski> an `State s'-action
09:04:25 <bwe> no, this can't be if it's the argument on the left, too
09:04:36 <ski> so `return' should make a `State s'-action .. how do you make values of type `State s a' ?
09:04:52 <ski> "if it's the argument on the left, too" -- huh ?
09:05:03 <bwe> return :: a -> State s a
09:05:10 <bwe> return x = x
09:05:11 <ski> (you may compare with `tickS' as a comparision)
09:05:15 <ski> no
09:05:26 <ski> `x' does have type `a', not type `State s a'
09:05:38 <bwe> that's what I am saying.
09:05:45 coot joins (~coot@89-69-206-216.dynamic.chello.pl)
09:05:48 <bwe> the right side needs to be different than just `x`
09:05:52 <ski> right
09:06:04 <ski> <ski> so `return' should make a `State s'-action .. how do you make values of type `State s a' ?
09:06:07 <bwe> let's type hole that
09:07:00 × DigitalKiwi quits (~kiwi@2604:a880:400:d0::1ca0:e001) (Server closed connection)
09:07:33 DigitalKiwi joins (~kiwi@137.184.156.191)
09:07:40 <bwe> return :: a -> State s a
09:07:43 <bwe> MkState :: (s -> (a, s)) -> State s a
09:07:51 <ski> yep
09:08:06 <ski> so, what's the new code with a hole ?
09:08:33 × leeb quits (~leeb@tk2-243-31079.vs.sakura.ne.jp) (Server closed connection)
09:08:33 ski started doing exercises like this, with holes, before holes were a technical feature in GHC
09:08:48 leeb joins (~leeb@tk2-243-31079.vs.sakura.ne.jp)
09:08:55 <ski> it's a good mental exercise to figure out the types of sections of code left to write
09:09:34 <bwe> return x = _ $ MkState
09:09:48 <bwe> Found hole: _ :: State s0 a0 -> State s a
09:10:09 <bwe> huh, what's the difference here?
09:10:20 <bwe> those zeroes
09:10:53 idgaen thinks State s a is a function that takes a s an return a (a, s)
09:11:15 <idgaen> s/an/and/
09:11:21 <ski> well, lets take a step back
09:11:23 <ski> to
09:11:30 <ski> return :: a -> State s a
09:11:34 <ski> return x = ..x..
09:11:37 <ski> here we know
09:11:40 <ski> x :: a
09:11:45 <ski> ..x.. :: State s a
09:11:50 <ski> and we also think
09:11:56 <ski> MkState :: (s -> (a, s)) -> State s a
09:11:59 <ski> may be relevant
09:12:22 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Remote host closed the connection)
09:12:36 <ski> note that the return type of `MkState' looks similar to the intended type for the (yet-to-write) hole `..x..' (possibly depending on `x')
09:12:42 <ski> iow, if we write
09:12:53 <ski> MkState (..x..) :: State s a
09:12:56 <ski> for some *new* hole
09:13:04 <ski> ..x.. :: s -> (a,s)
09:13:15 <ski> then that would fit into the old hole (of type `State s a')
09:13:20 <ski> iow, we would then have
09:13:30 <ski> return :: a -> State s a
09:13:36 <ski> return x = MkState (..x..)
09:13:41 <ski> bwe : makes sense ?
09:14:21 <bwe> let that sink in
09:15:08 ubert joins (~Thunderbi@178.115.42.132.wireless.dyn.drei.com)
09:16:07 ski would also suggest not so reflexively reaching for `$' .. `_ $ MkState' is just the same as `_ MkState'
09:16:47 ski thinks `$' is quite seldom warranted to use at all
09:16:56 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
09:18:52 <bwe> return x = MkState (_ x)
09:19:00 <bwe> Found hole: _ :: a -> s -> (a, s)
09:20:19 <ski> ok, so that's just saying that in `return x = MkState (..x..)', `..x..' has type `s -> (a,s)', if `x' has type `a'
09:21:09 <ski> next question here is : how to construct something of type `s -> (a,s)', fitting this hole ?
09:23:33 kuribas joins (~user@ip-188-118-57-242.reverse.destiny.be)
09:33:21 × tolt quits (~weechat-h@li219-154.members.linode.com) (Server closed connection)
09:33:48 tolt joins (~weechat-h@li219-154.members.linode.com)
09:36:00 CiaoSen joins (~Jura@2a05:5800:2cb:ad00:2a3a:4dff:fe84:dbd5)
09:38:09 <bwe> it's runState
09:38:55 <bwe> runState :: State s a -> s -> (a, s)
09:39:17 <bwe> hm, it has `State s a` in its front
09:42:56 szkl joins (uid110435@id-110435.uxbridge.irccloud.com)
09:43:44 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711)
09:46:14 <ski> well, that would get you back from trying to construct a hole `..x.. :: s -> (a,s)', to trying to construct a hole `..x.. :: State s a' (which was what we started with in `return x = ..x..')
09:46:53 <bwe> let me write all signatures in one place
09:46:58 <ski> iow, you'd be going from `return x = ..x..' to `return x = MkState (..x..)', to `return x = MkState (runState (..x..))'
09:47:17 <ski> .. but `runState' is the inverse of `MkState', so we're then back to where we started !
09:47:41 <ski> so, we need to find some *other* way to construct something of type `s -> (a,s)'
09:48:04 <bwe> runState :: State s a -> s -> (a, s)
09:48:04 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Ping timeout: 264 seconds)
09:48:31 <bwe> if we had not the State s a here, that would work, doesn't it?
09:48:42 <ski> "that" being ?
09:49:01 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
09:53:48 × danse-nr3 quits (~danse@151.57.147.208) (Read error: Connection reset by peer)
09:54:13 danse-nr3 joins (~danse@151.43.161.172)
09:55:18 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
09:57:02 × tzh quits (~tzh@c-71-193-181-0.hsd1.or.comcast.net) (Quit: zzz)
09:57:17 <bwe> uff… well… return x = runState (_ x)
09:57:25 <bwe> Found hole: _ :: a -> State s0 a0
09:57:57 <bwe> which is just the definition of return, if I get it right?
09:58:33 Pickchea joins (~private@user/pickchea)
09:58:34 <ski> `return x = runState (_ x)' is a type error
09:58:35 × quintasan quits (~quassel@quintasan.pl) (Server closed connection)
09:58:44 quintasan joins (~quassel@quintasan.pl)
09:58:45 × rosco quits (~rosco@175.136.157.149) (Quit: Lost terminal)
09:59:10 <bwe> ok I am too fast here, need to go steps back
09:59:21 <ski> the return type of `return' here is `State s a', which does not match the result type of calling `runState', which is `s -> (a,s)'
09:59:40 <bwe> return :: a -> State s a
09:59:50 <bwe> return :: a -> (s -> (a, s))
09:59:53 <ski> no
10:00:34 <ski> <ski> ok, so that's just saying that in `return x = MkState (..x..)', `..x..' has type `s -> (a,s)', if `x' has type `a'
10:00:37 <ski> <ski> next question here is : how to construct something of type `s -> (a,s)', fitting this hole ?
10:00:49 <ski> can you please describe the type `s -> (a,s)' for me, in words ?
10:01:11 <bwe> give me an s and I create (a, s) for you
10:01:27 <ski> what kind of animal is a thing that has type `s -> (a,s)' ?
10:01:50 × Sgeo quits (~Sgeo@user/sgeo) (Read error: Connection reset by peer)
10:02:06 <bwe> @type (1,)
10:02:07 <lambdabot> Num t1 => t2 -> (t1, t2)
10:02:14 <bwe> (a,)
10:02:34 <ski> is something of type `s -> (a,s)' a list ? is it a tree ?
10:02:36 <ski> what is it ?
10:02:41 <bwe> tuple
10:02:43 <ski> no
10:03:03 <ski> @type (False,)
10:03:04 <lambdabot> t -> (Bool, t)
10:03:05 <bwe> s -> (a,s) is a function taking s producing tuple (a,s)
10:03:11 <ski> `(False,)' is not a tuple
10:03:16 <ski> .. it's a *function*, yes !
10:03:17 <bwe> it's a tuple section
10:03:32 <ski> (a function that computes a tuple, sure)
10:03:49 <ski> now, how do we construct functions ?
10:04:23 <ski> what, generally speaking, is the kind of expression we use, to construct a function value ?
10:04:35 <bwe> (\x -> (a, x)) -- I am not getting your question - do you mean this?
10:04:49 <ski> yes, that's lambda expression, aka "anonymous function"
10:04:51 <danse-nr3> % :set -XTupleSections
10:04:51 <yahb2> <no output>
10:04:58 <danse-nr3> % :t (, 1)
10:04:58 <yahb2> (, 1) :: Num t1 => t2 -> (t2, t1)
10:04:58 <ski> lambda expressions are *the* way to construct functions
10:05:08 <ski> if you write
10:05:15 <ski> return x = MkState (..x..)
10:05:22 <ski> then this is really just syntactic sugar for
10:05:27 <ski> return = \x -> MkState (..x..)
10:05:42 <ski> (so `return' is the function `\x -> MkState (..x..)' here)
10:06:08 <ski> so, whenever we want to construct a function, the *most* basic, direct, way to do that, is to use a lambda expression
10:06:55 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection)
10:07:21 <ski> (and there's lots of indirect ways, like e.g. calling another function that in turn returns a function value .. e.g. `snd (False,not)' also happens to compute a function .. but is not a lambda expression. it evaluates to `not')
10:07:28 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
10:07:30 zaquest joins (~notzaques@5.130.79.72)
10:07:34 <ski> bwe : making sense ?
10:07:38 <bwe> that yes
10:07:45 <bwe> I am struggling with
10:07:51 <bwe> return :: a -> State s a
10:07:55 chele joins (~chele@user/chele)
10:08:04 <ski> return x = MkState (..x..)
10:08:12 <ski> here we have the hole
10:08:17 <ski> ..x.. :: s -> (a,s)
10:08:19 <bwe> MkState :: (s -> (a, s)) -> State s a
10:08:24 <ski> yes
10:08:43 <ski> the type of this hole is a function type. so we *could* try to construct this function by using a lambda expression
10:09:06 <ski> that is, replacing this `..x..' by `\x -> ..x..', for a new hole `..x..'
10:09:10 oo_miguel joins (~Thunderbi@78-11-179-96.static.ip.netia.com.pl)
10:09:15 <ski> bwe : following ?
10:09:40 <ski> well .. perhaps use a different variable name than `x' this time, since we already used `x'
10:10:00 <ski> right, so replacing this `..x..' by `\y -> ..x..y..', for this new hole `..x..y..'
10:10:18 <ski> return x = MkState (\y -> ..x..y..)
10:10:19 × Flow quits (~none@gentoo/developer/flow) (Server closed connection)
10:10:58 Flow joins (~none@gentoo/developer/flow)
10:11:52 <bwe> return x = MkState (\y -> _)
10:11:52 × rncwnd quits (~quassel@2a01:4f8:221:27c6::1) (Server closed connection)
10:11:56 <bwe> I've got this here
10:12:04 rncwnd joins (~quassel@2a01:4f8:221:27c6::1)
10:12:09 <ski> right
10:12:09 <bwe> Found hole: _ :: (a, s)
10:12:16 <ski> so what's the type of `y' now ?
10:12:28 <bwe> s
10:12:32 <ski> yeh
10:12:32 × hippoid quits (~hippoid@user/hippoid) (Server closed connection)
10:12:45 <ski> and what kind of animal would fit in this new hole ?
10:12:54 hippoid joins (~hippoid@c-98-213-162-40.hsd1.il.comcast.net)
10:13:03 <bwe> oh, it compiles
10:13:06 × xff0x quits (~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp) (Ping timeout: 268 seconds)
10:13:09 ski grins
10:13:10 <bwe> return x = MkState (\y -> (x, y))
10:13:13 <ski> indeed
10:13:36 <bwe> (I arrived there, yes, but I don't understand what I've done)
10:13:40 <ski> remember, in `s -> (a,s)', the first `s' is the input state. the `a' is the "monadic result". and the second `s' is the output state
10:14:21 <ski> so, looking at `\y -> (x,y)'. `y', having type `s', is the input state. `x' (of type `a') is the "monadic result". and `y' is also the output state
10:14:35 <ski> so, the state is not changed. and the monadic result is `x'
10:15:05 <ski> so, `return x' is a `State s'-action that does not change the state, and just gives back the argument `x' as monadic result
10:15:34 <bwe> wait, you are too fast for me :)
10:15:45 <ski> <ski> `return' is supposed to "do nothing, apart from just giving back the argument as result", btw
10:15:50 <ski> <ski> `return' creates a "trivial" or "no-op" monadic action
10:16:03 ski waits
10:17:07 × econo_ quits (uid147250@id-147250.tinside.irccloud.com) (Quit: Connection closed for inactivity)
10:17:08 nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net)
10:18:22 × ft quits (~ft@p508db3bc.dip0.t-ipconnect.de) (Quit: leaving)
10:19:43 × lieven quits (~mal@ns2.wyrd.be) (Server closed connection)
10:19:56 <bwe> understood it
10:19:57 pretty_dumm_guy joins (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655)
10:20:03 lieven joins (~mal@ns2.wyrd.be)
10:20:07 <bwe> s -> (a, s)
10:20:10 <bwe> x is a
10:20:17 × Ekho quits (~Ekho@user/ekho) (Server closed connection)
10:20:18 <bwe> s -> (x, s)
10:20:28 <bwe> (\z -> (x, z))
10:20:47 <bwe> filling MkState _ hole with that
10:20:58 <ski> well, you're somewhat mixing up the value and the type levels now .. but i get what you're aiming at
10:20:59 <bwe> MkState (\z -> (x,z))
10:21:11 <bwe> ski: I know but that helped me
10:21:20 <ski> (`x' is not `a'. `x' has *type* `a')
10:21:29 <ski> yes, that's why i didn't dismiss it entirely
10:21:48 <bwe> puh, great
10:21:54 <ski> you're still trying to get to grips with this all
10:22:02 × nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 260 seconds)
10:22:16 <bwe> yes
10:22:18 <ski> in the long run, one should strive to keep the distinction between values (and expressions), and types (and type expressions) clear in one's mind
10:22:19 bwe sighs
10:22:40 <bwe> now, let's try enumerateTree with your example
10:22:49 <ski> and .. *especially* as a beginner, i believe it is helpful to be a bit pedantic about this distinction, since things are a bit blurry and unclear at first
10:23:32 <ski> later, when you've got this more under your belt, you can afford to be more sloppy, when thinking for yourself, or when communicating with *other* people who've *also* got this understanding under their belt
10:24:04 idgaen agrees
10:24:28 <ski> bwe : right
10:24:36 Ekho joins (~Ekho@user/ekho)
10:26:33 <ski> bwe : .. so, does my suggested input data to `enumerateTree' run, now ?
10:26:45 <bwe> yes it does
10:26:54 <ski> and does the result look okay ?
10:27:37 <bwe> yes like your spec said
10:27:39 <bwe> https://gist.github.com/benjaminweb/ea91583983f5eceb10549ed25db03ec4
10:27:40 <bwe> doctest
10:27:45 <bwe> runs through fine
10:28:52 <bwe> until here ok? next up would be replacing tickS with State, right?
10:28:55 × _________ quits (~nobody@user/noodly) (Server closed connection)
10:29:17 _________ joins (~nobody@user/noodly)
10:29:40 <ski> replacing, how ?
10:29:44 <ski> it's already using `State'
10:30:30 <Inst> still working on State?
10:30:37 <Inst> or rather StateT
10:30:41 <bwe> < dminuoso> bwe: By the way, somewhat but not entirely tangentially: to use your State, ideally dont manually construct with MkState
10:32:06 <ski> Inst : `State'
10:32:40 <ski> ah, you mean to replace the primitive `tickS' with the primitives `get' and `set'
10:32:43 <ski> you can do that, if you want
10:32:55 <ski> it's not strictly needed, but could be nice to see how it's done
10:33:10 <bwe> before that I'd need to define them, right?
10:33:18 <ski> bwe : however, you probably ought to add `pure = return' to the `Applicative' instance
10:33:55 <ski> also, you might also (want to do that and) define `return', for `Maybee' as well
10:35:35 <ski> bwe : before or after. you can use top-down design and implementation ("programming by wishful thinking", start from overall goals, then work down by dividing tasks into smaller tasks, adding detail and granularity), or bottom-up (start with basic primitives, work your way up, building a larger vocabularly and higher levels)
10:35:43 <ski> (or you can do both)
10:38:13 × bramhaag7 quits (~bramhaag@198.8.58.39) (Server closed connection)
10:38:21 gtdg joins (~gtdg@user/gtdg)
10:38:23 bramhaag7 joins (~bramhaag@endeavour.server.bramh.me)
10:40:06 <ski> (btw, "primitive" here means that the implementation of it "reaches inside" the definition of the data type (`State'), e.g. pattern-matching on `MkState', or calling/using `MkState' to construct actions)
10:44:01 <danse-nr3> yesterday i was toying with instances and i realised a Traversable requires the simpler cons :: Foldable t, Traversable t => b -> t b -> t b function as a minimal definition
10:44:09 <bwe> ski: returns, pures both defined for Maybee and State s
10:44:59 <danse-nr3> (i thought your conversation was finished, apologies ^^;)
10:45:25 <ski> it ebbs and flows a bit
10:46:08 <ski> danse-nr3 : can you elaborate on what you mean ?
10:46:12 × tnks quits (sid412124@id-412124.helmsley.irccloud.com) (Server closed connection)
10:46:23 tnks joins (sid412124@id-412124.helmsley.irccloud.com)
10:46:51 <ski> bwe : but not on the gist yet ?
10:46:51 <danse-nr3> well i managed to get `traverse` from that `cons`, but maybe i did some calculation wrong?!
10:47:15 <ski> danse-nr3 : does that work for `traverse'ing trees ?
10:47:55 <ski> (say `data Tree a = Leaf | Node a (Tree a) (Tree a)', for concreteness' sake)
10:47:59 <danse-nr3> now that you make me think about it, i worked with the types without checking the laws
10:48:21 <danse-nr3> so... a flawed result i guess
10:48:25 <bwe> ski: now
10:48:59 <ski> right
10:49:16 <ski> (`return = Justt' works too, btw)
10:49:56 <bwe> yep
10:50:05 <ski> (a matter of which you find most clear or simple, i guess. although, sometimes, this kind of thing can result in efficiency improvements)
10:50:08 <bwe> now, tickS is just my get function, right?
10:50:13 <ski> not quite
10:50:26 <bwe> what's the type of get?
10:50:51 <ski> `tick' is like when you're at the post office or whatever, and you push a button on the queue machine to get a ticket number
10:51:15 <ski> you get a number, and the number in the machine is also incremented
10:51:37 <ski> `get' takes a peek at the current state, and provides it for the user as the "monadic result type"
10:51:44 <ski> (and doesn't change the state)
10:51:47 <bwe> oh
10:52:25 <ski> `set', otoh, discards the current state, replacing it with the explicit argument given to the function. and gives an "uninteresting" result as "monadic result"
10:52:32 <bwe> get :: State s a -> s ??
10:52:36 <ski> no
10:53:05 <ski> you're still something thinking "i need to get an input state, so i need to take an input of type `State .....'"
10:53:12 <ski> s/something/sometimes/
10:53:37 <ski> `get' is a single action, that, when performed/executed, will take a look at its *implicit* input state
10:57:22 <bwe> get runs within the context of State s a
10:57:48 <ski> `get' *is* an `State s'-action
10:58:17 × Feuermagier quits (~Feuermagi@user/feuermagier) (Quit: Leaving)
10:58:19 <ski> if you do
10:58:21 <ski> do ...
10:58:25 <ski> s <- get
10:58:29 <ski> ..s..
10:58:46 <ski> then `s' will be the current state at that point of executing the action `get'
10:58:54 glguy_ joins (g@libera/staff/glguy)
10:59:11 <ski> sometimes, you see people do
10:59:16 <ski> do s <- get
10:59:23 <ski> callSomething here
10:59:26 <ski> put s
10:59:49 <ski> to restore back the state, after `callSomething here' possibly changed it, for the purpose of some subcomputation
11:00:34 <bwe> for State Int Int it will be then the first Int, right?
11:00:43 × glguy quits (g@libera/staff/glguy) (Read error: Connection reset by peer)
11:00:45 × g quits (g@libera/staff/glguy) (Read error: Connection reset by peer)
11:00:54 <ski> .. so, you can see that `get' *is* an action, but `put' is a *function* (that given a new value to replace the current state with, gives an action that'll actually perform that)
11:01:14 <ski> the first `Int' is the type of the state. the second is the type of the "monadic result"
11:01:58 <ski> .. but in general, the type of the state could be anything. so we can say `s', to allow the variable `s' to stand for any type
11:02:12 <bwe> get :: s
11:02:43 <bwe> it just returns current state s
11:02:45 <ski> `s' is the type of the implicit state. `get' is an an action, not a state. (it's a `State s'-action)
11:03:10 × Pickchea quits (~private@user/pickchea) (Quit: Leaving)
11:03:45 <ski> (when you see `blah :: State Something SomethingElse', you should think "`blah' is an action, a state action, with state type `Something', and monadic result type `SomethingElse')
11:04:46 <ski> (perhaps it would have been easier to keep this clear, if the name `Stateful' had been chosen instead of `State', for state-actions .. but that's hysterical raisins, now)
11:05:33 g joins (g@libera/staff/glguy)
11:06:07 <bwe> let's recap runState
11:06:07 × anderson- quits (~anderson@user/anderson) (Server closed connection)
11:06:13 <bwe> runState :: s -> (a, s)
11:06:29 <ski> not quite (unfortunately)
11:06:43 bwe is frustrated now
11:06:52 <ski> (this is, imho, a wart of Haskell. i brought it up, briefly, yesterday)
11:07:03 <ski> yea
11:07:21 <ski> newtype State s a = MkState { runState :: s -> (a,s) }
11:07:26 <ski> this much is right
11:07:40 <ski> now, this says that the *field* `runState' has type `s -> (a,s)'
11:07:44 <ski> *however*
11:08:04 <bwe> the field of State s a
11:08:12 <bwe> which is why
11:08:13 <bwe> runState :: State s a -> s -> (a, s)
11:08:19 <bwe> true?
11:08:23 <ski> there's also an implicitly generated field *extraction* function, unhelpfully also named `runState', which if it was defined explicitly, would be defined as
11:08:34 <ski> runState :: State s a -> (s -> (a,s))
11:08:41 <ski> runState (MkState f) = f
11:09:04 <ski> you have to keep the field itself, and its field extraction function, distinct, in your mind
11:09:22 <ski> and it really does *not* help here, that Haskell spells both exactly the same :(
11:10:03 <ski> (e.g. programming in SML, the field extraction function would be `#runState', so there's a syntactic distinction, making this much clearer)
11:10:24 <bwe> so, what's the next step for me?
11:10:51 <ski> well, figure out types for `get' and `put', implement `tickS' in terms of them, and implement `get' and `put' ?
11:10:51 <bwe> I was trying to find out the type of get
11:10:56 <ski> (not necessarily in that order)
11:11:06 <ski> right
11:11:30 xff0x joins (~xff0x@2405:6580:b080:900:389:c68e:2e26:10bf)
11:12:16 <ski> so, whenever, in `do'-notation, you see `x <- blah', then `blah' is an action, namely an `m'-action for the monad `m' in question. this means that `blah' has type `m a' for some type `a' (monadic result type). and then `x' will get type `a' (because `x' will become the monadic result of running/performing/executing the action `blah')
11:12:26 <bwe> if I run get and put in the same Monad, that'd mean their return types should be same
11:12:27 × puke quits (~puke@user/puke) (Ping timeout: 246 seconds)
11:12:52 <ski> at least the monad part of them, yes. the monadic result type could be different
11:12:59 <bwe> if I assume this correctly, State s a is the return type of get and put
11:13:21 <bwe> while put changes the state and does not give it back
11:13:24 <ski> for some type `a', yes. not necessarily the same `a', for `get' and `put
11:13:25 <ski> '
11:13:31 <bwe> get does not change it but give it back
11:13:32 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Ping timeout: 268 seconds)
11:13:56 <ski> (also `put' takes an argument, while `get' does not (take an explicit argument. the implicit one is hidden inside `State', and so is not visible in the type signature))
11:14:00 <ski> right
11:15:57 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 246 seconds)
11:16:12 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
11:17:53 <bwe> put :: s -> _ -- it's not returning anything or unit?
11:19:10 <ski> <ski> `set', otoh, discards the current state, replacing it with the explicit argument given to the function. and gives an "uninteresting" result as "monadic result"
11:19:32 <ski> oh .. sorry, just realized that we apparently used both `set' and `put', to refer to the same operation
11:20:00 <ski> but yes, "unit type" is how you specify "uninteresting result" in Haskell
11:20:12 <ski> (this corresponds to `void' in C,C++,Java,C#,..)
11:21:23 <bwe> put :: s -> _ ()
11:21:42 <ski> yep, getting closer
11:22:13 <bwe> so, it being a monadic result, it might be State s ()
11:23:08 <ski> we want `put y' to be a state-action, specifically a `State s'-action (since we're attempting to make an action for the monad `State s' (where `s' is the type of the implicit state threaded around in it))
11:23:33 <ski> so
11:23:40 <ski> put :: s -> State s ()
11:24:01 <ski> says : if `y' has type `s', then `put y' is a `State s'-action, with monadic result type `()'
11:24:25 <ski> and we want `put y', when executed, to ignore/discard the current state (of type `s'), and replace it with `y'
11:27:23 <bwe> btw where do I define put ?
11:27:38 <bwe> it doesn't belong to Monad, the compiler complains
11:27:46 <ski> well, you can just define it in the top-level of your module, so far
11:28:08 <ski> (just as for `tickS')
11:28:28 <bwe> goood
11:28:33 <bwe> put y = _
11:28:35 <bwe> Found hole: _ :: State s ()
11:28:59 × lortabac quits (~lorenzo@2a01:e0a:541:b8f0:a708:6ef4:b35f:fb63) (Ping timeout: 256 seconds)
11:29:42 <ski> (btw the monadic result type of `put y' is `()', because we're here not interested in getting any monadic result. we're just interested in the state effect, in changing the underlying/implicit/hidden state. we're not getting any information *out* of the state (like `get' and `tickS' do))
11:30:30 <bwe> put :: s -> State s () -- is this now correct or not?
11:31:35 <ski> yea. we want to connect the argument of type `s', to the state type in the monad, since we want to swap out the implicit state with the argument
11:31:54 <ski> (so therefore it's not `put :: s0 -> State s1 ()' for `s0' and `s1' being different types)
11:33:42 × flocks_ quits (~flocks@134.122.90.60) (Server closed connection)
11:33:57 flocks joins (~flocks@134.122.90.60)
11:34:43 <bwe> put y = MkState (\x -> ((), y))
11:34:45 <bwe> it compiles
11:35:57 <ski> so `x' is the current/input state. `()' is the monadic result. and you put `y' in place of the output state
11:36:43 Square2 joins (~Square4@user/square)
11:37:25 sawilagar joins (~sawilagar@user/sawilagar)
11:38:32 <bwe> how do I store y?
11:39:07 <ski> store ?
11:39:26 <bwe> ski: we discard current state, so I drop x and set it to y
11:39:51 <bwe> so the implementation is right, right?
11:40:32 <ski> yes
11:42:12 <bwe> get :: State s a
11:42:22 × cyphase quits (~cyphase@user/cyphase) (Ping timeout: 246 seconds)
11:43:01 <bwe> MkState :: (s -> (a, s)) -> State s a
11:43:10 <bwe> so MkState would be start
11:43:13 <ski> yep
11:43:26 <ski> however .. perhaps look twice at the type signature
11:44:14 <bwe> I don't get it
11:44:17 <bwe> sry
11:44:20 <ski> get :: State s a
11:44:22 <ski> what is `a' ?
11:44:59 <bwe> it's the value we carry with us
11:45:13 puke joins (~puke@user/puke)
11:45:15 <bwe> but are we interested in it when using get? no
11:45:17 thyriaen joins (~thyriaen@2a01:aea0:dd4:7550:6245:cbff:fe9f:48b1)
11:45:20 <bwe> we want `s`
11:45:23 <bwe> correct?
11:45:30 <ski> the position `State s <here>' is the "monadic result type" position
11:45:43 <bwe> so, it'd be State s s
11:45:46 <ski> we want `get' to deliver the current state value/version as the monadic result
11:45:47 <ski> yes
11:45:49 <bwe> woooh
11:46:03 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
11:46:47 <bwe> get = MkState (\s -> (s, s))
11:46:52 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
11:46:52 <ski> ("version", because of the series of versions `n0',`n1',`n2',`n3' that you had for your counter. this series of evolving versions is "the state" itself. individual versions are snapshots of the state)
11:46:54 cyphase joins (~cyphase@user/cyphase)
11:46:56 <bwe> that compiles at least
11:47:05 <bwe> ski: true
11:47:20 <ski> so, `s' is the current input state. then `s' is the monadic result. and finally `s' is also the output state
11:47:31 <ski> so the state is not changed. and the state is delivered as monadic result
11:48:18 <ski> ok, so `tickS' ?
11:48:50 <bwe> tickS = MkState $ \s0 -> (s0, s0+1)
11:49:01 <ski> can it be defined with `do'-notation ?
11:49:02 <bwe> tickS :: State Int Int
11:49:12 <ski> e.g. using `get' and `put' ?
11:52:39 <bwe> tickS' :: State Int Int
11:52:46 <bwe> tickS' = do
11:52:50 <bwe> s0 <- get
11:53:03 <bwe> _ <- put (s0 + 1)
11:53:06 <bwe> get
11:53:24 <ski> that's preincement
11:53:49 <ski> if you want postincrement, the monadic result should be the value of the counter before incrementing
11:53:56 <ski> (iow `s0')
11:53:58 <bwe> return s0
11:54:01 <ski> yep
11:54:10 × remexre quits (~remexre@user/remexre) (Server closed connection)
11:54:19 <ski> btw, it's possible to abbreviate `_ <- ...' as simply `...'
11:54:20 remexre joins (~remexre@user/remexre)
11:54:27 lortabac joins (~lorenzo@2a01:e0a:541:b8f0:710e:fea0:5caf:9833)
11:54:49 <ski> (i'd probably also say `n' instead of `s0', since here we don't have an abstract arbitrary state, but the state is a counter, a number)
11:55:03 × kuribas quits (~user@ip-188-118-57-242.reverse.destiny.be) (Ping timeout: 256 seconds)
11:55:22 <bwe> yup, done
11:55:24 <ski> btw, imho, it would be very nice, if one could define `get' and `put' something like this :
11:55:28 <ski> get :: State s s
11:55:34 <ski> runState get s = (s,s)
11:55:36 <ski>
11:55:42 <ski> put :: s -> State s ()
11:55:52 <ski> runState (put s) _ = ((),s)
11:56:00 <ski> or, possibly using infix syntax, so
11:56:02 <ncf> one can, in Agda :)
11:56:09 <ski> get `runState` s = (s,s)
11:56:12 <ski> and
11:56:24 <ski> put s `runState` _ = ((),s)
11:56:32 <ski> ncf : yep, i was just about to mention that :)
11:57:12 <ski> tihs puts the emphasis on defining what happens when we execute the action. "if we feed an input state `s' to the action, what is the monadic result, and what is the output state ?"
11:57:42 <ncf> (although in Agda i don't think you'd need a State wrapper at all, because of higher-order unification)
11:57:54 <ski> (this is similar to defining a function `f' by 'f x = ..x..', instead of `f = \x -> ..x..'. defining `f' in terms of what a use of, a *call* to, `f', does)
11:58:17 <ski> years before Agda picked this up, i learned of this style of definition, in
11:58:21 <ski> @where ErikPoll
11:58:22 <lambdabot> "Subtyping and Inheritance for Inductive Types" in 1997 at <http://www.cs.ru.nl/E.Poll/papers/durham97.pdf>,"Subtyping and Inheritance for Categorical Datatypes" in 1997 at <http://www.cs.ru.nl/E.
11:58:22 <lambdabot> Poll/papers/kyoto97.pdf>,"A Coalgebraic Semantics of Subtyping" in 2000 at <http://www.cs.ru.nl/E.Poll/papers/cmcs00.pdf>,later version of that in 2001 at <http://www.cs.ru.nl/E.Poll/papers/ita01.
11:58:22 <lambdabot> pdf>
11:58:37 ski nods to ncf
11:59:16 <ski> bwe : this style also would be quite readable, for `return' and `(>>=)'
11:59:31 <ski> return x `runState` s = (x,s)
11:59:53 <ski> (ma >>= amb) `runState` s0 = (y,s2)
11:59:55 <ski> where
12:00:13 <ski> (x,s1) = ma `runState` s0
12:00:23 <ski> (y,s2) = amb a `runState` s1
12:00:36 × Goodbye_Vincent quits (cyvahl@freakshells.net) (Server closed connection)
12:00:50 Goodbye_Vincent joins (cyvahl@freakshells.net)
12:01:05 <ski> .. but, at least so far, this remains pseudo-Haskell, something that's currently not supported
12:01:30 <bwe> so, we've defined tickS' with get and put
12:01:33 <ski> yes
12:01:40 <ski> now
12:02:04 <ski> it *could* be useful for you to reformulate the `do'-notation, in terms of explicit calls to `>>=' (with lambda expressions)
12:02:17 × szkl quits (uid110435@id-110435.uxbridge.irccloud.com) (Quit: Connection closed for inactivity)
12:02:18 <bwe> tickS'?
12:02:24 <ski> to make it absolutely clear what's happening, to not hide any magic inside the `do'-notation
12:02:37 <ski> that, and `enumerateTreeFrom' too
12:03:18 × danse-nr3 quits (~danse@151.43.161.172) (Ping timeout: 260 seconds)
12:04:41 <ski> `ma >>= amb' is an `m'-action with result type `b' (where `ma' is an `m'-action with result type `a', and `amb' is a function transforming `a's into `m'-actions with result type `b'), such that, *when* this action `ma >>= amb' is executed, `ma' is first executed (performing some effects), and its monadic result `x' is passed to `amb', so that then the action `amb x' is executed, and its monadic result is the
12:04:48 <ski> overall monadic result
12:04:54 <bwe> get >>= put (\x -> x + 1) is one part
12:05:12 × tcard quits (~tcard@2400:4051:5801:7500:cf17:befc:ff82:5303) (Remote host closed the connection)
12:05:20 <bwe> I'd still need to return the value of get
12:05:20 zetef joins (~quassel@95.77.17.251)
12:05:23 <ski> so, `(>>=)' combines two actions in sequence into a larger action, so that when performed, it performs the two given smaller actions, in order (keeping the result of the second one)
12:05:27 tcard joins (~tcard@2400:4051:5801:7500:cf17:befc:ff82:5303)
12:05:47 <ski> or, strictly speaking, the second action is actually a function that will be given the intermediate result of the first action
12:06:16 <ski> bwe : well, `put' doesn't want a lambda expression (a function), here
12:06:31 <ski> but `>>=' *does* want a function (e.g. a lambda expression), as right operand
12:06:48 <ski> so `get >>= \n -> ..n..' e.g.
12:07:22 anderson- joins (~anderson@user/anderson)
12:07:28 <bwe> get >>= (\x -> x + 1) >>= put
12:07:47 <ski> getting a bit closer
12:07:53 <bwe> however the lambda will not work
12:08:05 <ski> now, you want to pass the new state as an argument to `put'
12:08:10 <ski> what is the new state, here ?
12:08:43 <ski> (`x' is the old state, recall. it's the result that `get' delivers)
12:09:08 <bwe> the lambda will result State s s
12:09:20 <bwe> (x+1, x+1)
12:09:28 <ski> yes, `>>=' expects its right operand to be a function that computes an action
12:09:36 <bwe> that's what put receives
12:09:53 <ski> in `tickS', the state is an `Int', a counter
12:09:55 <ski> not a pair
12:10:17 <bwe> what will be the type of x?
12:10:22 <ski> `Int'
12:10:53 <bwe> good, so I can send that through to put with >>= -- but you had a concern, right?
12:11:09 <ski> `put' is a function
12:11:18 <ski> you need to pass the intended new state to `put' as an argument
12:12:09 <bwe> put (get >>= (\x -> x + 1))
12:12:28 <ski> <ski> what is the new state, here ?
12:12:43 <bwe> well, the interface between the paren and put is not correct, ofc
12:13:36 danse-nr3 joins (~danse@151.43.161.172)
12:13:41 <bwe> n' <- get >>= (\x -> x + 1)
12:13:44 <bwe> put n'
12:13:58 <bwe> that's where I am at now
12:14:04 <bwe> do you agree with this?
12:14:24 <ski> well, you're supposed to do away with `do' here. that means no `<-'
12:14:33 <bwe> yes, I know
12:14:34 <ski> <ski> (`x' is the old state, recall. it's the result that `get' delivers)
12:14:36 <ski> agree ?
12:14:40 <bwe> yes
12:14:45 <ski> what is the new state, then ?
12:14:52 <ski> (just the new state, nothing else)
12:15:20 <bwe> I don't understand, the result after the lambda function: get >>= (\x -> x + 1)
12:15:31 <ski> the purpose of `tickS' is to increment the state counter
12:15:41 <ski> the old value of the counter state is `x'
12:15:48 <ski> what is the intended new value of the counter state ?
12:16:03 <bwe> x+1
12:16:04 <ski> yes
12:16:23 <ski> in order to effect *changing* the implicit state to this new state, we want to call `put'
12:16:32 <ski> `put' wants the to-be new state as an argument
12:16:41 <ski> how would such a call to `put' look like ?
12:16:46 <ski> (again, just the call, nothing else)
12:17:03 × CiaoSen quits (~Jura@2a05:5800:2cb:ad00:2a3a:4dff:fe84:dbd5) (Ping timeout: 268 seconds)
12:17:17 <bwe> put (\x -> x + 1)
12:17:24 <bwe> no no
12:17:26 <ski> is `\x -> x + 1' the new state ?
12:17:34 <ski> what was the new state, again ?
12:17:41 <bwe> x + 1
12:17:42 <ski> yes
12:17:44 <ski> so ?
12:18:41 kuribas joins (~user@ip-188-118-57-242.reverse.destiny.be)
12:19:40 <bwe> (\x -> x + 1) is clear but I don't know where to put it
12:19:55 <ski> `\x -> x + 1' is not clear to me
12:19:55 <bwe> put is not taking a function
12:20:12 <ski> (or rather, it's not clear what purpose it would serve, here)
12:20:14 <ski> right
12:20:26 <ski> `btw' wants a state value/version. in this case, an `Int'
12:20:36 <ski> er .. `put' wants
12:20:58 ski idly wonders how that serialization mixup occured
12:21:03 <bwe> how do I give put the new version then?
12:21:21 <ski> give it to `put' ?
12:21:33 <ski> the new version is ?
12:21:41 <bwe> x + 1
12:21:46 <bwe> but I don't have x
12:21:50 <ski> and passing that to `put' would like what ?
12:21:58 <ski> doesn't matter. imagine you have `x' already
12:22:09 <bwe> you're kidding
12:22:10 <bwe> get >>= put (x + 1)
12:22:24 <ski> getting closer still
12:22:33 bwe sighs
12:22:41 <ski> *now* is the time to ask where `x' comes from
12:23:03 <ski> the answer to "how does it look like to pass `put' the (intended) new state ?" was `put (x + 1)'
12:23:15 <ski> so, if
12:23:18 <ski> x :: Int
12:23:19 <bwe> we need a lift function that gets us the bare Int
12:23:20 <ski> then
12:23:25 <ski> put (x + 1) :: State Int ()
12:23:41 <ski> but `>>=' still wants a function to its right
12:24:09 <ski> (so we're back to `get >>= \x -> ..x..', no ?)
12:24:09 <bwe> get >>= (\x -> put (x + 1))
12:24:14 <ski> right, good ! :D
12:24:50 <bwe> oh, inside we could use the x to return that
12:25:23 <ski> so, we're passing "what to do with the monadic result of `get'", as the right operand to `>>=', this function `\x -> put (x + 1)', when it recieves the intermediate result `x', will give the action `put (x + 1)' that (when executed) will update the state
12:25:34 <ski> there's only one detail left here now
12:25:44 <bwe> giving back the current state
12:25:56 <ski> the monadic result of `put (...)' is `()'. but we want `tickS' to give a monadic result of type `Int'
12:25:59 <ski> right
12:26:11 <bwe> so we can't do >>= get
12:26:29 <ski> no .. but we can use `>>=' again, still (but not with another `get')
12:26:52 <bwe> get >>= (\x -> put (x + 1)) >>= _
12:26:56 <ski> yes
12:27:05 <bwe> Found hole: _ :: () -> State Int Int
12:27:13 <ski> (you'll want to insert extra brackets there ..
12:27:25 <ski> (get >>= (\x -> put (x + 1))) >>= _
12:27:25 <ski> )
12:27:52 <ski> oh, actually, it doesn't matter
12:28:05 <ski> right, `>>=' is left-associative, so you're fine
12:28:30 <ski> "Found hole: _ :: () -> State Int Int" -- `()' here is the monadic result of the `put (x + 1)'
12:29:04 <dminuoso> ski: I think there's a deeper value in focusing on `get/put` here. It emphasises in the transformer situation on the effect combination.
12:29:07 <bwe> so let's discard that unit and use get again
12:29:40 <ski> dminuoso : it certainly helps to provide relatively simple, but instructive, combinations of effects
12:29:44 <dminuoso> That is, some underlying tickS in terms of (MaybeT StateT S) doesnt become some adhoc implementation, but it rather shows that the implementation in terms of put/get stays the same.
12:29:50 <dminuoso> Yup
12:30:24 <ski> (not quite sure what you mean by "the transformer situation on the effect combination")
12:31:02 <ski> dminuoso : well, now you're stepping/thinking ahead to `MonadState' (which we haven't touched yet). but good point
12:31:07 <bwe> ski: (get >>= (\x -> put (x + 1)) >>= (\_ -> get))
12:31:10 <bwe> heureka
12:31:49 <ski> bwe : let me show you an equivalence of code, often used for refactoring
12:31:58 <dminuoso> ski: I think mtl-style classes and transformers are useful for very similar reasons: You get to compose effects. While granted, mtl-style does not specify effect ordering, that may not always be relevant.
12:32:24 <ski> ma >>= (\a -> amb a) >>= (\b -> bmc b)
12:32:27 <ski> which really means
12:32:31 <ski> (ma >>= (\a -> amb a)) >>= (\b -> bmc b)
12:32:35 <ski> is the same as
12:32:41 <ski> ma >>= (\a -> amb a >>= (\b -> bmc b))
12:32:44 <dminuoso> ski: The thing is, even if you had a MyStateT now, but they implemented tickS in terms of MkStateT, it wouldn't be as obvious how MyStateT is a combination of effects.
12:33:14 <ski> it doesn't matter if we say "First do A and B, and then do C.", or if we say "First do A, then do B and C.". the grouping doesn't matter (even though the ordering might)
12:33:54 <ski> bwe : this is called the associative law. it's similar to `(x + y) + z = x + (y + z)' or `(x * y) * z = x * (y * z)' or `(xs ++ ys) ++ zs = xs ++ (ys ++ zs)'
12:34:07 <bwe> sk
12:34:23 <bwe> ski: so I can remove some parens
12:34:26 <ski> so
12:34:29 <ski> your suggestion
12:34:35 <ski> (get >>= (\x -> put (x + 1)) >>= (\_ -> get))
12:34:53 <ski> is then equivalent to
12:35:01 <bwe> tickS' = get >>= \x -> put (x + 1) >>= \_ -> get
12:35:15 <ski> (get >>= (\x -> put (x + 1) >>= (\_ -> get)))
12:35:31 <ski> and Haskell allows us to remove the brackets here, in fact, writing just
12:35:41 <ski> get >>= \x -> put (x + 1) >>= \_ -> get
12:35:49 <ski> bwe : right
12:36:23 <ski> so .. note that you're first getting the current state. then setting/putting the current state to a new value. then getting the current state again
12:36:35 <bwe> yup
12:36:37 <ski> what do you thing the result of getting the current value again will be ?
12:36:42 <ski> s/thing/think/
12:37:01 <bwe> type or value?
12:37:52 <ski> dminuoso : yea, the aim is to eventually move to combine state and failure. but i didn't want to needlessly complicate stuff to begin with, by introducing `MonadState' when it wasn't needed
12:38:01 <ski> bwe : value
12:38:20 <bwe> x+1
12:38:24 <ski> right
12:38:33 <ski> so, `tickS' is now preincrementing again
12:38:45 <ski> the original one, using `MkState' was postincrementing
12:38:53 <ski> so there's a discrepancy in behaviour
12:39:42 <bwe> right, we wanted to return the value before incrementing
12:39:46 <ski> yea
12:39:53 <ski> 'x+1' is the value after incrementing
12:39:58 <ski> what's the value before incrementing ?
12:40:22 <bwe> we shouldn't do it with x-1 because we don't know what put got as an argument, it could be sth. different than x+1
12:40:43 <ski> well, `x-1' would be pre*decrementing*
12:40:48 <bwe> :)
12:40:50 <ski> (or something like that ..)
12:41:22 <ski> we do know that the first `get' doesn't change the state, but does provide it as monadic result
12:41:24 <bwe> since we have x in the put lambda, we could use it, all we'd neede is to return that instead of calling get again
12:41:32 <ski> right
12:41:42 <bwe> ofc we'd need to make a State out of it
12:41:51 <bwe> but I'd type hole my way to that
12:41:56 <ski> well, `return' already makes a `State ...'
12:42:25 <bwe> so, it'd be *just* a return x
12:42:30 <bwe> within the put lambda
12:42:41 ski kinda thinks of type holes as luxury, instead of figuring out the types of the holes in your head (or on paper) ;)
12:42:48 <ski> yes
12:42:52 <ski> so ?
12:43:21 <bwe> but how to put the return into the lambda without do notation?
12:43:32 <ski> just do it ?
12:43:56 <ski> (`return' is an ordinary function, has nothing, per se, to do with `do'-notation)
12:44:09 <bwe> tickS' = get >>= \x -> put (x + 1) return x
12:44:13 <bwe> this is not going to work
12:44:20 <ski> <bwe> within the put lambda
12:44:47 <ski> where did the second `>>=' go ?
12:45:06 <bwe> I removed it because we get rid of the second get
12:45:15 <ski> well, we still need it
12:45:17 <ski> just not the `get'
12:45:22 <bwe> wait
12:45:43 <bwe> tickS' = get >>= (\x -> put (x + 1) >>= return x)
12:45:50 lisbeths joins (uid135845@id-135845.lymington.irccloud.com)
12:45:51 <bwe> that's closer I feel but doesn't compile
12:45:57 <ski> and the lambda ?
12:46:09 <ski> where does the monadic result of `put (...)' go ?
12:47:12 <bwe> we can discard it; now it goes to return x which makes no sense
12:47:20 <ski> how do we discard it ?
12:47:41 <ski> (recall you did discard it before, in the preincrement version)
12:47:41 <bwe> tickS' = get >>= (\x -> put (x + 1) >>= (\_ -> return x))
12:47:49 <ski> yep :)
12:48:02 bwe sighs as it compiles
12:48:06 <ski> note how
12:48:10 <ski> tickS = do
12:48:16 <ski> x <- get
12:48:26 <ski> _ <- put (x + 1)
12:48:30 <ski> return x
12:48:35 <ski> becomes
12:48:41 <ski> tickS =
12:48:53 <ski> get >>= \x ->
12:49:06 <ski> put (x + 1) >>= \_ ->
12:49:10 <ski> return x
12:49:18 <ski> or, if you want to be explicit with brackets
12:49:24 <ski> tickS =
12:49:28 <ski> get >>= (\x ->
12:49:32 <ski> put (x + 1) >>= (\_ ->
12:49:42 <ski> return x ))
12:50:06 × kuribas quits (~user@ip-188-118-57-242.reverse.destiny.be) (Ping timeout: 246 seconds)
12:50:08 <ski> note how the `<result> <- <action>' translates to `<action> >>= \<result> ->'
12:50:30 szkl joins (uid110435@id-110435.uxbridge.irccloud.com)
12:50:51 <bwe> fine
12:51:03 <bwe> enumerateTreeFrom?
12:51:30 Feuermagier joins (~Feuermagi@user/feuermagier)
12:52:34 <ski> now, recall your earlier
12:52:35 <ski> <bwe> ski: (get >>= (\x -> put (x + 1)) >>= (\_ -> get))
12:53:22 <ski> the trouble here was that you had written this like `(... >>= \x -> ..x..) >>= ...', so you couldn't use `x' (starting state of counter) inside the last `...', since it wasn't in scope
12:53:24 akegalj joins (~akegalj@141-136-147-15.dsl.iskon.hr)
12:54:06 <bwe> yup
12:54:19 <ski> but since `(... >>= \x -> ..x..) >>= \y -> ..y..' is equivalent to `... >>= \x -> (..x.. >>= \y -> ..y..)', by the associative monad law, in this right-associated form we could refer to `x' in the last part
12:55:10 <bwe> the key were the parentheses
12:55:15 <ski> yes
12:55:19 <bwe> brilliant
12:55:25 <ski> (as always with associativity, it's about grouping)
12:55:30 <ski> in terms of `do'-notation, the associative law says that
12:55:54 <ski> do y <- do x <- blah
12:56:04 <ski> bleh x
12:56:11 <ski> bloh y
12:56:14 <ski> is the same as
12:56:20 <ski> do x <- blah
12:56:27 <ski> do y <- bleh x
12:56:33 <ski> bloh
12:56:48 <ski> which by syntactic sugar can also be written as
12:56:53 <ski> do x <- blah
12:57:01 <ski> y <- bleh x
12:57:05 <ski> bloh y
12:58:05 <ski> so, the associative law is what allows us to regroup a sequence of commands inside `do'-notation, and to e.g. factor out a subsequence of them into a separate definition. or the reverse, inlining a definition (using `do') into a sequence of `do'-commands
12:58:07 Simikando joins (~Simikando@adsl-dyn216.91-127-84.t-com.sk)
12:58:56 <ski> there's also "neutral element" laws, aka "unit laws". these are similar to `0 + x = x = x + 0', `1 * x = x = x + 1' and `[] ++ xs = xs = xs ++ []'
12:59:06 <ski> return x >>= k = k x
12:59:22 <ski> mx >>= return = mx
12:59:36 <ski> in terms of `do', these say that
12:59:44 <ski> do ...
12:59:51 <ski> y <- return x
13:00:01 <ski> ..y..
13:00:04 <ski> can be replaced by
13:00:06 <ski> do ...
13:00:09 <ski> ..x..
13:00:16 <ski> and that
13:00:21 <ski> do ...
13:00:25 <ski> blah
13:00:27 <ski> is the same as
13:00:29 <ski> do ...
13:00:35 <ski> x <- blah
13:00:37 <ski> return x
13:00:50 <ski> bwe : makes sense ?
13:00:59 <thyriaen> no
13:01:21 <ski> did you get the first part, associativity in terms of `do' ?
13:01:27 kuribas joins (~user@ip-188-118-57-242.reverse.destiny.be)
13:02:20 × idgaen quits (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1)
13:03:00 <bwe> ski: yes, think so
13:03:13 <ski> ok
13:03:32 <ski> so `return x' is an acion that "does nothing", a no-op. it only presents `x' back as monadic result
13:03:40 × ChaiTRex quits (~ChaiTRex@user/chaitrex) (Ping timeout: 264 seconds)
13:03:40 <ski> so, the `do'-command
13:03:42 <ski> y <- return x
13:03:59 <ski> then does nothing, except to take `x', and now (also) name it `y'
13:04:23 <ski> so, we could just remove the `y <- return x' command in the `do', and replace the `y's after it by `x's
13:04:34 × alp_ quits (~alp@2001:861:5e02:eff0:1f45:1768:2920:edd0) (Remote host closed the connection)
13:04:42 <bwe> yup
13:04:56 alp_ joins (~alp@2001:861:5e02:eff0:6102:872f:f333:fe94)
13:05:48 <ski> (`return' does *not* "stop execution and return from the function", like `return' in C,C++,Java,C#,... does. it's simply a "do nothing" operation. some people think that it would have been better to use a different name, to avoid confusion with comparision to other languages here. some people prefer using `pure' (which does the same thing) over `return', for this reason)
13:06:23 <ski> but `return' and `Monad' came years before `Applicative' and `pure' was invented, and we're more or less stuck with it now
13:07:21 <ski> (the reason for the name `return' is that, *usually*, the only place (in `do') you'd use `return' is at the *end* of the command sequence, and so it looked superficially similar to that meaning of `return' in other languages)
13:08:04 <ski> ok, so that's the left neutral element law, `return x >>= k = k x'. doing `return x' first, then doing `k' with the result of that, is the same as just doing `k x' directly
13:08:07 <danse-nr3> well one can use `pure` as well
13:08:18 <ski> as i just said, yes :)
13:08:19 <bwe> so, I am trying to use >>= to rewrite the enumerateTreeFrom now
13:08:38 <danse-nr3> ops sorry i should stop reacting on single lines ... :P
13:09:30 <ski> the right neutral element law, `mx >>= return = mx' (or `mx >>= \x -> return x = mx') just says that if you execute `mx', getting result `x' say, and then execute `return x', then that's the same as only executing `mx', since the effects are only those of `mx', and the monadic result is also the same
13:09:48 <bwe> Postorder looks now like
13:09:48 <bwe> tickS >>= (\z -> return $ (Branch (z, x)) _l' _r'
13:10:11 <bwe> my approach is similar to the one we did in tickS'
13:10:13 <ski> so, if you end a `do'-sequence with something that's not a call to `return', some `blah', you can always replace that by naming the result, `x <- blah', and then doing `return x'
13:10:51 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711)
13:10:59 <ski> bwe : right. so you also need to perform the actions of the two recursive calls
13:13:18 falafel_ joins (~falafel@62.175.113.194.dyn.user.ono.com)
13:16:16 <bwe> _l' is `Tree (Int, a)` but enumerateTreeFrom returns `State Int (Tree (Int, a))`
13:16:34 <ski> yes
13:16:47 <bwe> State s a -- I just want the a, out of the monad
13:16:54 <ski> hehee :)
13:17:10 <bwe> I am thinking of <$> _ <*> _
13:17:23 <ski> you don't get it out of the monadic, you put the consumer of the result inside the monadic action
13:17:29 <ski> that's what `>>=' is *for*
13:17:52 <bwe> it's the parentheses again, right
13:17:53 <ski> @quote /bin/ls
13:17:53 <lambdabot> shachaf says: getLine :: IO String contains a String in the same way that /bin/ls contains a list of files
13:18:00 <ski> could be ?
13:19:06 <ski> (and yea, you could also use `<$>' and `<*>' .. although that'd be simpler for the preorder case (due to the ordering of parameters to the internal node constructor for trees) .. but currently we're considering the `Monad' combinators, not the `Applicative' ones)
13:19:51 × geekosaur quits (sid609282@xmonad/geekosaur) (Server closed connection)
13:19:57 <ski> (that node constructor you apparently renamed to `Branch', i see)
13:20:00 geekosaur joins (sid609282@xmonad/geekosaur)
13:20:16 × L29Ah quits (~L29Ah@wikipedia/L29Ah) (Ping timeout: 268 seconds)
13:22:19 × Inst quits (~Inst@120.244.192.250) (Ping timeout: 256 seconds)
13:22:23 <bwe> enumarateTreeFrom l (and r) goes before >>= return $ Branch ...
13:22:35 <bwe> Branch is the consumer
13:22:36 <ski> yep
13:24:35 <bwe> tickS >>= (\z -> enumerateTreeFrom l >>= (\l' -> enumerateTreeFrom r >>= ( \r' -> return $ (Branch (z, x) l' r'))))
13:24:41 <bwe> wow it compiles
13:24:47 bwe throws confetti
13:24:58 <ski> (note that a `State Int (Tree (Int,a))' does *not* really contain a `Tree (Int,a)'. at least not unless you're prepared to say that `reverse' contains `[7,5,3,2]', because that's what `reverse [2,3,5,7]' computes. in `State s a', `a' is the type of monadic results that you get, *if* you feed a starting state of type `s' into the action. you can rerun the same action many times, with different starting
13:25:04 <ski> states, getting possibly different `a's as results)
13:25:07 <ski> bwe : ok, that's preorder
13:25:30 <bwe> let's move it to the right place
13:25:45 <ski> tickS >>= (\z ->
13:25:49 <ski> enumerateTreeFrom l >>= (\l' ->
13:25:52 <ski> enumerateTreeFrom r >>= (\r' ->
13:25:55 waleee joins (~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
13:26:13 <ski> return (Branch (z,x) l' r') )))
13:26:22 <ski> or
13:26:28 <ski> tickS >>= \z ->
13:26:31 <ski> enumerateTreeFrom l >>= \l' ->
13:26:34 <ski> enumerateTreeFrom r >>= \r' ->
13:26:36 <ski> return (Branch (z,x) l' r')
13:26:45 <ski> which is the same as
13:26:50 <ski> do z <- tickS
13:26:59 <ski> l' <- enumerateTreeFrom l
13:27:03 <ski> r' <- enumerateTreeFrom r
13:27:09 <ski> return (Branch (z,x) l' r')
13:28:06 <ski> now, you *could* without too much clutter do this one (preorder), with `<$>' and `<*>' in place of `>>='
13:28:15 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Quit: = "")
13:28:20 <ski> btw, if you have
13:28:26 <ski> _ <- put (x + 1)
13:28:33 <ski> i said you could simply write a command
13:28:36 <ski> put (x + 1)
13:28:42 <ski> this actually gets translated to
13:28:53 <ski> put (x + 1) >>
13:28:56 <ski> rather than to
13:29:03 <ski> put (x + 1) >>= \_ ->
13:29:09 <ski> but the meaning is the same
13:29:43 Feuermagier is now known as Guest6499
13:29:43 Feuermagier joins (~Feuermagi@user/feuermagier)
13:29:52 <ski> (you can define `(>>)' as well, when you're making an instance of `Monad'. occasionally, it might be a little bit more efficient to use `>>' over `>>=')
13:30:15 × Simikando quits (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 256 seconds)
13:30:55 × gtdg quits (~gtdg@user/gtdg) (Quit: Client closed)
13:32:07 <bwe> ski: https://gist.github.com/benjaminweb/ea91583983f5eceb10549ed25db03ec4#file-monadt-hs-L108-L112
13:32:14 <bwe> what do you seeV
13:32:15 <bwe> ?
13:32:26 × Guest6499 quits (~Feuermagi@user/feuermagier) (Ping timeout: 260 seconds)
13:33:40 <ski> looks okay
13:34:33 × falafel_ quits (~falafel@62.175.113.194.dyn.user.ono.com) (Ping timeout: 246 seconds)
13:35:28 <bwe> what would be the next step to undertake after a break I am taking?
13:35:56 Inst joins (~Inst@120.244.192.250)
13:37:26 <ski> btw, if you want another monadic task on trees, you could try checking that a tree with number elements is a "mobile". a "mobile" here is a kind of spatial toy. imagine a horizontal bar, hanging from a string attached at some position on it. then, at each end of the bar, you have a new string hanging down, from which another submobile hangs. until you eventually get to the "leaves", where there's just some
13:37:32 <ski> weight hanging from the string
13:38:01 × Logio quits (em@kapsi.fi) (Server closed connection)
13:38:09 Logio joins (em@kapsi.fi)
13:38:28 <ski> so, for such a tree, you need to record the (horizontal) length to the left subtree and the length to the right subtree. and for leaves, how much weight is attached there. then this would be a task for the `Maybee' monad
13:38:30 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 260 seconds)
13:38:38 euleritian joins (~euleritia@dynamic-002-247-251-218.2.247.pool.telefonica.de)
13:39:15 <ski> bwe : well, you could try using `<$>' and `<*>' for the preorder case of `enumerateTreeFrom', if you want to (although we've talked about `Monad', not `Applicative' really)
13:39:28 <ski> or you could try the mobile one, if it sounds interesting
13:39:57 <bwe> dminuoso: where were you heading me towards?
13:40:08 <bwe> ski: the mobile sounds interesting, though
13:40:18 Simikando joins (~Simikando@adsl-dyn216.91-127-84.t-com.sk)
13:40:43 <probie> Does anyone here have strong opinions on http client libraries? Are there any real alternatives to Snoyman's?
13:40:54 <ski> or you could try to tackle both state and failure at the same time (what you started with asking, yesterday, at least when i entered the conversation (i later saw you had talked some more before, but i didn't check the details))
13:41:13 <bwe> probie: my default is req
13:42:09 <ski> see e.g. <https://upload.wikimedia.org/wikipedia/commons/8/88/Mobile_titled_%22Doppler%22_by_Julie_Frith.jpg> and <https://en.wikipedia.org/wiki/Mobile_(sculpture)>
13:43:54 × jmdaemon quits (~jmdaemon@user/jmdaemon) (Ping timeout: 256 seconds)
13:44:25 <bwe> ski: thanks for taking me here!
13:44:40 <ski> bwe : oh, and eventually, i'd also like to point you not only in the direction of those Wadler papers i mentioned yesterday, but also
13:44:43 <ski> @where Typeclassopedia
13:44:44 <lambdabot> http://www.haskell.org/haskellwiki/Typeclassopedia
13:44:46 <ski> @where AAM
13:44:46 <lambdabot> http://www.haskell.org/haskellwiki/All_About_Monads
13:45:47 <ski> Typeclassopedia has many useful exercises to whet your appetite on, to better understand these concepts (and more)
13:46:23 <probie> bwe: req is implemented on top of Snoyman's libraries. I'm mainly just wondering if there's some "low level" alternative that I've missed
13:48:59 <ski> bwe : oh, and it's my delight
13:49:06 × Rembane quits (~Rembane@li346-36.members.linode.com) (Server closed connection)
13:49:13 Rembane joins (~Rembane@li346-36.members.linode.com)
13:50:59 <ddellacosta> probie: well, if you want low-level, req and wreq both sit on top of https://hackage.haskell.org/package/http-client
13:53:33 × danse-nr3 quits (~danse@151.43.161.172) (Read error: Connection reset by peer)
13:54:34 danse-nr3 joins (~danse@151.57.198.230)
13:59:08 <probie> ddellacosta: my problem is that I'm trying to avoid the `tls` package, and `http-client-tls` uses that
13:59:09 × Simikando quits (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 256 seconds)
13:59:43 × targetdisk quits (~daemonchi@45-33-4-162.ip.linodeusercontent.com) (Server closed connection)
13:59:51 targetdisk joins (~daemonchi@45-33-4-162.ip.linodeusercontent.com)
13:59:52 Simikando joins (~Simikando@adsl-dyn216.91-127-84.t-com.sk)
14:02:10 × zetef quits (~quassel@95.77.17.251) (Remote host closed the connection)
14:03:35 <ddellacosta> oooh yeah I'm not sure you're going to be able to avoid TLS with any commonly used HTTP clients. I think the botan folks are working on a replacement now though?
14:03:42 <ddellacosta> the tls lib I mean
14:04:03 <ddellacosta> not that it helps you now
14:04:13 × acidjnk quits (~acidjnk@p200300d6e72b9344700ee309897754f9.dip0.t-ipconnect.de) (Ping timeout: 260 seconds)
14:05:23 × alp_ quits (~alp@2001:861:5e02:eff0:6102:872f:f333:fe94) (Ping timeout: 256 seconds)
14:05:34 × Simikando quits (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 260 seconds)
14:06:19 <ddellacosta> probie: an opinion I read recently https://discourse.haskell.org/t/haskell-http-s-libraries-dont-work-well/8087/4
14:06:28 alp_ joins (~alp@2001:861:5e02:eff0:ab2f:dcd1:5fa1:c307)
14:07:31 <ddellacosta> that thread in general is probably useful for info about the state of HTTP clients in Haskell, wrt tls in particular
14:08:03 × waleee quits (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 268 seconds)
14:08:07 <probie> I might see if I can get http-client to play with BearSSL
14:08:44 <ddellacosta> good luck!
14:09:08 ChaiTRex joins (~ChaiTRex@user/chaitrex)
14:10:06 <danse-nr3> % :t (.)
14:10:06 <yahb2> (.) :: (b -> c) -> (a -> b) -> a -> c
14:10:20 <danse-nr3> % :t (+) . (+1)
14:10:20 <yahb2> (+) . (+1) :: Num b => b -> b -> b
14:10:28 <danse-nr3> % :t (-1) . (+) . (+1)
14:10:28 <yahb2> (-1) . (+) . (+1) :: (Num b, Num ((b -> b) -> c)) => b -> c
14:11:23 <danse-nr3> .oO(i lost an argument with the last one)
14:17:54 <danse-nr3> ops, - is special
14:17:55 <danse-nr3> % :t (+1) . (+) . (+1)
14:17:55 <yahb2> (+1) . (+) . (+1) :: (Num b, Num (b -> b)) => b -> b -> b
14:18:40 <danse-nr3> something tells me this is not going to work either...
14:18:41 nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net)
14:23:30 <probie> Are you trying to get something equivalent to `\x y -> (x + 1) + (y + 1)`?
14:23:46 × nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 260 seconds)
14:24:16 thegeekinside joins (~thegeekin@189.180.53.210)
14:25:54 <danse-nr3> nevermind, i used composition on a function with multiple arguments, then used composition again trying to affect its /result/. Out of habit piggybacking compositions one after the other, i guess. I forgot that composition cannot be used to affect the result of functions with multiple arguments
14:28:41 <exarkun> well, not with `.`. but see Data.Composition.
14:29:05 <danse-nr3> >:-D
14:29:23 <danse-nr3> well, possibly will be not as >:-D as compositions of dots, let us see
14:31:45 <danse-nr3> oh yeah, had looked that before and then forgot, possibly for the best :P ... thanks anyway for the pointer!
14:35:41 × Buggys quits (Buggys@Buggy.shelltalk.net) (Ping timeout: 240 seconds)
14:38:04 <danse-nr3> i think i will use it actually, hoping other people will not frown about it
14:39:41 wroathe joins (~wroathe@207-153-38-140.fttp.usinternet.com)
14:39:41 × wroathe quits (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
14:39:41 wroathe joins (~wroathe@user/wroathe)
14:44:00 Buggys joins (Buggys@Buggy.shelltalk.net)
14:48:30 × danse-nr3 quits (~danse@151.57.198.230) (Ping timeout: 256 seconds)
14:49:27 danse-nr3 joins (~danse@151.57.198.230)
14:55:30 × alp_ quits (~alp@2001:861:5e02:eff0:ab2f:dcd1:5fa1:c307) (Quit: Leaving)
15:00:02 × szkl quits (uid110435@id-110435.uxbridge.irccloud.com) (Quit: Connection closed for inactivity)
15:07:12 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Ping timeout: 256 seconds)
15:07:48 L29Ah joins (~L29Ah@wikipedia/L29Ah)
15:08:06 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 260 seconds)
15:09:13 × welterde quits (welterde@thinkbase.srv.welterde.de) (Server closed connection)
15:09:57 welterde joins (welterde@thinkbase.srv.welterde.de)
15:10:55 fweht joins (uid404746@id-404746.lymington.irccloud.com)
15:17:53 × xstill_ quits (xstill@fimu/xstill) (Server closed connection)
15:17:54 × Inst quits (~Inst@120.244.192.250) (Ping timeout: 260 seconds)
15:18:13 xstill_ joins (xstill@fimu/xstill)
15:19:54 glguy_ is now known as glguy
15:20:31 vglfr joins (~vglfr@78.26.242.160)
15:26:09 Inst joins (~Inst@120.244.192.250)
15:26:21 × vglfr quits (~vglfr@78.26.242.160) (Quit: Quit)
15:26:44 vglfr joins (~vglfr@78.26.242.160)
15:30:06 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
15:34:29 erty joins (~user@user/aeroplane)
15:37:20 × noctux quits (~noctux@user/noctux) (Read error: Connection reset by peer)
15:39:42 noctux joins (~noctux@user/noctux)
15:40:41 Simikando joins (~Simikando@adsl-dyn216.91-127-84.t-com.sk)
15:45:21 × micro quits (~micro@user/micro) (Server closed connection)
15:45:28 micro joins (~micro@user/micro)
15:45:47 lhpitn_ joins (~tn@193.96.224.66)
15:48:12 × vpan quits (~vpan@mail.elitnet.lt) (Quit: Leaving.)
15:49:38 × lhpitn quits (~tn@193.96.224.66) (Ping timeout: 260 seconds)
15:50:55 idgaen joins (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
15:53:46 × ChaiTRex quits (~ChaiTRex@user/chaitrex) (Quit: ChaiTRex)
15:53:51 × misterfish quits (~misterfis@87.215.131.102) (Ping timeout: 246 seconds)
15:55:15 × Typedfern quits (~Typedfern@220.red-83-37-25.dynamicip.rima-tde.net) (Server closed connection)
15:55:38 Typedfern joins (~Typedfern@220.red-83-37-25.dynamicip.rima-tde.net)
15:58:06 mechap joins (~mechap@user/mechap)
15:58:26 × lortabac quits (~lorenzo@2a01:e0a:541:b8f0:710e:fea0:5caf:9833) (Quit: WeeChat 3.5)
15:58:27 zetef joins (~quassel@95.77.17.251)
16:00:48 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
16:01:17 × bgamari_ quits (~bgamari@64.223.173.10) (Server closed connection)
16:02:36 bgamari joins (~bgamari@64.223.173.10)
16:03:18 × mechap quits (~mechap@user/mechap) (Ping timeout: 246 seconds)
16:03:38 ChaiTRex joins (~ChaiTRex@user/chaitrex)
16:03:43 × rubin55 quits (sid175221@id-175221.hampstead.irccloud.com) (Server closed connection)
16:04:01 rubin55 joins (sid175221@id-175221.hampstead.irccloud.com)
16:05:24 mechap joins (~mechap@user/mechap)
16:10:29 × kimiamania46 quits (~b4f4a2ab@user/kimiamania) (Ping timeout: 240 seconds)
16:12:18 × driib5 quits (~driib@vmi931078.contaboserver.net) (Server closed connection)
16:12:52 driib5 joins (~driib@vmi931078.contaboserver.net)
16:14:34 × davetapley quits (sid666@id-666.uxbridge.irccloud.com) (Server closed connection)
16:14:44 davetapley joins (sid666@id-666.uxbridge.irccloud.com)
16:15:44 kimiamania46 joins (~65804703@user/kimiamania)
16:15:54 × zetef quits (~quassel@95.77.17.251) (Ping timeout: 246 seconds)
16:16:56 zetef joins (~quassel@95.77.17.251)
16:19:29 × kimiamania46 quits (~65804703@user/kimiamania) (Client Quit)
16:20:29 kimiamania46 joins (~65804703@user/kimiamania)
16:24:06 × Franciman quits (~Franciman@mx1.fracta.dev) (Server closed connection)
16:24:19 Franciman joins (~Franciman@mx1.fracta.dev)
16:25:00 × kimiamania46 quits (~65804703@user/kimiamania) (Client Quit)
16:25:21 × lisbeths quits (uid135845@id-135845.lymington.irccloud.com) (Quit: Connection closed for inactivity)
16:26:23 × todi quits (~todi@p4fd1a3e6.dip0.t-ipconnect.de) (Ping timeout: 260 seconds)
16:26:39 × akegalj quits (~akegalj@141-136-147-15.dsl.iskon.hr) (Quit: leaving)
16:26:42 kimiamania46 joins (~65804703@user/kimiamania)
16:30:05 × Simikando quits (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Remote host closed the connection)
16:30:18 × pierrot quits (~pi@user/pierrot) (Server closed connection)
16:30:25 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711)
16:30:27 Simikando joins (~Simikando@adsl-dyn216.91-127-84.t-com.sk)
16:30:35 pierrot joins (~pi@user/pierrot)
16:30:44 × Unode quits (~Unode@fg-ext-220.embl.de) (Server closed connection)
16:30:56 Unode joins (~Unode@fg-ext-220.embl.de)
16:38:23 × Simikando quits (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 256 seconds)
16:39:29 Simikando joins (~Simikando@adsl-dyn216.91-127-84.t-com.sk)
16:40:08 × ddellacosta quits (~ddellacos@ool-44c738de.dyn.optonline.net) (Ping timeout: 256 seconds)
16:49:30 Sgeo joins (~Sgeo@user/sgeo)
16:49:53 × __monty__ quits (~toonn@user/toonn) (Quit: leaving)
16:51:59 lhpitn joins (~tn@ipv6-2d1e9090b42fa986.nowe.clients.hamburg.freifunk.net)
16:54:58 × lhpitn_ quits (~tn@193.96.224.66) (Ping timeout: 260 seconds)
16:57:18 acidjnk joins (~acidjnk@p200300d6e72b9344349e196aee999b14.dip0.t-ipconnect.de)
17:00:06 × zetef quits (~quassel@95.77.17.251) (Ping timeout: 260 seconds)
17:02:18 ddellacosta joins (~ddellacos@ool-44c738de.dyn.optonline.net)
17:02:51 × cawfee_ quits (~root@2406:3003:2077:2758::babe) (Server closed connection)
17:03:11 cawfee_ joins (~root@2406:3003:2077:2758::babe)
17:04:18 × Simikando quits (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 260 seconds)
17:05:20 econo_ joins (uid147250@id-147250.tinside.irccloud.com)
17:09:28 × AlexZenon quits (~alzenon@178.34.162.228) (Ping timeout: 255 seconds)
17:09:39 × jbalint quits (~jbalint@071-090-119-177.res.spectrum.com) (Server closed connection)
17:09:50 jbalint joins (~jbalint@2600:6c44:117f:e98a:816a:9488:fb1:7b7)
17:11:02 × mjrosenb_ quits (~mjrosenb@pool-96-232-177-77.nycmny.fios.verizon.net) (Server closed connection)
17:11:11 mjrosenb joins (~mjrosenb@pool-96-232-177-77.nycmny.fios.verizon.net)
17:13:28 × dispater quits (~dispater@mail.brprice.uk) (Server closed connection)
17:13:39 × machinedgod quits (~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 246 seconds)
17:13:42 × glider quits (~glider@user/glider) (Server closed connection)
17:13:48 dispater joins (~dispater@mail.brprice.uk)
17:13:50 × pavonia quits (~user@user/siracusa) (Quit: Bye!)
17:15:14 zetef joins (~quassel@95.77.17.251)
17:15:34 <erty> thanks to laziness this both lines of code takes equal time: λ> putStrLn.show.length $ init.drop 1 $ take 5 ([x | x <- [1..50000000],odd x] :: [Int])
17:15:41 <erty> λ> putStrLn.show.length $ ([1..5] :: [Int])
17:15:54 tzh joins (~tzh@c-71-193-181-0.hsd1.or.comcast.net)
17:16:18 glider joins (~glider@user/glider)
17:16:28 _ht joins (~Thunderbi@28-52-174-82.ftth.glasoperator.nl)
17:16:41 <ski> yea
17:16:43 <ski> @src print
17:16:43 <lambdabot> print x = putStrLn (show x)
17:16:48 × hippoid quits (~hippoid@c-98-213-162-40.hsd1.il.comcast.net) (Ping timeout: 246 seconds)
17:17:12 hippoid joins (~hippoid@c-98-213-162-40.hsd1.il.comcast.net)
17:17:20 <erty> ski: thanks I did not know about `print`
17:18:17 ski figured
17:20:05 AlexZenon joins (~alzenon@178.34.162.228)
17:21:21 × tzh quits (~tzh@c-71-193-181-0.hsd1.or.comcast.net) (Ping timeout: 246 seconds)
17:21:34 × lhpitn quits (~tn@ipv6-2d1e9090b42fa986.nowe.clients.hamburg.freifunk.net) (Ping timeout: 260 seconds)
17:26:22 tzh joins (~tzh@c-71-193-181-0.hsd1.or.comcast.net)
17:27:08 Simikando joins (~Simikando@adsl-dyn216.91-127-84.t-com.sk)
17:29:53 × chele quits (~chele@user/chele) (Quit: Leaving)
17:32:52 × euleritian quits (~euleritia@dynamic-002-247-251-218.2.247.pool.telefonica.de) (Read error: Connection reset by peer)
17:33:09 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
17:33:24 × Simikando quits (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 268 seconds)
17:39:03 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
17:39:25 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
17:40:40 × cstml quits (~cstml@user/cstml) (Quit: WeeChat 2.3)
17:43:17 cstml joins (~cstml@user/cstml)
17:44:08 × kuribas quits (~user@ip-188-118-57-242.reverse.destiny.be) (Remote host closed the connection)
17:44:53 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Remote host closed the connection)
17:45:10 × sord937 quits (~sord937@gateway/tor-sasl/sord937) (Remote host closed the connection)
17:46:50 sord937 joins (~sord937@gateway/tor-sasl/sord937)
17:47:39 misterfish joins (~misterfis@84-53-85-146.bbserv.nl)
17:47:42 × danse-nr3 quits (~danse@151.57.198.230) (Ping timeout: 260 seconds)
17:49:39 <dminuoso> In recent times I find myself more happy with the way lazyness is accomplished in languages like Ruby or Python. When you map over a list, you get some first class object representing an iterator.
17:49:47 × zetef quits (~quassel@95.77.17.251) (Ping timeout: 256 seconds)
17:50:01 <dminuoso> It's much more enjoyable when you can visibly trace and control where lazyness occurs
17:50:02 × fendor quits (~fendor@2a02:8388:1640:be00:2528:5dc7:a36e:9b87) (Ping timeout: 260 seconds)
17:50:03 <duncan> You like that? That behaviour enrages me
17:50:05 wroathe joins (~wroathe@207-153-38-140.fttp.usinternet.com)
17:50:06 × wroathe quits (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
17:50:06 wroathe joins (~wroathe@user/wroathe)
17:50:42 × fweht quits (uid404746@id-404746.lymington.irccloud.com) (Quit: Connection closed for inactivity)
17:50:48 Simikando joins (~Simikando@adsl-dyn216.91-127-84.t-com.sk)
17:51:12 <dminuoso> duncan: It seems preferrable to when it invisibly happens across your entire program, except when it doesnt.
17:51:44 <exarkun> How about when you accidentally try to iterate a map twice and you just get no elements the second time
17:52:02 <exarkun> So you're forced to consume the whole thing before the first iteration and lose all laziness
17:52:37 <dminuoso> exarkun: You are not?
17:52:51 <dminuoso> You can map over iterables in Python and Ruby.
17:52:52 <exarkun> Haskell could use more accessible debugging and introspection tools but I don't think "give laziness program-level visible semantic changes" is a great route.
17:52:52 <EvanR> at least we're not as bad as clojure which mixes both
17:53:24 <exarkun> dminuoso: We might be talking past each other. I meant the thing you get back from `map`.
17:53:34 <exarkun> dminuoso: But more generally, the iterator protocol has no guarantee of reusability.
17:53:36 <dminuoso> exarkun: Yes, you can write map(foo, map(foo, [1,2,3])) just fine.
17:53:55 <exarkun> dminuoso: Right - but that only consumes each `map` result once. I mean `x = map(f, g); y(x); y(x)`
17:54:26 <exarkun> dminuoso: It destroys the ability to reason locally about code which I usually frown on.
17:54:31 <dminuoso> Oh you mean there is non sharing, yes.
17:54:44 <dminuoso> The thing is just, lazyness in Haskell is not a built-in feature.
17:54:53 <dminuoso> It's in reality just a lose and unwritten promise of GHC.
17:55:42 <dminuoso> At best we are all relying on GHC doing hidden magic and sprinkling lazyness on the right places, doing monomorphism on other right places where you really dont want lazyness/indirection, and strictness analyzer kicking in on those tight loops.
17:55:43 <EvanR> are you doubting the normal order evaluation
17:55:50 <dminuoso> But nothing is ever really under your control
17:55:52 <EvanR> which guarantees that if there is a normal form, it will find it
17:56:00 × misterfish quits (~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 246 seconds)
17:56:35 <dminuoso> Haskell by its very definition is not lazy, its only non-strict.
17:56:54 <dminuoso> If we assume the Haskell reports to be some valuable sense of definition, anyway
17:57:12 <dminuoso> I just greatly dislike lazyness being so implicit and hidden away.
17:57:19 <dminuoso> You can notice the pain with this with unsafeInterleaveIO
17:57:33 <dminuoso> There's good reason why we *all* immediately switch to streaming libraries
17:57:37 <EvanR> I'm glad you finally got around to that, you're trying to do I/O
17:57:43 <dminuoso> No, not just IO.
17:58:07 <dminuoso> Im suggesting we use streaming libraries precisely because its not clear where sharing happens, where lazyness happens, how its unraveled.
17:58:24 <EvanR> so you agree with a hypothetical type called stream(a) and a map operation of type (a -> b) -> stream(a) -> stream(b) which works lazily
17:58:27 <dminuoso> Why we just silently accept it in all the pure parts instead is a bit strange.
17:58:33 <EvanR> er, do you agree
17:58:36 <dminuoso> Perhaps its because at least the result should always be the same
17:59:11 <dminuoso> EvanR: So if I agree, I want to emphasize I dont want to have discussions about implications on type inference or the type system in general.
17:59:13 <EvanR> ok you're really concerned about guarantees (or not) about when sharing happens
17:59:32 <dminuoso> Sure, or where lazyness occurs.
17:59:34 misterfish joins (~misterfis@84-53-85-146.bbserv.nl)
17:59:36 <EvanR> that part is definitely not in the report
17:59:53 <dminuoso> Like, seq is often too shallow, deepseq is often too strict.
18:00:42 <dminuoso> You get around this by carefully analyzing your expressions, and introducing arbitrary data structures that deepseq wont pierce. But that's really just shoehorning execution control into some implicit semantics
18:01:16 <EvanR> I haven't had a problem is understanding when laziness happens
18:01:18 <dminuoso> Another thing is, you really dont see when things are strict.
18:01:29 <dminuoso> I give you `f :: Int -> Int -> [Int] -> [Int]`
18:01:39 <dminuoso> Do you know whether it will force the spine? Will it force the numbers?
18:01:41 <dminuoso> Who knows
18:02:03 <dminuoso> Look at the implementation, because strictness is rarely documented well
18:02:08 <monochrom> I come from a completely different angle. I would like the standard to specify two things: what answer you get (the Haskell Report has almost done it), and how much time and space it costs at most. Then the standard won't need to commit to a particular evaluation strategy.
18:03:00 <EvanR> that won't help with the last point, documenting somehow the behavior of library code
18:03:24 <monochrom> "take 1 (map f [1..]) is O(1) time, print [1..] is O(1) space" are some pretty reasonable expectations despite how the Report currently doesn't "guarantee" it.
18:03:45 <EvanR> but guaranteeing quality of library code sounds like some next level shit
18:04:23 <EvanR> maybe in 10 years it will be moot because AI writes all your documentation
18:04:37 × natto quits (~natto@129.154.243.159) (Server closed connection)
18:05:19 <dminuoso> monochrom: Haskellers are quite adept at not documenting anything. The number of libraries that documents time _and_ space usage is extremely limited. Possible exceptions, none. In some sad sense, its the curse of the type system.
18:05:41 <dminuoso> Because a type signature lets you infer so much, it gives incentive to not write haddock docs.
18:05:53 <monochrom> Well, it is actually more widespread than that.
18:06:06 <monochrom> Look around all language standards.
18:06:16 <EvanR> libraries in web land which have no documentation nor type signatures xD
18:06:29 <EvanR> at best a readme with 1 example
18:06:29 analoq joins (~yashi@user/dies)
18:06:42 <monochrom> Only C++ STL bothers to write "map lookup is lg time".
18:07:54 <monochrom> And only SML uses the overkill of pinning down the operational semantics to help you with time and space (and effect order, perhaps most importantly).
18:08:03 natto joins (~natto@129.154.243.159)
18:08:20 <monochrom> All other language standards simply leave it unsaid.
18:08:28 <int-e> `containers` is one of the libraries that does document time complexity of most functions.
18:08:59 <EvanR> I think it also explains uh "strictness"
18:09:13 <EvanR> if that's even the right word
18:09:24 <EvanR> "does this evaluate your stuff"
18:10:42 × Square2 quits (~Square4@user/square) (Ping timeout: 246 seconds)
18:11:34 johnw joins (~johnw@69.62.242.138)
18:11:39 <monochrom> I don't think you can even infer, from the C standard, that "x = 1;" is constant time. Instead, it has been competition that drove time costs down. If some compiler makes it, I don't know, exponential time, no one will use it. But it is legal.
18:12:36 × smalltalkman quits (uid545680@id-545680.hampstead.irccloud.com) (Server closed connection)
18:12:45 smalltalkman joins (uid545680@id-545680.hampstead.irccloud.com)
18:13:28 <monochrom> And then in the case of Perl and Python, we are simply grateful that their dictators did not make you suffer.
18:13:41 <EvanR> much
18:14:43 × Simikando quits (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 256 seconds)
18:15:12 <monochrom> In Haskell, 99% of my reason to assume lazy evaluation is just because I want to state time and space costs. I don't really care otherwise.
18:15:31 <monochrom> The other 1% is just to give a concrete model when teaching.
18:16:00 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711)
18:16:20 <EvanR> it would be an awful choice if someone said you can have 10 pages of essay docs on each function like python, or you can have the type signature, it would be a terrible choice. But the frustration of the first one when you just want the type signature is great
18:16:49 <EvanR> I would settle for type sigs and a minor amount of docs
18:17:02 <EvanR> which a lot of stuff that I've used on hackage has
18:17:38 <probie> If the type sig and mediocre docs don't suffice, just look at the source. It's pretty reliable documentation
18:17:48 <monochrom> Clearly, it should be a 10-page essay and a 10-page type sig. Haven't you seen, like, servant and lens? >:)
18:18:52 Square joins (~Square@user/square)
18:19:31 Simikando joins (~Simikando@adsl-dyn216.91-127-84.t-com.sk)
18:19:40 <EvanR> in that case just make it a 10-page type sig
18:19:53 <EvanR> soup up the type system to support everything you need to say
18:20:06 <geekosaur> and a 10-page error message when you make a mistake, like C++
18:20:11 nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net)
18:20:21 <geekosaur> enterprise grade
18:20:50 <probie> I have vague recollections of reading a paper on including time complexity in types in agda
18:21:02 <darkling> No, Enterprise-grade is 10-page function names, like Java.
18:21:33 <monochrom> We can surely do all of the above. :)
18:22:05 Tuplanolla joins (~Tuplanoll@91-159-68-236.elisa-laajakaista.fi)
18:23:01 <probie> I'm 95% sure it was this https://projekter.aau.dk/projekter/files/335444832/pt101f20thesis.pdf
18:24:21 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 256 seconds)
18:24:35 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Remote host closed the connection)
18:24:44 euleritian joins (~euleritia@dynamic-002-247-251-218.2.247.pool.telefonica.de)
18:24:50 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711)
18:24:58 <EvanR> monochrom, you could use the competition card to solve anything. Library has zero documentation? No one would use it right??
18:25:02 × nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 260 seconds)
18:25:30 × misterfish quits (~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 260 seconds)
18:26:06 <monochrom> Heh.
18:26:27 <monochrom> But let me go bonkers on this.
18:27:18 <monochrom> For time costs, the competition is a simple one between compiler vendors, given that most vendors are commercial and actually need to beg for business.
18:28:11 <monochrom> Libraries have two opposing competitions, even if commercial. Getting users on board, vs the users themselves wanting job security via barrier to entrance.
18:29:00 <EvanR> job security through obscurity
18:29:18 lg188 joins (~lg188@82.18.98.230)
18:30:02 <monochrom> Ever wonder why all the senior experienced engineers are so smug about "this is field experience you won't learn from school"?
18:30:18 <monochrom> I bet 80% of their experience are teachable in school.
18:30:31 <monochrom> But where is the fun if school actually teaches it?
18:30:31 × mjacob quits (~mjacob@adrastea.uberspace.de) (Read error: Connection reset by peer)
18:30:49 <mauke> teachable, sure. but taught?
18:31:37 <monochrom> I am exactly hypothesizing when it is not taught: No incentive to, actually much incentive against.
18:31:43 <monochrom> s/when/why/
18:31:57 <Inst> hmmm
18:32:28 <probie> Only 80%? I don't think I've learnt anything job related that can't be explicitly taught (although some of it would sound _very_ cynical to students if explicitly taught)
18:33:28 L29Ah parts (~L29Ah@wikipedia/L29Ah) ()
18:34:24 <Inst> to someone new to computer science, would you recommend, as an adjunct to Thinking Functionally in Haskell, HaskellBook or Effective Haskell?
18:35:14 jathan joins (~jathan@69.61.93.38)
18:35:20 <Inst> ehh, i've answered my own question, effective haskell is probably the better book
18:35:40 Unicorn_Princess joins (~Unicorn_P@user/Unicorn-Princess/x-3540542)
18:35:57 <EvanR> affirming the consequent, haskell logic
18:36:37 mjacob joins (~mjacob@adrastea.uberspace.de)
18:36:55 × lg188 quits (~lg188@82.18.98.230) (Quit: Bye.)
18:37:24 × kawzeg_ quits (kawzeg@2a01:7e01::f03c:92ff:fee2:ec34) (Server closed connection)
18:37:25 <EvanR> I still think the haskell course notes with exercises beat any book if you want to get into it
18:37:43 kawzeg_ joins (kawzeg@2a01:7e01::f03c:92ff:fee2:ec34)
18:38:00 × stefan-_ quits (~cri@42dots.de) (Server closed connection)
18:38:04 <EvanR> https://www.seas.upenn.edu/~cis1940/fall16/index.html ?
18:38:16 stefan-_ joins (~cri@42dots.de)
18:38:33 <EvanR> Functional Reactive Programming Homework 11 xD
18:38:48 <Inst> I got a response from BadVortex
18:38:58 <probie> Inst: SICP, and then teach them Haskell later
18:39:13 <Inst> i'm recommending HTDP, SICP, Thinking Functionally with Hasklel, Effective Haskell, and need to pick up a Py book
18:39:23 × adamCS quits (~adamCS@ec2-34-207-160-255.compute-1.amazonaws.com) (Server closed connection)
18:40:09 adamCS joins (~adamCS@ec2-34-207-160-255.compute-1.amazonaws.com)
18:40:37 × cawfee_ quits (~root@2406:3003:2077:2758::babe) (Ping timeout: 268 seconds)
18:43:19 lg188 joins (~lg188@82.18.98.230)
18:43:20 <ski> (SICP using Scheme, rather than Javascript)
18:43:37 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 256 seconds)
18:43:44 <dolio> Did they rewrite SICP with javascript?
18:43:57 <EvanR> D:
18:44:03 target_i joins (~target_i@217.175.14.39)
18:44:18 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Remote host closed the connection)
18:44:53 cawfee_ joins (~root@2406:3003:2077:2758::babe)
18:46:57 × cstml quits (~cstml@user/cstml) (Quit: WeeChat 2.3)
18:49:10 <ski> "Structure and Interpretation of Computer Programs: JavaScript Edition (MIT Electrical Engineering and Computer Science)" by Martin Henz (Adapter),Tobias Wrigstad (Adapter),Harold Abelson (Author),Gerald Jay Sussman (Author),Julie Sussman (Contributor) in 2022-04-12 at <https://www.amazon.com/Structure-Interpretation-Computer-Programs-Engineering/dp/0262543230>
18:49:30 × thyriaen quits (~thyriaen@2a01:aea0:dd4:7550:6245:cbff:fe9f:48b1) (Remote host closed the connection)
18:51:38 <probie> Is it even the same book? Writing an interpreter and compiler for a subset of JS seems like it'd be a real challenge
18:52:21 × dcoutts quits (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 246 seconds)
18:52:51 <ski> .. no idea
18:55:09 <EvanR> if their version of js has proper tail calls I'd be interested
18:55:11 <ddellacosta> probie: "Chapters four and five, which used Scheme to formulate language processors for Scheme, required significant revision." https://mitpress.mit.edu/9780262543231/structure-and-interpretation-of-computer-programs/
18:55:45 <ddellacosta> sounds like they keep to the same topics though
18:56:00 <ddellacosta> with some additions?
19:01:15 × hololeap quits (~quassel@user/hololeap) (Server closed connection)
19:01:32 hololeap joins (~quassel@user/hololeap)
19:04:36 zer0bitz_ joins (~zer0bitz@user/zer0bitz)
19:05:04 <EvanR> how about haskell edition
19:08:19 × haskellbridge quits (~haskellbr@069-135-003-034.biz.spectrum.com) (Remote host closed the connection)
19:08:50 × zer0bitz quits (~zer0bitz@user/zer0bitz) (Ping timeout: 252 seconds)
19:10:00 haskellbridge joins (~haskellbr@069-135-003-034.biz.spectrum.com)
19:10:00 ChanServ sets mode +v haskellbridge
19:10:15 × Simikando quits (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 256 seconds)
19:11:38 × ChaiTRex quits (~ChaiTRex@user/chaitrex) (Remote host closed the connection)
19:11:40 <probie> Haskell would be even worse than JS if you want to keep chapter four and five (plus you'd probably need an additional chapter on type checking)
19:15:15 ChaiTRex joins (~ChaiTRex@user/chaitrex)
19:16:12 Simikando joins (~Simikando@adsl-dyn216.91-127-84.t-com.sk)
19:16:19 misterfish joins (~misterfis@84-53-85-146.bbserv.nl)
19:17:03 <dolio> Yeah, the advantage of Scheme is that the structures nominally used to represent the language are very simple, and already built into the language.
19:17:06 × ggVGc quits (~ggVGc@a.lowtech.earth) (Ping timeout: 256 seconds)
19:17:28 ggVGc joins (~ggVGc@a.lowtech.earth)
19:19:15 × euleritian quits (~euleritia@dynamic-002-247-251-218.2.247.pool.telefonica.de) (Read error: Connection reset by peer)
19:19:24 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711)
19:19:37 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
19:20:30 ft joins (~ft@p508db3bc.dip0.t-ipconnect.de)
19:23:28 <kaol> I find myself wishing for a variant of Data.List.NonEmpty that'd take two type variables, where the extra one would be data that lies between each element. So that NonEmpty' () a would be isomorphic to regular NonEmpty a.
19:23:41 × tomboy64 quits (~tomboy64@user/tomboy64) (Ping timeout: 240 seconds)
19:23:54 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 256 seconds)
19:24:50 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
19:28:23 × trev quits (~trev@user/trev) (Quit: trev)
19:29:08 tomboy64 joins (~tomboy64@user/tomboy64)
19:30:08 waleee joins (~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
19:31:39 × Simikando quits (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Remote host closed the connection)
19:35:16 <probie> As in something like `data NonEmpty' a b = Cons' a (NonEmpty'' a b); data NonEmpty'' a b = End | Cons'' b (NonEmpty' a b)`?
19:38:05 dcoutts joins (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net)
19:38:49 × pierrot quits (~pi@user/pierrot) (Read error: Connection reset by peer)
19:38:52 × Nixkernal quits (~Nixkernal@115.16.194.178.dynamic.wline.res.cust.swisscom.ch) (Quit: No Ping reply in 180 seconds.)
19:39:50 <kaol> I'm not quite sure about that representation. Basically I have one a and a list [(a,b)].
19:40:16 <monochrom> I think you should write it. :)
19:40:19 Nixkernal joins (~Nixkernal@115.16.194.178.dynamic.wline.res.cust.swisscom.ch)
19:40:49 <kaol> It's not too difficult to handle the list as a list and stick the extra a in front where needed.
19:41:22 <kaol> I can't build NonEmpty like a :| [(a,b)].
19:42:41 pierrot joins (~pi@user/pierrot)
19:44:03 × stilgart quits (~Christoph@chezlefab.net) (Server closed connection)
19:44:11 stilgart joins (~Christoph@chezlefab.net)
19:45:22 × SanchayanMaity quits (sid478177@id-478177.hampstead.irccloud.com) (Server closed connection)
19:45:32 SanchayanMaity joins (sid478177@id-478177.hampstead.irccloud.com)
19:49:58 <kaol> I guess I'll go with a list of type [(b,(a,a))]. Never mind me, just thinking on IRC.
19:50:57 thegman joins (~thegman@072-239-207-086.res.spectrum.com)
19:54:02 <ski> kaol : hm, reminds me of `data SkipList a b = Nil | Cons a (SkipList b a)'
19:54:42 <ski> but in your case, you always have one more `a's than `b's
19:56:06 <ski> (for `SkipList', there's either the same number of `a's as `b's (which are alternating, as in your case), or one more `a')
19:56:52 <monochrom> "<a href="https://en.wikipedia.org/wiki/Skip_list">This</a> is not the skip list you're looking for." >:)
19:57:09 <ski> hah, nah, not that one ;)
19:58:32 cheater_ joins (~Username@user/cheater)
19:58:33 <monochrom> We need an IETF central registry of data structure names, like they have one for domain names. :)
20:00:19 <ski> kaol : i'm also reminded of fenceposts vs. intervening fencestretches, "* --- * --- *". or stuff like dedekind cuts (dividing e.g. the rational number line into two halves (rays), to represent any real number), and reminded of zippers, where a zipper for `[a]' is `([a],a,[a])', being `(reversed_front,current,back)'. or if you're focusing on edges (vertical bar cursor) rather than nodes (block cursor), just
20:00:25 <mauke> we should also avoid homophones
20:00:25 <ski> `([a],[a])'
20:00:40 mauke annoyed that 'tree' and 'trie' are pronounced the same
20:00:48 <kaol> 1+2*3 isn't that far off from what I'm modeling.
20:01:38 <ski> hm, and Conor McBride had a paper for when you're traversing a collection, and say mapping as you go, you can have a zipper structure, with processed elements to your left, of type `b' say, and unprocessed elements to your right, of type `a'
20:01:45 <monochrom> But I don't model 1+2*3 as a list.
20:01:51 <ski> (and if you can map back, you could move back and forth)
20:02:08 <ski> iirc, this is the "Clowns to the left of me, Jokers to the right" paper ?
20:02:20 × cheater quits (~Username@user/cheater) (Ping timeout: 268 seconds)
20:02:26 <monochrom> OK I lied. Sometimes I do. Then I just use (1, [("+", 2), ("*", 3)]).
20:02:29 cheater_ is now known as cheater
20:03:24 <ski> "Clowns to the left of me, jokers to the right (Dissecting Data Structures)" by Conor McBride in 2006-10-02 at <http://strictlypositive.org/Dissect.pdf>
20:03:33 <kaol> [("+",(1,2)),("*",(2,3))]
20:04:19 <ski> kaol : wouldn't `[(b,(a,a))]' be something different from your NonEmpty' a b ?
20:04:27 <monochrom> And the only use case I have met is writing chainl1 to use foldl instead of its own recursion.
20:04:47 <ski> mauke : not more like "try-e" ?
20:05:10 <ski> kaol : oh .. you're duplicating intermediate nodes ?
20:05:14 <monochrom> more detailedly, chainl1 in terms of only Alternative and foldl, so that I don't have to use >>=.
20:05:35 <mauke> ski: it's called "trie" because it's a data structure optimized for re-trie-val :-(
20:05:35 <kaol> Good old zip xs $ tail xs
20:05:37 <monochrom> (I still need my own recursion.)
20:05:41 <ski> perhaps your expressions should be graphs, where the atomic components are the nodes, and the binary infix operators are edges ?
20:05:55 <ski> mauke : oh, TIL
20:06:13 <monochrom> ski: That one is also on Wikipedia. >:)
20:06:43 <ski> apparently i never bothered to look the etymology up
20:06:52 <ski> (but i had heard of the other type of skip list before)
20:07:04 <monochrom> I got curious one day. "trie" is such a strange name.
20:07:12 <ski> 'tis
20:07:29 <kaol> zip <*> tail if I'm feeling evil.
20:08:04 <ski> anyway this infix operator expression business makes me want to think about my idea of using composable continuations for parsing them
20:10:10 <ski> @quote aztec.god
20:10:10 <lambdabot> quicksilver says: zip`ap`tail - the Aztec god of consecutive numbers
20:10:20 <ski> (for the incognoscenti)
20:11:55 <erty> I've created this very simple algo to find min element in a list [http://ix.io/4LGC/haskell], does this looks good?
20:12:00 <erty> I mean, does those pattern matching statements supposed to go inside guard statements
20:12:26 <EvanR> data Chain a b = Node a | Link b (Chain a b)
20:12:35 <ski> monochrom : btw, if you have a total (say finite) order `n', and `n -> 2' is the characteristic morphisms (morphisms into the total order `2'), then this is `n + 1'
20:12:55 <monochrom> ski: In that case, have you seen "precedence climbing" or Pratt parsing? (E.g., https://www.engr.mun.ca/~theo/Misc/pratt_parsing.htm or its prequel https://www.engr.mun.ca/~theo/Misc/exp_parsing.htm )
20:13:04 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
20:13:14 × sord937 quits (~sord937@gateway/tor-sasl/sord937) (Quit: sord937)
20:13:32 <ski> EvanR : that's `([b],a)' .. sometimes useful thing, actually
20:14:00 <EvanR> no...
20:14:15 <ski> monochrom : i've heard the name, but haven't checked the details
20:14:19 <mauke> erty: I wouldn't have written it this way, but that looks correct
20:14:47 <EvanR> you can have more than one a in the chain
20:14:57 <ski> EvanR : or did you mean to flip the parameters in the recursion ?
20:15:05 <EvanR> no
20:15:28 <EvanR> er, but I did make a big mistake
20:15:39 <EvanR> data Chain a b = Node a | Link b (Chain a b) (Chain a b)
20:15:56 <ski> ah, that makes more sense then
20:16:11 <ski> ok, so it's a tree with one type of element in internal nodes, and another type at leaves
20:16:17 <EvanR> yeah
20:16:18 <monochrom> ski: I think if you have "upon seeing this operator, here is the continuation for parsing the rest of the input", then I think Pratt parsing is defunctionalization of that.
20:16:32 <erty> mauke: If I may ask, how you would have written that function :-), Thanks ?
20:16:44 <erty> *-?
20:16:52 <monochrom> Because it goes like "upon seeing this operator, here is the new precedence interval to parse for".
20:16:53 <EvanR> if you flatten it out it's like that puncuated list type from earlier
20:17:31 <monochrom> with the main loop being basically a case analysis on precedence interval.
20:17:38 <ski> monochrom : hm, i'll try to recall looking in that, for comparision
20:18:08 <mauke> erty: findMin [] = error "findMin: empty list"; findMin (x : xs) = go x xs where go m [] = m; go m (x : xs) = go (if x < m then x else m) xs
20:18:27 <mauke> erty: basically, pulling out the "current minimum" element into its own function parameter
20:18:46 <kaol> foldr1 min
20:18:54 <ski> erty : if i would be doing `findMin (x:xs)' recursive calls, i'd probably separate that into a worker that does `findMinCons x xs'
20:18:56 Pickchea joins (~private@user/pickchea)
20:19:03 <ski> (to avoid consing all the time)
20:19:04 <mauke> then I'd realize that 'if x < m then x else m' is just 'min x m'
20:19:30 <ski> EvanR : hmm, except that it also has nesting structure now
20:19:30 <mauke> and then the whole thing collapses into a fold, as kaol said :-)
20:19:37 <ski> EvanR : s/nesting/grouping/
20:19:45 <EvanR> "parentheses" ?
20:19:54 <ski> yea
20:19:59 <EvanR> you could say the basic list has that too...
20:20:08 <EvanR> x:(y:(z:...
20:20:20 <monochrom> ski: This is beautiful and evil at the same time that n+1 = 2^n for partial-order morphisms!
20:21:12 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
20:21:19 <EvanR> but in that case there's now way to represent the "same list" multiple ways
20:21:21 <ski> erty : i see mauke did what i had in mind. also, instead of using an accumulator, you *could* go direct style (say using `min') .. although that *would* use unbounded space
20:21:28 <monochrom> Also dangerously close to combinatorics which is the only area of math that I hate (because I fear it --- "fear begets hate" amirite?)
20:21:59 <EvanR> and hate begets unironic use of unsafeCoerce
20:22:11 <monochrom> fear leads to hate, hate leads to switching major to CS. :)
20:22:41 <ski> EvanR : yea, but basic lists are fully right-associated (`x * y * z' is `x * (y * (z * 1))'), but your `Chain' allows different associations
20:23:01 <mauke> CS - it's a gas
20:23:02 <ski> (number of associations of a list of length `n' is Catalan number)
20:23:35 <EvanR> I based it on the "JList" structure data JList a = Empty | Single a | Join (JList a) (JList a)
20:24:13 <erty> mauke: unfortunately ,that line looks complicated for me. I will save it and will analyze it later
20:24:14 <EvanR> which has even more equivalents
20:25:02 <ski> ah, `JList' is just an arbitrary expression with a nullary and a binary operation (not assumed to form a monoid), and with elements from some generating set
20:26:54 <ski> (and one could consider the variant to `data JList a = MkJList (Maybe (JNonEmpty a)); data JNonEmpty a = Single a | Join (JNonEmpty a) (JNonEmpty a)')
20:27:34 <EvanR> that is looking better in some sense
20:27:41 <ski> .. anyway, this `min' business makes me think of `min'-`max'ing in a lazy language. iirc "Why Functional Programming Matters" by John Hughes mention this ?
20:28:35 <monochrom> It does? I thought it was rambling on Newton's method only. >:)
20:29:07 <ski> oh, i guess i meant alpha-beta pruning
20:29:12 <ski> @where whyfp
20:29:12 <lambdabot> "Why Functional Programming Matters" by John Hughes in 1984 at <http://www.cse.chalmers.se/~rjmh/Papers/whyfp.html>
20:29:20 <erty> ski: In your previous comment to me, what do you mean by `unbounded` space?
20:29:54 <erty> min function would scan all elemetns of the list
20:29:57 <monochrom> OK yeah found it.
20:30:01 <mauke> erty: it looks a lot better with proper formatting :-)
20:30:11 <ski> erty : do you understand what i meant by "direct recursion", rather than accumulator ?
20:30:42 <ski> monochrom : p. 19
20:31:53 <erty> ski: No, I dont understand, but I am sorry, but am I not using recursion?
20:31:54 <ski> erty : but, i guess, if not, perhaps first understand mauke's version, and suggested improvements (sans the `foldl' one)
20:32:00 <ski> you are
20:32:17 <monochrom> But laziness helps the tree case only (write seemingly-whole-tree code, get DFS). min of list is linear time no matter how you dice it.
20:32:24 <ski> you are using the first element of the list as an accumulator, accumulating the least element you've seen, so far
20:32:35 <mauke> findMin (x : xs) = min x (findMin xs) -- this one?
20:32:41 <ski> in mauke's version, the first argument of `go' is the accumulator
20:33:05 cheater_ joins (~Username@user/cheater)
20:33:55 <EvanR> findMin = head -- sometimes
20:34:03 <ski> monochrom : i don't think it helps just `minTree' ? you have to have both `min' and `max', right ?
20:34:24 <ski> er
20:34:27 <ski> mauke ^
20:35:45 <monochrom> Too many "min"s. We need 10-page function names, yes. >:)
20:35:49 <ski> erty : anyway, have you implemented `length' or `sum' yourself ?
20:36:01 <ski> monochrom : one min.
20:36:47 <erty> ski: yes I have, those accumulate results
20:37:13 <ski> well, the most direct definitions would be
20:37:19 <ski> length [ ] = 0
20:37:25 <ski> length (x:xs) = 1 + length xs
20:37:26 <ski> and
20:37:31 × cheater quits (~Username@user/cheater) (Ping timeout: 256 seconds)
20:37:31 <ski> sum [ ] = 0
20:37:32 cheater_ is now known as cheater
20:37:41 <ski> sum (n:ns) = n + sum ns
20:37:48 <ski> (and similarly for `product')
20:38:12 <ski> (although, one could special-case so that one stops traversing in `product', if one sees a `0' ..)
20:38:25 <ski> erty : do you understand how these definitions would unfold ?
20:39:02 <erty> yes i have implemented them and understand them very well, (thanks fo typing :-)
20:39:14 <erty> are those using unbounded space?
20:39:17 <ski> let's try `sum [2,3,5,7]'
20:39:23 <ski> sum [2,3,5,7]
20:39:31 <ski> = 2 + sum [3,5,7]
20:39:37 <ski> = 2 + (3 + sum [5,7])
20:39:49 <ski> = 2 + (3 + (5 + sum [7]))
20:39:56 <ski> = 2 + (3 + (5 + (7 + sum [])))
20:39:59 <ski> = 2 + (3 + (5 + (7 + sum 0)))
20:40:02 <ski> er
20:40:04 <ski> = 2 + (3 + (5 + (7 + 0)))
20:40:07 <ski> = 2 + (3 + (5 + 7))
20:40:09 <ski> = 2 + (3 + 12)
20:40:13 <ski> = 2 + 15
20:40:15 <ski> = 17
20:40:38 <erty> you are accumulating and recursing
20:40:41 <ski> note how we get deeper and deeper, the recursive call gets embedded inside a growing context. this is basically "the stack"
20:41:14 <ski> so, you can visually see that this is using unbounded space, deferring more and more additions to perform later, after the recursion, doing them only on the "way back up"
20:41:16 <mauke> not really accumulating
20:41:21 <ski> no, there's no accumulator here
20:41:36 <ski> here's the accumulator version, for comparision
20:41:53 <mauke> we're just rolling out the whole list into one big expression, which we can only start reducing after reaching the end of the list
20:42:00 <ski> sum ns = sumPlus 0 ns
20:42:06 <ski> sumPlus acc [ ] = acc
20:42:20 <ski> sumPlus acc (n:ns) = sumPlus (acc + n) ns
20:42:34 <ski> now, imagine the following reduction/"evaulation" trace
20:42:41 <ski> sum [2,3,5,7]
20:42:50 <ski> = sumPlus 0 [2,3,5,7]
20:42:58 <ski> = sumPlus (0 + 2) [3,5,7]
20:43:02 <ski> = sumPlus 2 [3,5,7]
20:43:08 <ski> = sumPlus (2 + 3) [5,7]
20:43:12 <ski> = sumPlus 5 [5,7]
20:43:19 <ski> = sumPlus (5 + 5) [7]
20:43:22 <ski> = sumPlus 10 [7]
20:43:28 <ski> = sumPlus (10 + 7) []
20:43:32 <ski> = sumPlus 17 []
20:43:34 <ski> = 17
20:43:44 <erty> ok
20:43:49 <ski> here, there's no growth of the context around the recursion
20:43:54 <ski> however !
20:44:06 <EvanR> that's the javascript edition
20:44:08 <ski> this is actually not how this would work, in a lazy implementation of Haskell
20:44:16 <ski> yea, this is how it would work, in a strict language
20:44:16 × matijja quits (~matijja@193.77.181.201) (Server closed connection)
20:44:22 <ski> in Haskell, you actually get
20:44:28 <ski> sum [2,3,5,7]
20:44:35 <ski> = sumPlus 0 [2,3,5,7]
20:44:41 <ski> = sumPlus (0 + 2) [3,5,7]
20:44:44 <mauke> or if ghc -O2 figures out the function is strict in its first argument :-)
20:44:48 <ski> = sumPlus ((0 + 2) + 3) [5,7]
20:44:56 <ski> = sumPlus (((0 + 2) + 3) + 5) [7]
20:45:02 matijja joins (~matijja@193.77.181.201)
20:45:02 <ski> = sumPlus ((((0 + 2) + 3) + 5) + 7) []
20:45:10 <ski> = (((0 + 2) + 3) + 5) + 7
20:45:14 <ski> = ((2 + 3) + 5) + 7
20:45:18 <ski> = (5 + 5) + 7
20:45:21 <ski> = 10 + 7
20:45:22 <ski> = 17
20:45:44 <erty> ok
20:45:53 <ski> you get a build-up of unevaluated expression (thunks), in the accumulator, and those only happen at the end, when it's clear that the result is demanded
20:46:31 <ski> (as mauke says, there are optimizations that can make GHC realize that the result is always demanded here, and so perform the additions upfront, rather than at the end, and so avoid an unbounded buildup)
20:46:57 <ski> but if you don't want to rely on optimizations, you should make sure the accumulator gets demanded, as we go
20:47:10 <ski> simplest way is to use a strict pattern
20:47:15 <erty> ok
20:47:23 <ski> sumPlus !acc (n:ns) = sumPlus (acc + n) ns
20:47:32 <ski> you could also use the `seq' function
20:47:41 <ski> sumPlus acc (n:ns) = acc `seq` sumPlus (acc + n) ns
20:48:18 <mauke> ... = (sumPlus $! (acc + n)) ns
20:48:52 <ski> btw, the naming of `sumPlus acc ns' is to suggest/remind oneself of the specification `sumPlus acc ns = acc + sum ns' .. this specification can be used to more or less mechanically derive the implementation of `sumPlus' (and the new version of `sum'), from the original (directly recursive) version of `sum'
20:49:04 <ski> yea, `$!' is another option
20:49:30 <EvanR> :t f $! x y
20:49:31 <lambdabot> error:
20:49:31 <lambdabot> • Couldn't match expected type ‘Expr -> a0’ with actual type ‘Expr’
20:49:31 <lambdabot> • The function ‘x’ is applied to one argument,
20:49:45 <EvanR> why are parentheses needed
20:49:57 <ski> (because `sumPlus acc ns = acc + sum ns', we know `sumPlus 0 ns = 0 + sum ns = sum ns', and so we can define `sum ns = sumPlus 0 acc'. deriving `sumPlus' is a little bit more complicated, but not very hard)
20:50:00 <mauke> application beats infix operators
20:50:33 <mauke> :t \f x y -> f $! x $ y
20:50:34 <lambdabot> (a -> b) -> (t -> a) -> t -> b
20:50:49 <ski> .. and unfortunately `$' and `$!' are right-associative, not left-associative. otherwise you could have said `sumPlus $! (acc + n) $ ns'
20:50:52 <mauke> yeah, that's f (x y)
20:50:57 pavonia joins (~user@user/siracusa)
20:50:59 <EvanR> yeesh
20:51:28 <ski> (well, even without the brackets, so `sumPlus $! acc + n $ ns', i guess)
20:52:03 × mechap quits (~mechap@user/mechap) (Ping timeout: 246 seconds)
20:52:04 <ski> erty : anyway .. hopefully it's clear what i meant by "direct recursive" version of `findMin', now ?
20:53:17 <erty> ski: Thanks for explaining at this level. I will take my good time to understand those concepts and will reply you back tomorrow as this is this is some good stuff
20:54:05 <ski> yw
20:54:48 <EvanR> in the first version of sum given above, the one with sum (n:ns) = n + sum ns, which "stack" is growing.
20:55:11 <ski> "the stack"
20:55:19 <EvanR> lol
20:55:32 <ski> (Felleisen evaluation contexts)
20:56:27 <EvanR> which level of abstraction do we need to be on to see the stack
20:56:30 <ski> E[] ::= [] | E[] E | case E[] of P -> E; ...
20:56:47 <ski> but *not* including `E E[]' as an alternative !
20:57:48 <EvanR> a context is an empty context, or a context with E appended, or a case....?
20:57:49 <ski> so we have reduction steps like
20:58:37 imdoor joins (~imdoor@balticom-142-78-50.balticom.lv)
20:58:54 <ski> E[(\x -> E1) E0] ~> E[ E1{x := E0} ]
20:59:29 <ski> yea, the `E[] E' case says that to reduce an application, we *need* to reduce the operator position
20:59:53 <mauke> TIL Felleisen is an archaic word meaning knapsack and is related to valise
20:59:55 <ski> so, pushing the operand expression on the stack, to later pass into the resulting lambda
21:00:01 × imdoor quits (~imdoor@balticom-142-78-50.balticom.lv) (Client Quit)
21:00:19 imdoor joins (~imdoor@balticom-142-78-50.balticom.lv)
21:00:35 ski thought the "sen" was a version of "son", common surname ending
21:00:45 <ski> @wn valise
21:00:46 <lambdabot> *** "valise" wn "WordNet (r) 3.0 (2006)"
21:00:46 <lambdabot> valise
21:00:46 <lambdabot> n 1: a small overnight bag for short trips
21:01:41 <ski> EvanR : and likewise, the `case E[] of ...' alternative is that when doing a `case', we need to remember the branches to select from, after getting the scrutinee to WHNF
21:02:44 <EvanR> so there's an argument stack for the application, and a continuation stack for case
21:03:01 <ski> yep. or just a common stack for both
21:03:43 <EvanR> remembering the context you are in when delving into an expression tree sounds like a zipper
21:04:20 <ski> but there's no `V E[]' case for remembering to call the function after we've evaluated the argument. and no `let x = E[] in E' for remembering to continue with the body after evaluating the value for the local variable
21:05:03 <ski> yea, you can represent the evaluation context "inside-out", like you'd commonly do with zippers
21:05:22 <dolio> It doesn't have all the cases the zipper would, though.
21:05:36 <ski> i guess the evaluation context restricts which paths are valid, as compared to all possible paths
21:05:56 <dolio> It's like a zipper for neutral terms.
21:06:28 <ski> (even for a strict language, you still have no `\x -> E[]' case, no evaluation under lambdas. you'd need applicative (or normal) order evaluation for that, not just call-by-value (or call-by-name))
21:06:30 <dolio> Focused on the part making it neutral.
21:07:50 <ski> dolio : hm, reminds me, do you know off hand a nice paper (perhaps the originating source) to read about neutral terms ?
21:08:08 <dolio> Not off hand.
21:08:22 ski was thinking it was related to uniform derivations and goal-directedness & focusing
21:09:30 <ski> EvanR : anyway, iirc, Felleisen contexts originate from Matthias Felleisen's thesis (on continuations, iirc)
21:13:50 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 256 seconds)
21:14:13 × target_i quits (~target_i@217.175.14.39) (Quit: leaving)
21:14:46 euleritian joins (~euleritia@dynamic-002-247-251-218.2.247.pool.telefonica.de)
21:18:10 <ski> hmm .. come to think about it, the evaluation contexts as zipper for neutral terms reminds me of "Generalized Phrase Structure Grammar" and "island constraints"
21:19:02 × califax quits (~califax@user/califx) (Remote host closed the connection)
21:19:57 califax joins (~califax@user/califx)
21:20:42 <ski> (see e.g. "Extending Definite Clause Grammar with Scoping Constructs" by Remo Pareschi,Dale Miller in 1990-06 at <https://web.archive.org/web/20030803060005/ftp://ftp.cis.upenn.edu/pub/papers/miller/iclp90pareschi.dvi.Z>
21:20:46 <ski> )
21:21:30 <ski> (this is computational linguistics. well, the paper is the intersection of that, and logic programming)
21:21:48 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
21:23:12 <imdoor> Hey, i'm trying to figure out how to fold pipes (i.e., consume all elements and produce a single resulting value at the end) in a composable fashion. Ideally i'd want something like Consumer a m x -> Consumer b m y -> Consumer (a, b) m (x, y), but there are 2 problems with this – 1) afaict you cannot fold a Pipe into a Consumer and 2) I can't find a way to compose Consumers like that (is it because they're not arrows?). I've found that th
21:23:14 <imdoor> ere's fold in Pipes.Prelude that folds Producers but that also doesn't seem to compose. What are my options? Using another lib?
21:24:38 <ski> the issue in the paper is relative clauses, like "John missed the rat that the cat ate.". specifically, thinking of the phrase after "that" as a sentence missing a noun phrase, "the cat ate [the rat]"
21:26:21 × pounce quits (~pounce@user/cute/pounce) (Server closed connection)
21:26:35 pounce joins (~pounce@user/cute/pounce)
21:27:36 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
21:28:33 <ski> but the noun phrase that's missing doesn't just have to be at the end, as in that example, e.g. "John wrote the book that {Jane read [gap]}". but there are restrictions on where the gap can occur, called "island constraints". it occured to me that these could have similarities paths in an expression to neutral terms
21:28:43 cheater_ joins (~Username@user/cheater)
21:29:30 × cheater quits (~Username@user/cheater) (Ping timeout: 246 seconds)
21:29:39 cheater_ is now known as cheater
21:30:22 <dolio> Oh, perhaps.
21:32:36 <dolio> I'm not really familiar with how different linguistic stuff is encoded into formal languages.
21:33:36 cheater_ joins (~Username@user/cheater)
21:35:30 × mc47 quits (~mc47@xmonad/TheMC47) (Remote host closed the connection)
21:35:53 × cheater quits (~Username@user/cheater) (Ping timeout: 256 seconds)
21:36:01 cheater_ is now known as cheater
21:36:13 <dolio> I mean, the idea of neutral terms is pretty simple. They are essentially the elimination forms that are normal because they are hereditarily blocked on some corresponding introduction form being a variable.
21:37:01 <dolio> I don't know how 'redexes' arise in linguistics, though.
21:39:00 mastarija joins (~mastarija@42-10.dsl.iskon.hr)
21:40:49 fendor joins (~fendor@2a02:8388:1640:be00:2528:5dc7:a36e:9b87)
21:49:27 cheater_ joins (~Username@user/cheater)
21:50:53 × takuan quits (~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection)
21:51:14 jmdaemon joins (~jmdaemon@user/jmdaemon)
21:53:10 × oo_miguel quits (~Thunderbi@78-11-179-96.static.ip.netia.com.pl) (Ping timeout: 260 seconds)
21:53:30 × cheater quits (~Username@user/cheater) (Ping timeout: 256 seconds)
21:53:33 cheater_ is now known as cheater
21:54:04 × ubert quits (~Thunderbi@178.115.42.132.wireless.dyn.drei.com) (Ping timeout: 256 seconds)
21:54:38 × elkcl quits (~elkcl@broadband-95-84-226-240.ip.moscow.rt.ru) (Ping timeout: 256 seconds)
21:56:19 × _ht quits (~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Remote host closed the connection)
21:57:43 CiaoSen joins (~Jura@2a05:5800:2cb:ad00:2a3a:4dff:fe84:dbd5)
21:59:28 × fendor quits (~fendor@2a02:8388:1640:be00:2528:5dc7:a36e:9b87) (Remote host closed the connection)
21:59:31 × idgaen quits (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1)
22:00:23 rekahsoft joins (~rekahsoft@bas1-sudbury98-67-70-201-226.dsl.bell.ca)
22:00:35 × rekahsoft quits (~rekahsoft@bas1-sudbury98-67-70-201-226.dsl.bell.ca) (Remote host closed the connection)
22:01:13 rekahsoft joins (~rekahsoft@67.70.201.226)
22:03:47 elkcl joins (~elkcl@broadband-95-84-226-240.ip.moscow.rt.ru)
22:06:14 × sawilagar quits (~sawilagar@user/sawilagar) (Ping timeout: 260 seconds)
22:07:33 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
22:07:40 × rekahsoft quits (~rekahsoft@67.70.201.226) (Ping timeout: 256 seconds)
22:09:45 × EsoAlgo81 quits (~EsoAlgo@129.146.136.145) (Server closed connection)
22:10:06 EsoAlgo81 joins (~EsoAlgo@129.146.136.145)
22:10:09 × mastarija quits (~mastarija@42-10.dsl.iskon.hr) (Quit: Client closed)
22:14:43 × pretty_dumm_guy quits (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5)
22:14:59 × notzmv quits (~zmv@user/notzmv) (Ping timeout: 256 seconds)
22:15:02 × misterfish quits (~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 256 seconds)
22:15:14 pretty_dumm_guy joins (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655)
22:17:00 cheater_ joins (~Username@user/cheater)
22:17:26 × CiaoSen quits (~Jura@2a05:5800:2cb:ad00:2a3a:4dff:fe84:dbd5) (Ping timeout: 260 seconds)
22:19:12 CiaoSen joins (~Jura@2a05:5800:2be:2c00:2a3a:4dff:fe84:dbd5)
22:20:42 × cheater quits (~Username@user/cheater) (Ping timeout: 260 seconds)
22:20:47 cheater_ is now known as cheater
22:21:06 mastarija joins (~mastarija@42-10.dsl.iskon.hr)
22:21:42 nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net)
22:21:47 × Pickchea quits (~private@user/pickchea) (Quit: Leaving)
22:23:39 × pretty_dumm_guy quits (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5)
22:26:20 <johnw> "Consumer a m x -> Consumer b m y -> Consumer (a, b) m (x, y)" can't work because it would produce a consumer that needs both an `a` and a `b` at every step, whereas the original consumers only needed an `a` or a `b` depending on which was being used. You can zip the return values though, as shown in https://stackoverflow.com/questions/21691252/join-two-consumers-into-a-single-consumer-that-returns-multiple-values
22:26:46 × nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 260 seconds)
22:26:51 × thegman quits (~thegman@072-239-207-086.res.spectrum.com) (Read error: Connection reset by peer)
22:27:12 <johnw> and you might be able to use the same trick as in that link to write "Consumer a m x -> Consumer b m y -> Consumer (Either a b) m (x, y)"
22:32:02 cheater_ joins (~Username@user/cheater)
22:34:20 × cheater quits (~Username@user/cheater) (Ping timeout: 268 seconds)
22:34:28 cheater_ is now known as cheater
22:35:57 × CiaoSen quits (~Jura@2a05:5800:2be:2c00:2a3a:4dff:fe84:dbd5) (Ping timeout: 256 seconds)
22:40:43 × thegeekinside quits (~thegeekin@189.180.53.210) (Remote host closed the connection)
22:44:38 Guest|94 joins (~Guest|94@62.151.227.157)
22:45:52 × Guest|94 quits (~Guest|94@62.151.227.157) (Client Quit)
22:47:10 × imdoor quits (~imdoor@balticom-142-78-50.balticom.lv) (Quit: imdoor)
22:47:39 imdoor joins (~imdoor@balticom-142-78-50.balticom.lv)
22:47:45 × imdoor quits (~imdoor@balticom-142-78-50.balticom.lv) (Remote host closed the connection)
22:48:05 wroathe joins (~wroathe@50.205.197.50)
22:48:06 × wroathe quits (~wroathe@50.205.197.50) (Changing host)
22:48:06 wroathe joins (~wroathe@user/wroathe)
22:49:09 × wroathe quits (~wroathe@user/wroathe) (Client Quit)
22:49:14 × caryhartline quits (~caryhartl@168.182.58.169) (Quit: caryhartline)
22:50:27 × michalz quits (~michalz@185.246.207.193) (Remote host closed the connection)
22:52:39 L29Ah joins (~L29Ah@wikipedia/L29Ah)
22:56:16 × gmg quits (~user@user/gehmehgeh) (Quit: Leaving)
22:56:53 Square2 joins (~Square4@user/square)
22:57:45 × mastarija quits (~mastarija@42-10.dsl.iskon.hr) (Quit: Client closed)
22:59:45 × Square quits (~Square@user/square) (Ping timeout: 256 seconds)
23:04:51 × acidjnk quits (~acidjnk@p200300d6e72b9344349e196aee999b14.dip0.t-ipconnect.de) (Ping timeout: 256 seconds)
23:07:43 × coot quits (~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
23:19:29 Ivelten joins (~textual@38.252.84.3)
23:20:26 × Jackneill quits (~Jackneill@20014C4E1E1AA2009B34AF74A9557C2A.dsl.pool.telekom.hu) (Ping timeout: 260 seconds)
23:21:54 × chomwitt quits (~chomwitt@2a02:587:7a03:f500:1ac0:4dff:fedb:a3f1) (Ping timeout: 256 seconds)
23:21:56 × Ivelten quits (~textual@38.252.84.3) (Client Quit)
23:24:35 × migas9 quits (~migas@static.140.65.63.178.clients.your-server.de) (Server closed connection)
23:24:54 migas9 joins (~migas@static.140.65.63.178.clients.your-server.de)
23:31:10 thegeekinside joins (~thegeekin@189.180.53.210)
23:35:28 emmanuelux joins (~emmanuelu@user/emmanuelux)
23:36:09 ivelten joins (~ivelten@38.252.84.3)
23:38:06 × hexeme quits (~hexeme@user/hexeme) (Server closed connection)
23:39:28 hexeme joins (~hexeme@user/hexeme)
23:49:11 cheater_ joins (~Username@user/cheater)
23:50:32 <jackdk> My standard response on the streaming topic is "`conduit` is warty and annoying but servicable for single source -> single sink; I have never successfully written a nontrivial program in `pipes`; `streaming` has an extremely core abstraction and is my default choice for nontrivial stuff; `streamly` might be interesting but also broke my code in a minor version update so I'll look at it again some other day"
23:51:28 <jackdk> johnw's point that you don't want a consumer of `(a,b)`s remains correct whatever streaming abstraction you use
23:53:01 × cheater quits (~Username@user/cheater) (Ping timeout: 256 seconds)
23:53:08 cheater_ is now known as cheater
23:55:43 × haskellbridge quits (~haskellbr@069-135-003-034.biz.spectrum.com) (Remote host closed the connection)
23:56:25 × L29Ah quits (~L29Ah@wikipedia/L29Ah) (Ping timeout: 256 seconds)

All times are in UTC on 2023-11-16.