2023/11/16

2023-11-16 00:00:21 +0100 <dibblego> readerState :: MonadState r f => ReaderT r f b -> f b; readerState r = get >>= runReaderT r
2023-11-16 00:01:56 +0100 <EvanR> at that point... you could just write "get >>= runReaderT r"
2023-11-16 00:02:21 +0100jmdaemon(~jmdaemon@user/jmdaemon) (Ping timeout: 246 seconds)
2023-11-16 00:03:46 +0100 <EvanR> and it would be obvious what it does
2023-11-16 00:03:51 +0100 <dibblego> agree
2023-11-16 00:04:48 +0100 <dibblego> wait, that's not quite right
2023-11-16 00:05:26 +0100 <ski> `fmap', i guess
2023-11-16 00:06:30 +0100 <ski> hm, right, that's `ReaderT', not `Reader'. so `lift' ?
2023-11-16 00:07:01 +0100 <ski> @type \r -> lift . runReaderT r =<< get
2023-11-16 00:07:03 +0100 <lambdabot> (MonadTrans t, Monad m, MonadState r (t m)) => ReaderT r m b -> t m b
2023-11-16 00:07:06 +0100coot(~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
2023-11-16 00:07:44 +0100coot(~coot@89.69.206.216)
2023-11-16 00:09:13 +0100 <probie> readerState :: Monad f => ReaderT r f a -> StateT r f a; readerState = coerce . (&&& returnA) . Kleisli . runReader
2023-11-16 00:10:09 +0100jmdaemon(~jmdaemon@user/jmdaemon)
2023-11-16 00:10:11 +0100chomwitt(~chomwitt@ppp-94-67-217-242.home.otenet.gr) (Ping timeout: 268 seconds)
2023-11-16 00:11:23 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470)
2023-11-16 00:12:27 +0100 <EvanR> ski and probie came to the conclusion f needed to be a Monad
2023-11-16 00:13:53 +0100santiagopim(~user@90.167.66.131) (Ping timeout: 268 seconds)
2023-11-16 00:14:16 +0100 <EvanR> does it ?
2023-11-16 00:14:22 +0100 <ski> @type \(ReaderT f) -> StateT (\s -> (,s) <$> f s)
2023-11-16 00:14:23 +0100 <lambdabot> Functor m => ReaderT r m a -> StateT r m a
2023-11-16 00:14:27 +0100 <ski> (did we ?)
2023-11-16 00:14:50 +0100 <EvanR> well the type sigs don't liez1
2023-11-16 00:14:55 +0100 <EvanR> !
2023-11-16 00:15:07 +0100[_](~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 268 seconds)
2023-11-16 00:15:14 +0100 <ski> dibblego's original seems fine, to me
2023-11-16 00:15:17 +0100 <probie> I needed it to be a monad because I wanted to pretend Arrow is somehow still relevant
2023-11-16 00:15:28 +0100 <EvanR> lol
2023-11-16 00:15:55 +0100skiwas just trying to fix the `get >>= runReaderT r' one (which obviously already presupposed `Monad')
2023-11-16 00:18:30 +0100vilya_(~vilya@user/vilya)
2023-11-16 00:18:49 +0100 <EvanR> it's cool that this operation involving 2 monad transformers doesn't require an underlying monad
2023-11-16 00:18:49 +0100vilya(~vilya@user/vilya) (Ping timeout: 268 seconds)
2023-11-16 00:19:47 +0100 <EvanR> this is why happens when type systems are actually reasonable
2023-11-16 00:19:50 +0100 <EvanR> what*
2023-11-16 00:21:29 +0100 <probie> Is it that surprising? You're just turning `a -> m b` to `a -> m (b, a)`
2023-11-16 00:21:53 +0100 <EvanR> also, the scheme semantics are apparently written in haskell... or perhaps agda https://i.imgur.com/YpEJfY4.png
2023-11-16 00:21:54 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 268 seconds)
2023-11-16 00:22:40 +0100coot(~coot@89.69.206.216) (Quit: coot)
2023-11-16 00:23:44 +0100 <EvanR> in lisp their code looks like data. In haskell our code looks like semantics
2023-11-16 00:25:23 +0100 <ski> denotational semantics
2023-11-16 00:26:45 +0100caryhartline(~caryhartl@168.182.58.169)
2023-11-16 00:31:38 +0100wroathe(~wroathe@user/wroathe) (Ping timeout: 256 seconds)
2023-11-16 00:36:10 +0100mechap(~mechap@user/mechap) (Ping timeout: 256 seconds)
2023-11-16 00:37:52 +0100stiell(~stiell@gateway/tor-sasl/stiell) (Ping timeout: 264 seconds)
2023-11-16 00:38:34 +0100idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1)
2023-11-16 00:38:58 +0100tremon(~tremon@83.80.159.219) (Quit: getting boxed in)
2023-11-16 00:39:31 +0100Pickchea(~private@user/pickchea) (Quit: Leaving)
2023-11-16 00:39:34 +0100 <ski> @type state . runState
2023-11-16 00:39:35 +0100 <lambdabot> MonadState s m => State s a -> m a
2023-11-16 00:39:40 +0100 <ski> something along the lines of `forall a. MonadStateT t s m n => t (StateT s m) a -> n a', and `forall a. MonadStateT t s m n => n a -> t (StateT s m) a', could perhaps be useful
2023-11-16 00:42:57 +0100hueso(~root@user/hueso) (Quit: hueso)
2023-11-16 00:46:19 +0100hueso(~root@user/hueso)
2023-11-16 00:50:52 +0100hueso(~root@user/hueso) (Client Quit)
2023-11-16 00:53:27 +0100zetef(~quassel@5.2.182.98) (Ping timeout: 246 seconds)
2023-11-16 00:53:55 +0100falafel_(~falafel@62.175.113.194.dyn.user.ono.com)
2023-11-16 00:53:57 +0100 <EvanR> I heard you like State, so I put a StateT in your MonadStateT
2023-11-16 00:53:59 +0100megaTherion(~therion@unix.io) (Server closed connection)
2023-11-16 00:54:07 +0100hueso(~root@user/hueso)
2023-11-16 00:54:13 +0100megaTherion(~therion@unix.io)
2023-11-16 00:55:50 +0100 <monochrom> "state of the onion" >:)
2023-11-16 00:56:34 +0100 <EvanR> er where is MonadStateT defined
2023-11-16 00:56:47 +0100 <monochrom> There is none. There is only MonadState.
2023-11-16 00:57:24 +0100 <monochrom> But you can just go with "I put a StateT in your MonadState". :)
2023-11-16 00:57:50 +0100CiaoSen(~Jura@2a05:5800:289:5000:2a3a:4dff:fe84:dbd5) (Ping timeout: 245 seconds)
2023-11-16 00:58:15 +0100Tuplanolla(~Tuplanoll@91-159-68-236.elisa-laajakaista.fi) (Quit: Leaving.)
2023-11-16 00:58:16 +0100falafel_(~falafel@62.175.113.194.dyn.user.ono.com) (Ping timeout: 256 seconds)
2023-11-16 01:01:37 +0100jmdaemon(~jmdaemon@user/jmdaemon) (Quit: ZNC 1.8.2 - https://znc.in)
2023-11-16 01:02:04 +0100acidjnk(~acidjnk@p200300d6e72b93446103f524bf4ee276.dip0.t-ipconnect.de) (Read error: Connection reset by peer)
2023-11-16 01:04:27 +0100jmdaemon(~jmdaemon@user/jmdaemon)
2023-11-16 01:05:04 +0100machinedgod(~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 256 seconds)
2023-11-16 01:06:25 +0100 <ski> there would possibly be methods of `MonadStateT'
2023-11-16 01:06:33 +0100 <ski> s/there/these/
2023-11-16 01:06:47 +0100fun-safe-math(~fun-safe-@c-24-21-106-247.hsd1.or.comcast.net)
2023-11-16 01:07:35 +0100geekosaurdoesn't see what it would be, doesn't MonadState encapsulate the common operations of State and StateT?
2023-11-16 01:07:48 +0100 <geekosaur> (and RWS and RWST)
2023-11-16 01:07:48 +0100 <ski> if i have `MonadState s m', i can't get access to "the rest of `m', not including the state parts referencing `s'"
2023-11-16 01:09:08 +0100alp_(~alp@static-176-175-7-165.ftth.abo.bbox.fr)
2023-11-16 01:12:22 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580)
2023-11-16 01:16:31 +0100vilya_vilya
2023-11-16 01:16:47 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580) (Ping timeout: 268 seconds)
2023-11-16 01:19:01 +0100dsrt^(~cd@12.206.76.226)
2023-11-16 01:19:15 +0100 <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'
2023-11-16 01:19:21 +0100 <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
2023-11-16 01:19:23 +0100 <lambdabot> (MonadTrans t, MonadState s (t m), Monad m) => StateT s m a -> t m a
2023-11-16 01:19:48 +0100 <ski> but could one go in the other direction ?
2023-11-16 01:23:33 +0100sawilagar(~sawilagar@user/sawilagar) (Ping timeout: 246 seconds)
2023-11-16 01:31:14 +0100jinsun(~jinsun@user/jinsun)
2023-11-16 01:32:49 +0100fun-safe-math(~fun-safe-@c-24-21-106-247.hsd1.or.comcast.net) ()
2023-11-16 01:34:30 +0100fun-safe-math(~fun-safe-@c-24-21-106-247.hsd1.or.comcast.net)
2023-11-16 01:44:17 +0100machinedgod(~machinedg@d198-53-218-113.abhsia.telus.net)
2023-11-16 01:45:46 +0100jmdaemon(~jmdaemon@user/jmdaemon) (Ping timeout: 268 seconds)
2023-11-16 01:51:11 +0100jmdaemon(~jmdaemon@user/jmdaemon)
2023-11-16 01:53:07 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580)
2023-11-16 01:56:06 +0100alp_(~alp@static-176-175-7-165.ftth.abo.bbox.fr) (Ping timeout: 246 seconds)
2023-11-16 02:09:06 +0100jmdaemon(~jmdaemon@user/jmdaemon) (Ping timeout: 256 seconds)
2023-11-16 02:09:49 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580) (Ping timeout: 268 seconds)
2023-11-16 02:14:06 +0100Feuermagier(~Feuermagi@user/feuermagier) (Ping timeout: 245 seconds)
2023-11-16 02:17:30 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com)
2023-11-16 02:17:30 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
2023-11-16 02:17:30 +0100wroathe(~wroathe@user/wroathe)
2023-11-16 02:18:38 +0100emmanuelux_(~emmanuelu@user/emmanuelux)
2023-11-16 02:18:55 +0100emmanuelux_(~emmanuelu@user/emmanuelux) (Remote host closed the connection)
2023-11-16 02:19:28 +0100Feuermagier(~Feuermagi@user/feuermagier)
2023-11-16 02:19:54 +0100emmanuelux(~emmanuelu@user/emmanuelux) (Ping timeout: 246 seconds)
2023-11-16 02:29:59 +0100emmanuelux(~emmanuelu@user/emmanuelux)
2023-11-16 02:38:00 +0100arahael(~arahael@119-18-2-212.771202.syd.nbn.aussiebb.net) (Ping timeout: 256 seconds)
2023-11-16 02:43:28 +0100rosco(~rosco@175.136.157.149)
2023-11-16 02:58:16 +0100califax(~califax@user/califx) (Ping timeout: 264 seconds)
2023-11-16 02:59:13 +0100califax(~califax@user/califx)
2023-11-16 03:00:04 +0100ec(~ec@gateway/tor-sasl/ec) (Ping timeout: 264 seconds)
2023-11-16 03:00:18 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection)
2023-11-16 03:01:03 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643)
2023-11-16 03:01:20 +0100jmdaemon(~jmdaemon@user/jmdaemon)
2023-11-16 03:02:02 +0100ec(~ec@gateway/tor-sasl/ec)
2023-11-16 03:11:37 +0100otto_s(~user@p5b044a1d.dip0.t-ipconnect.de) (Ping timeout: 260 seconds)
2023-11-16 03:13:09 +0100otto_s(~user@p4ff275a7.dip0.t-ipconnect.de)
2023-11-16 03:17:40 +0100xff0x(~xff0x@2405:6580:b080:900:3141:d1c2:46a9:b11c) (Ping timeout: 256 seconds)
2023-11-16 03:22:47 +0100Fangs(sid141280@id-141280.hampstead.irccloud.com) (Server closed connection)
2023-11-16 03:23:01 +0100Fangs(sid141280@id-141280.hampstead.irccloud.com)
2023-11-16 03:23:12 +0100ystael(~ystael@user/ystael) (Ping timeout: 268 seconds)
2023-11-16 03:24:28 +0100Square2(~Square4@user/square) (Ping timeout: 256 seconds)
2023-11-16 03:31:39 +0100machinedgod(~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 246 seconds)
2023-11-16 03:41:03 +0100ystael(~ystael@user/ystael)
2023-11-16 03:48:00 +0100Boarders___(sid425905@id-425905.lymington.irccloud.com) (Server closed connection)
2023-11-16 03:48:20 +0100Boarders___(sid425905@id-425905.lymington.irccloud.com)
2023-11-16 03:52:37 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470) (Remote host closed the connection)
2023-11-16 03:54:53 +0100kiriakos_(~kiriakos@p57b65bf0.dip0.t-ipconnect.de)
2023-11-16 03:54:59 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580)
2023-11-16 03:55:38 +0100kiriakos(~kiriakos@p57b647b8.dip0.t-ipconnect.de) (Ping timeout: 256 seconds)
2023-11-16 03:55:38 +0100kiriakos_kiriakos
2023-11-16 04:01:16 +0100thegman(~thegman@072-239-207-086.res.spectrum.com) (Read error: Connection reset by peer)
2023-11-16 04:02:28 +0100xff0x(~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp)
2023-11-16 04:03:05 +0100degraafk(sid71464@id-71464.lymington.irccloud.com) (Server closed connection)
2023-11-16 04:03:14 +0100degraafk(sid71464@id-71464.lymington.irccloud.com)
2023-11-16 04:04:08 +0100superbil(~superbil@1-34-176-171.hinet-ip.hinet.net) (Ping timeout: 256 seconds)
2023-11-16 04:07:24 +0100 <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.
2023-11-16 04:08:45 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex)
2023-11-16 04:08:51 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5)
2023-11-16 04:15:16 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-11-16 04:16:55 +0100califax(~califax@user/califx) (Remote host closed the connection)
2023-11-16 04:16:55 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection)
2023-11-16 04:16:55 +0100ec(~ec@gateway/tor-sasl/ec) (Read error: Connection reset by peer)
2023-11-16 04:17:10 +0100califax(~califax@user/califx)
2023-11-16 04:17:15 +0100ec(~ec@gateway/tor-sasl/ec)
2023-11-16 04:17:27 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643)
2023-11-16 04:21:42 +0100td_(~td@i53870930.versanet.de) (Ping timeout: 256 seconds)
2023-11-16 04:23:21 +0100td_(~td@i53870904.versanet.de)
2023-11-16 04:25:01 +0100finn_elija(~finn_elij@user/finn-elija/x-0085643)
2023-11-16 04:25:01 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
2023-11-16 04:25:01 +0100finn_elijaFinnElija
2023-11-16 04:34:52 +0100califax(~califax@user/califx) (Ping timeout: 264 seconds)
2023-11-16 04:36:04 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Ping timeout: 264 seconds)
2023-11-16 04:36:40 +0100chiselfuse(~chiselfus@user/chiselfuse) (Ping timeout: 264 seconds)
2023-11-16 04:36:40 +0100adanwan(~adanwan@gateway/tor-sasl/adanwan) (Ping timeout: 264 seconds)
2023-11-16 04:37:29 +0100alphastate(~alphastat@176.254.244.83) (Ping timeout: 260 seconds)
2023-11-16 04:48:27 +0100califax(~califax@user/califx)
2023-11-16 04:48:28 +0100chiselfuse(~chiselfus@user/chiselfuse)
2023-11-16 04:48:33 +0100adanwan(~adanwan@gateway/tor-sasl/adanwan)
2023-11-16 04:49:31 +0100chiselfuse(~chiselfus@user/chiselfuse) (Remote host closed the connection)
2023-11-16 04:51:49 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643)
2023-11-16 04:53:32 +0100chiselfuse(~chiselfus@user/chiselfuse)
2023-11-16 04:54:39 +0100lexi-lambda(sid92601@id-92601.hampstead.irccloud.com) (Server closed connection)
2023-11-16 04:54:49 +0100lexi-lambda(sid92601@id-92601.hampstead.irccloud.com)
2023-11-16 04:58:34 +0100edr(~edr@user/edr) (Quit: Leaving)
2023-11-16 04:59:43 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580) (Remote host closed the connection)
2023-11-16 05:06:48 +0100ddellacosta(~ddellacos@ool-44c738de.dyn.optonline.net) (Ping timeout: 268 seconds)
2023-11-16 05:07:09 +0100pr0ton(~pr0ton@176.254.244.83)
2023-11-16 05:07:22 +0100ddellacosta(~ddellacos@ool-44c738de.dyn.optonline.net)
2023-11-16 05:09:41 +0100aforemny(~aforemny@2001:9e8:6cf2:3800:48da:c417:67b:551b) (Ping timeout: 240 seconds)
2023-11-16 05:10:26 +0100aforemny(~aforemny@2001:9e8:6cd7:8c00:47af:9d09:fce9:5fc4)
2023-11-16 05:13:01 +0100Yumemi(~Yumemi@2001:bc8:47a0:1b14::1) (Server closed connection)
2023-11-16 05:13:21 +0100Yumemi(~Yumemi@chamoin.net)
2023-11-16 05:17:29 +0100yvan-sraka(sid419690@id-419690.lymington.irccloud.com) (Server closed connection)
2023-11-16 05:17:40 +0100yvan-sraka(sid419690@id-419690.lymington.irccloud.com)
2023-11-16 05:18:56 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 256 seconds)
2023-11-16 05:20:59 +0100ddellacosta(~ddellacos@ool-44c738de.dyn.optonline.net) (Ping timeout: 268 seconds)
2023-11-16 05:22:36 +0100ddellacosta(~ddellacos@ool-44c738de.dyn.optonline.net)
2023-11-16 05:25:02 +0100rosco(~rosco@175.136.157.149) (Quit: Lost terminal)
2023-11-16 05:25:17 +0100rosco(~rosco@175.136.157.149)
2023-11-16 05:26:21 +0100Inst(~Inst@120.244.192.250)
2023-11-16 05:26:47 +0100nrr______(sid20938@id-20938.lymington.irccloud.com) (Server closed connection)
2023-11-16 05:27:04 +0100nrr______(sid20938@id-20938.lymington.irccloud.com)
2023-11-16 05:29:42 +0100wroathe(~wroathe@user/wroathe) (Ping timeout: 256 seconds)
2023-11-16 05:35:15 +0100trev(~trev@user/trev)
2023-11-16 05:38:51 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711)
2023-11-16 05:40:44 +0100lightandlight(sid135476@id-135476.helmsley.irccloud.com) (Server closed connection)
2023-11-16 05:40:53 +0100lightandlight(sid135476@id-135476.helmsley.irccloud.com)
2023-11-16 05:41:09 +0100Lycurgus(~georg@user/Lycurgus) (Server closed connection)
2023-11-16 05:41:25 +0100Lycurgus(~georg@user/Lycurgus)
2023-11-16 05:47:27 +0100ubert(~Thunderbi@178.165.182.252.wireless.dyn.drei.com) (Ping timeout: 246 seconds)
2023-11-16 05:50:09 +0100sham(~sham@2605:a601:a98c:be00:fdc4:4550:60c7:3408)
2023-11-16 05:52:00 +0100dmj`(sid72307@id-72307.hampstead.irccloud.com) (Server closed connection)
2023-11-16 05:52:25 +0100dmj`(sid72307@id-72307.hampstead.irccloud.com)
2023-11-16 05:53:07 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com)
2023-11-16 05:53:07 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
2023-11-16 05:53:07 +0100wroathe(~wroathe@user/wroathe)
2023-11-16 06:03:16 +0100_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl)
2023-11-16 06:05:23 +0100waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 268 seconds)
2023-11-16 06:06:47 +0100superbil(~superbil@1-34-176-171.hinet-ip.hinet.net)
2023-11-16 06:08:02 +0100emmanuelux(~emmanuelu@user/emmanuelux) (Quit: au revoir)
2023-11-16 06:12:33 +0100sham(~sham@2605:a601:a98c:be00:fdc4:4550:60c7:3408) (Quit: Ping timeout (120 seconds))
2023-11-16 06:17:52 +0100kiriakos(~kiriakos@p57b65bf0.dip0.t-ipconnect.de) (Ping timeout: 256 seconds)
2023-11-16 06:18:52 +0100czy(~user@180.116.181.15)
2023-11-16 06:18:52 +0100stiell(~stiell@gateway/tor-sasl/stiell)
2023-11-16 06:19:13 +0100kiriakos(~kiriakos@p5b03ee49.dip0.t-ipconnect.de)
2023-11-16 06:21:50 +0100Inst(~Inst@120.244.192.250) (Ping timeout: 256 seconds)
2023-11-16 06:25:23 +0100michalz(~michalz@185.246.207.193)
2023-11-16 06:30:38 +0100Inst(~Inst@120.244.192.250)
2023-11-16 06:33:08 +0100wroathe(~wroathe@user/wroathe) (Ping timeout: 268 seconds)
2023-11-16 06:33:46 +0100chomwitt(~chomwitt@2a02:587:7a03:f500:1ac0:4dff:fedb:a3f1)
2023-11-16 06:40:32 +0100Unicorn_Princess(~Unicorn_P@user/Unicorn-Princess/x-3540542) (Quit: Leaving)
2023-11-16 06:42:40 +0100czy(~user@180.116.181.15) (Remote host closed the connection)
2023-11-16 06:48:56 +0100mhatta(~mhatta@www21123ui.sakura.ne.jp) (Server closed connection)
2023-11-16 06:49:38 +0100mhatta(~mhatta@www21123ui.sakura.ne.jp)
2023-11-16 06:55:00 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 246 seconds)
2023-11-16 06:55:43 +0100euleritian(~euleritia@dynamic-089-204-130-029.89.204.130.pool.telefonica.de)
2023-11-16 07:04:51 +0100AlexZenon(~alzenon@178.34.162.228) (Server closed connection)
2023-11-16 07:05:09 +0100AlexZenon(~alzenon@178.34.162.228)
2023-11-16 07:07:40 +0100euleritian(~euleritia@dynamic-089-204-130-029.89.204.130.pool.telefonica.de) (Ping timeout: 268 seconds)
2023-11-16 07:09:27 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl)
2023-11-16 07:11:35 +0100zetef(~quassel@95.77.17.251)
2023-11-16 07:13:16 +0100notzmv(~zmv@user/notzmv) (Ping timeout: 245 seconds)
2023-11-16 07:13:44 +0100AlexNoo(~AlexNoo@178.34.162.228) (Server closed connection)
2023-11-16 07:14:07 +0100AlexNoo(~AlexNoo@178.34.162.228)
2023-11-16 07:16:41 +0100acidjnk(~acidjnk@p200300d6e72b9344700ee309897754f9.dip0.t-ipconnect.de)
2023-11-16 07:17:37 +0100euleritian(~euleritia@dynamic-002-247-248-051.2.247.pool.telefonica.de)
2023-11-16 07:19:07 +0100euleritian(~euleritia@dynamic-002-247-248-051.2.247.pool.telefonica.de) (Read error: Connection reset by peer)
2023-11-16 07:19:24 +0100euleritian(~euleritia@77.22.252.56)
2023-11-16 07:22:58 +0100takuan(~takuan@178-116-218-225.access.telenet.be)
2023-11-16 07:27:34 +0100euleritian(~euleritia@77.22.252.56) (Ping timeout: 256 seconds)
2023-11-16 07:28:05 +0100euleritian(~euleritia@dynamic-002-247-248-051.2.247.pool.telefonica.de)
2023-11-16 07:36:37 +0100_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Remote host closed the connection)
2023-11-16 07:37:56 +0100 <dminuoso> bwe: I am here now.
2023-11-16 07:43:50 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-11-16 07:44:00 +0100zetef(~quassel@95.77.17.251) (Ping timeout: 246 seconds)
2023-11-16 07:47:45 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 268 seconds)
2023-11-16 07:54:53 +0100xxpor(~xxpor@user/xxpor)
2023-11-16 07:59:09 +0100zetef(~quassel@95.77.17.251)
2023-11-16 08:03:00 +0100nitrix(~nitrix@user/nitrix) (Server closed connection)
2023-11-16 08:03:19 +0100nitrix(~nitrix@user/nitrix)
2023-11-16 08:05:16 +0100gmg(~user@user/gehmehgeh)
2023-11-16 08:10:44 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-11-16 08:12:20 +0100qqq(~qqq@92.43.167.61) (Ping timeout: 256 seconds)
2023-11-16 08:14:36 +0100sord937(~sord937@gateway/tor-sasl/sord937)
2023-11-16 08:15:54 +0100xxpor(~xxpor@user/xxpor) (Quit: WeeChat 4.1.1)
2023-11-16 08:29:54 +0100zetef(~quassel@95.77.17.251) (Ping timeout: 256 seconds)
2023-11-16 08:36:33 +0100mc47(~mc47@xmonad/TheMC47) (Remote host closed the connection)
2023-11-16 08:46:45 +0100sord937(~sord937@gateway/tor-sasl/sord937) (Remote host closed the connection)
2023-11-16 08:47:00 +0100thegeekinside(~thegeekin@189.180.53.210) (Ping timeout: 246 seconds)
2023-11-16 08:47:09 +0100sord937(~sord937@gateway/tor-sasl/sord937)
2023-11-16 08:47:19 +0100euleritian(~euleritia@dynamic-002-247-248-051.2.247.pool.telefonica.de) (Read error: Connection reset by peer)
2023-11-16 08:47:38 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-11-16 08:48:02 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-11-16 08:49:02 +0100lortabac(~lorenzo@2a01:e0a:541:b8f0:a708:6ef4:b35f:fb63)
2023-11-16 08:50:06 +0100meejah(~meejah@rutas.meejah.ca) (Server closed connection)
2023-11-16 08:50:15 +0100meejah(~meejah@rutas.meejah.ca)
2023-11-16 09:00:05 +0100dsrt^(~cd@12.206.76.226) (Remote host closed the connection)
2023-11-16 09:00:34 +0100mc47(~mc47@xmonad/TheMC47)
2023-11-16 09:01:57 +0100danza(~francesco@151.57.147.208)
2023-11-16 09:06:08 +0100qqq(~qqq@92.43.167.61)
2023-11-16 09:06:52 +0100lhpitn(~tn@193.96.224.66)
2023-11-16 09:08:53 +0100jrm(~jrm@user/jrm) (Ping timeout: 240 seconds)
2023-11-16 09:11:53 +0100misterfish(~misterfis@87.215.131.102)
2023-11-16 09:14:12 +0100fendor(~fendor@2a02:8388:1640:be00:2528:5dc7:a36e:9b87)
2023-11-16 09:14:18 +0100Feuermagier(~Feuermagi@user/feuermagier) (Ping timeout: 246 seconds)
2023-11-16 09:14:36 +0100Feuermagier(~Feuermagi@user/feuermagier)
2023-11-16 09:15:37 +0100jrm(~jrm@user/jrm)
2023-11-16 09:16:14 +0100idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
2023-11-16 09:18:00 +0100mikko(~mikko@user/mikko) (Server closed connection)
2023-11-16 09:18:22 +0100mikko(~mikko@dsl-trebng22-58c1a8-185.dhcp.inet.fi)
2023-11-16 09:18:22 +0100mikko(~mikko@dsl-trebng22-58c1a8-185.dhcp.inet.fi) (Changing host)
2023-11-16 09:18:22 +0100mikko(~mikko@user/mikko)
2023-11-16 09:22:06 +0100notzmv(~zmv@user/notzmv)
2023-11-16 09:28:53 +0100Inst(~Inst@120.244.192.250) (Ping timeout: 268 seconds)
2023-11-16 09:30:24 +0100aku(~aku@65.108.245.241) (Server closed connection)
2023-11-16 09:30:32 +0100aku(~aku@65.108.245.241)
2023-11-16 09:32:34 +0100 <bwe> dminuoso: ski led me up to this point: https://gist.github.com/benjaminweb/ea91583983f5eceb10549ed25db03ec4
2023-11-16 09:34:48 +0100 <ski> we left off with `return' not being defined
2023-11-16 09:40:39 +0100minigrim0(~minigrim0@2a01:4f9:6b:3416:68ba:8dff:fe58:a5ea) (Server closed connection)
2023-11-16 09:40:59 +0100minigrim0(~minigrim0@2a01:4f9:6b:3416:68ba:8dff:fe58:a5ea)
2023-11-16 09:43:04 +0100Lord_of_Life(~Lord@user/lord-of-life/x-2819915) (Ping timeout: 268 seconds)
2023-11-16 09:44:40 +0100Lord_of_Life(~Lord@user/lord-of-life/x-2819915)
2023-11-16 09:44:56 +0100vpan(~vpan@mail.elitnet.lt)
2023-11-16 09:46:30 +0100 <dminuoso> bwe: By the way, somewhat but not entirely tangentially: to use your State, ideally dont manually construct with MkState
2023-11-16 09:47:02 +0100 <dminuoso> bwe: By the way, somewhat but not entirely tangentially: to use your State, ideally dont manually construct with MkState
2023-11-16 09:47:04 +0100 <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.
2023-11-16 09:47:30 +0100 <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.
2023-11-16 09:47:37 +0100 <dminuoso> And the internals disappear.
2023-11-16 09:47:40 +0100 <ski> well, `tick' was intended as a primitive here
2023-11-16 09:47:49 +0100 <bwe> dminuoso: I've had that intuition just a couple of moments ago, too. I suspect, we did not arrive at that point yesterday.
2023-11-16 09:47:56 +0100 <ski> (partly for convenience sake)
2023-11-16 09:47:59 +0100 <bwe> let's do first the return
2023-11-16 09:48:20 +0100 <bwe> dminuoso: we started with the tick :: Int -> Int
2023-11-16 09:48:34 +0100 <dminuoso> Right I see.
2023-11-16 09:48:34 +0100machinedgod(~machinedg@d198-53-218-113.abhsia.telus.net)
2023-11-16 09:49:05 +0100 <ski> <ski> `return' is supposed to "do nothing, apart from just giving back the argument as result", btw
2023-11-16 09:49:30 +0100 <ski> <ski> return :: a -> State s a
2023-11-16 09:49:30 +0100Inst(~Inst@120.244.192.250)
2023-11-16 09:49:34 +0100 <ski> <ski> in your case
2023-11-16 09:50:17 +0100alp_(~alp@2001:861:5e02:eff0:1f45:1768:2920:edd0)
2023-11-16 09:51:12 +0100Jackneill(~Jackneill@20014C4E1E1AA2009B34AF74A9557C2A.dsl.pool.telekom.hu)
2023-11-16 09:52:26 +0100danza(~francesco@151.57.147.208) (Ping timeout: 260 seconds)
2023-11-16 09:52:49 +0100 <bwe> @type pure
2023-11-16 09:52:50 +0100 <lambdabot> Applicative f => a -> f a
2023-11-16 09:56:06 +0100 <bwe> … a function that takes an `a` to produce a `State s a`
2023-11-16 09:56:51 +0100 <ski> yes
2023-11-16 09:57:28 +0100 <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))
2023-11-16 09:57:55 +0100 <bwe> hm, I wouldn't understand then what I am doing
2023-11-16 09:58:18 +0100 <bwe> why does the return take an `a` to return a `State s a`?
2023-11-16 09:58:38 +0100 <bwe> that would be the `Tree Int` in our example
2023-11-16 09:58:40 +0100 <ski> you have defined `(>>=)' (which your use of `do'-notation expands to calls to). but you have't defined `return' yet
2023-11-16 09:58:43 +0100 <ski> no
2023-11-16 09:58:54 +0100 <ski> `(>>=)' isn't about trees. neither is `return'
2023-11-16 09:59:09 +0100 <ski> @type return
2023-11-16 09:59:10 +0100 <lambdabot> Monad m => a -> m a
2023-11-16 09:59:32 +0100danse-nr3(~danse@151.57.147.208)
2023-11-16 09:59:35 +0100 <ski> return takes an `a' and computes an `m a', where `m' is a monad, and the `a' there is the "monadic result type"
2023-11-16 10:00:04 +0100 <ski> (in `enumerateTreeFrom', that monadic result type will actually be `Tree (Int,a)', yes)
2023-11-16 10:00:07 +0100 <bwe> return for State s a defines how to create a State s a for a proivded a
2023-11-16 10:00:26 +0100 <ski> in your case, the monad `m' is `State s'. so `return :: a -> m a' becomes `return :: a -> State s a'
2023-11-16 10:00:31 +0100 <ski> yes
2023-11-16 10:00:47 +0100 <ski> `return' creates a "trivial" or "no-op" monadic action
2023-11-16 10:01:08 +0100 <bwe> on type-level I'd do that manually with State s (Tree (Int, a))
2023-11-16 10:01:21 +0100 <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"))
2023-11-16 10:01:40 +0100 <ski> bwe : yea, that's what you did in `enumerateTreeFrom'
2023-11-16 10:01:51 +0100 <bwe> now we want to do it generally, right?
2023-11-16 10:01:56 +0100 <ski> right
2023-11-16 10:02:28 +0100 <bwe> but now I do it in the function body, right?
2023-11-16 10:02:40 +0100 <ski> which function body ?
2023-11-16 10:02:49 +0100 <bwe> return = …
2023-11-16 10:03:06 +0100 <ski> yea, you have to provide a defining equation of `return', not just a type signature
2023-11-16 10:03:19 +0100__monty__(~toonn@user/toonn)
2023-11-16 10:03:20 +0100 <ski> return :: a -> State s a
2023-11-16 10:03:21 +0100 <bwe> I am lost at that transition
2023-11-16 10:03:24 +0100 <ski> return x = ..x..
2023-11-16 10:03:34 +0100 <ski> what is the type of `..x..' ?
2023-11-16 10:03:42 +0100 <bwe> a
2023-11-16 10:03:43 +0100 <ski> no
2023-11-16 10:03:51 +0100 <bwe> State s a
2023-11-16 10:03:58 +0100 <ski> yep. the result type of `return'
2023-11-16 10:04:05 +0100 <ski> an `State s'-action
2023-11-16 10:04:25 +0100 <bwe> no, this can't be if it's the argument on the left, too
2023-11-16 10:04:36 +0100 <ski> so `return' should make a `State s'-action .. how do you make values of type `State s a' ?
2023-11-16 10:04:52 +0100 <ski> "if it's the argument on the left, too" -- huh ?
2023-11-16 10:05:03 +0100 <bwe> return :: a -> State s a
2023-11-16 10:05:10 +0100 <bwe> return x = x
2023-11-16 10:05:11 +0100 <ski> (you may compare with `tickS' as a comparision)
2023-11-16 10:05:15 +0100 <ski> no
2023-11-16 10:05:26 +0100 <ski> `x' does have type `a', not type `State s a'
2023-11-16 10:05:38 +0100 <bwe> that's what I am saying.
2023-11-16 10:05:45 +0100coot(~coot@89-69-206-216.dynamic.chello.pl)
2023-11-16 10:05:48 +0100 <bwe> the right side needs to be different than just `x`
2023-11-16 10:05:52 +0100 <ski> right
2023-11-16 10:06:04 +0100 <ski> <ski> so `return' should make a `State s'-action .. how do you make values of type `State s a' ?
2023-11-16 10:06:07 +0100 <bwe> let's type hole that
2023-11-16 10:07:00 +0100DigitalKiwi(~kiwi@2604:a880:400:d0::1ca0:e001) (Server closed connection)
2023-11-16 10:07:33 +0100DigitalKiwi(~kiwi@137.184.156.191)
2023-11-16 10:07:40 +0100 <bwe> return :: a -> State s a
2023-11-16 10:07:43 +0100 <bwe> MkState :: (s -> (a, s)) -> State s a
2023-11-16 10:07:51 +0100 <ski> yep
2023-11-16 10:08:06 +0100 <ski> so, what's the new code with a hole ?
2023-11-16 10:08:33 +0100leeb(~leeb@tk2-243-31079.vs.sakura.ne.jp) (Server closed connection)
2023-11-16 10:08:33 +0100skistarted doing exercises like this, with holes, before holes were a technical feature in GHC
2023-11-16 10:08:48 +0100leeb(~leeb@tk2-243-31079.vs.sakura.ne.jp)
2023-11-16 10:08:55 +0100 <ski> it's a good mental exercise to figure out the types of sections of code left to write
2023-11-16 10:09:34 +0100 <bwe> return x = _ $ MkState
2023-11-16 10:09:48 +0100 <bwe> Found hole: _ :: State s0 a0 -> State s a
2023-11-16 10:10:09 +0100 <bwe> huh, what's the difference here?
2023-11-16 10:10:20 +0100 <bwe> those zeroes
2023-11-16 10:10:53 +0100idgaenthinks State s a is a function that takes a s an return a (a, s)
2023-11-16 10:11:15 +0100 <idgaen> s/an/and/
2023-11-16 10:11:21 +0100 <ski> well, lets take a step back
2023-11-16 10:11:23 +0100 <ski> to
2023-11-16 10:11:30 +0100 <ski> return :: a -> State s a
2023-11-16 10:11:34 +0100 <ski> return x = ..x..
2023-11-16 10:11:37 +0100 <ski> here we know
2023-11-16 10:11:40 +0100 <ski> x :: a
2023-11-16 10:11:45 +0100 <ski> ..x.. :: State s a
2023-11-16 10:11:50 +0100 <ski> and we also think
2023-11-16 10:11:56 +0100 <ski> MkState :: (s -> (a, s)) -> State s a
2023-11-16 10:11:59 +0100 <ski> may be relevant
2023-11-16 10:12:22 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Remote host closed the connection)
2023-11-16 10:12:36 +0100 <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')
2023-11-16 10:12:42 +0100 <ski> iow, if we write
2023-11-16 10:12:53 +0100 <ski> MkState (..x..) :: State s a
2023-11-16 10:12:56 +0100 <ski> for some *new* hole
2023-11-16 10:13:04 +0100 <ski> ..x.. :: s -> (a,s)
2023-11-16 10:13:15 +0100 <ski> then that would fit into the old hole (of type `State s a')
2023-11-16 10:13:20 +0100 <ski> iow, we would then have
2023-11-16 10:13:30 +0100 <ski> return :: a -> State s a
2023-11-16 10:13:36 +0100 <ski> return x = MkState (..x..)
2023-11-16 10:13:41 +0100 <ski> bwe : makes sense ?
2023-11-16 10:14:21 +0100 <bwe> let that sink in
2023-11-16 10:15:08 +0100ubert(~Thunderbi@178.115.42.132.wireless.dyn.drei.com)
2023-11-16 10:16:07 +0100skiwould also suggest not so reflexively reaching for `$' .. `_ $ MkState' is just the same as `_ MkState'
2023-11-16 10:16:47 +0100skithinks `$' is quite seldom warranted to use at all
2023-11-16 10:16:56 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-11-16 10:18:52 +0100 <bwe> return x = MkState (_ x)
2023-11-16 10:19:00 +0100 <bwe> Found hole: _ :: a -> s -> (a, s)
2023-11-16 10:20:19 +0100 <ski> ok, so that's just saying that in `return x = MkState (..x..)', `..x..' has type `s -> (a,s)', if `x' has type `a'
2023-11-16 10:21:09 +0100 <ski> next question here is : how to construct something of type `s -> (a,s)', fitting this hole ?
2023-11-16 10:23:33 +0100kuribas(~user@ip-188-118-57-242.reverse.destiny.be)
2023-11-16 10:33:21 +0100tolt(~weechat-h@li219-154.members.linode.com) (Server closed connection)
2023-11-16 10:33:48 +0100tolt(~weechat-h@li219-154.members.linode.com)
2023-11-16 10:36:00 +0100CiaoSen(~Jura@2a05:5800:2cb:ad00:2a3a:4dff:fe84:dbd5)
2023-11-16 10:38:09 +0100 <bwe> it's runState
2023-11-16 10:38:55 +0100 <bwe> runState :: State s a -> s -> (a, s)
2023-11-16 10:39:17 +0100 <bwe> hm, it has `State s a` in its front
2023-11-16 10:42:56 +0100szkl(uid110435@id-110435.uxbridge.irccloud.com)
2023-11-16 10:43:44 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711)
2023-11-16 10:46:14 +0100 <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..')
2023-11-16 10:46:53 +0100 <bwe> let me write all signatures in one place
2023-11-16 10:46:58 +0100 <ski> iow, you'd be going from `return x = ..x..' to `return x = MkState (..x..)', to `return x = MkState (runState (..x..))'
2023-11-16 10:47:17 +0100 <ski> .. but `runState' is the inverse of `MkState', so we're then back to where we started !
2023-11-16 10:47:41 +0100 <ski> so, we need to find some *other* way to construct something of type `s -> (a,s)'
2023-11-16 10:48:04 +0100 <bwe> runState :: State s a -> s -> (a, s)
2023-11-16 10:48:04 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Ping timeout: 264 seconds)
2023-11-16 10:48:31 +0100 <bwe> if we had not the State s a here, that would work, doesn't it?
2023-11-16 10:48:42 +0100 <ski> "that" being ?
2023-11-16 10:49:01 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643)
2023-11-16 10:53:48 +0100danse-nr3(~danse@151.57.147.208) (Read error: Connection reset by peer)
2023-11-16 10:54:13 +0100danse-nr3(~danse@151.43.161.172)
2023-11-16 10:55:18 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-11-16 10:57:02 +0100tzh(~tzh@c-71-193-181-0.hsd1.or.comcast.net) (Quit: zzz)
2023-11-16 10:57:17 +0100 <bwe> uff… well… return x = runState (_ x)
2023-11-16 10:57:25 +0100 <bwe> Found hole: _ :: a -> State s0 a0
2023-11-16 10:57:57 +0100 <bwe> which is just the definition of return, if I get it right?
2023-11-16 10:58:33 +0100Pickchea(~private@user/pickchea)
2023-11-16 10:58:34 +0100 <ski> `return x = runState (_ x)' is a type error
2023-11-16 10:58:35 +0100quintasan(~quassel@quintasan.pl) (Server closed connection)
2023-11-16 10:58:44 +0100quintasan(~quassel@quintasan.pl)
2023-11-16 10:58:45 +0100rosco(~rosco@175.136.157.149) (Quit: Lost terminal)
2023-11-16 10:59:10 +0100 <bwe> ok I am too fast here, need to go steps back
2023-11-16 10:59:21 +0100 <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)'
2023-11-16 10:59:40 +0100 <bwe> return :: a -> State s a
2023-11-16 10:59:50 +0100 <bwe> return :: a -> (s -> (a, s))
2023-11-16 10:59:53 +0100 <ski> no
2023-11-16 11:00:34 +0100 <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'
2023-11-16 11:00:37 +0100 <ski> <ski> next question here is : how to construct something of type `s -> (a,s)', fitting this hole ?
2023-11-16 11:00:49 +0100 <ski> can you please describe the type `s -> (a,s)' for me, in words ?
2023-11-16 11:01:11 +0100 <bwe> give me an s and I create (a, s) for you
2023-11-16 11:01:27 +0100 <ski> what kind of animal is a thing that has type `s -> (a,s)' ?
2023-11-16 11:01:50 +0100Sgeo(~Sgeo@user/sgeo) (Read error: Connection reset by peer)
2023-11-16 11:02:06 +0100 <bwe> @type (1,)
2023-11-16 11:02:07 +0100 <lambdabot> Num t1 => t2 -> (t1, t2)
2023-11-16 11:02:14 +0100 <bwe> (a,)
2023-11-16 11:02:34 +0100 <ski> is something of type `s -> (a,s)' a list ? is it a tree ?
2023-11-16 11:02:36 +0100 <ski> what is it ?
2023-11-16 11:02:41 +0100 <bwe> tuple
2023-11-16 11:02:43 +0100 <ski> no
2023-11-16 11:03:03 +0100 <ski> @type (False,)
2023-11-16 11:03:04 +0100 <lambdabot> t -> (Bool, t)
2023-11-16 11:03:05 +0100 <bwe> s -> (a,s) is a function taking s producing tuple (a,s)
2023-11-16 11:03:11 +0100 <ski> `(False,)' is not a tuple
2023-11-16 11:03:16 +0100 <ski> .. it's a *function*, yes !
2023-11-16 11:03:17 +0100 <bwe> it's a tuple section
2023-11-16 11:03:32 +0100 <ski> (a function that computes a tuple, sure)
2023-11-16 11:03:49 +0100 <ski> now, how do we construct functions ?
2023-11-16 11:04:23 +0100 <ski> what, generally speaking, is the kind of expression we use, to construct a function value ?
2023-11-16 11:04:35 +0100 <bwe> (\x -> (a, x)) -- I am not getting your question - do you mean this?
2023-11-16 11:04:49 +0100 <ski> yes, that's lambda expression, aka "anonymous function"
2023-11-16 11:04:51 +0100 <danse-nr3> % :set -XTupleSections
2023-11-16 11:04:51 +0100 <yahb2> <no output>
2023-11-16 11:04:58 +0100 <danse-nr3> % :t (, 1)
2023-11-16 11:04:58 +0100 <yahb2> (, 1) :: Num t1 => t2 -> (t2, t1)
2023-11-16 11:04:58 +0100 <ski> lambda expressions are *the* way to construct functions
2023-11-16 11:05:08 +0100 <ski> if you write
2023-11-16 11:05:15 +0100 <ski> return x = MkState (..x..)
2023-11-16 11:05:22 +0100 <ski> then this is really just syntactic sugar for
2023-11-16 11:05:27 +0100 <ski> return = \x -> MkState (..x..)
2023-11-16 11:05:42 +0100 <ski> (so `return' is the function `\x -> MkState (..x..)' here)
2023-11-16 11:06:08 +0100 <ski> so, whenever we want to construct a function, the *most* basic, direct, way to do that, is to use a lambda expression
2023-11-16 11:06:55 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection)
2023-11-16 11:07:21 +0100 <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')
2023-11-16 11:07:28 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643)
2023-11-16 11:07:30 +0100zaquest(~notzaques@5.130.79.72)
2023-11-16 11:07:34 +0100 <ski> bwe : making sense ?
2023-11-16 11:07:38 +0100 <bwe> that yes
2023-11-16 11:07:45 +0100 <bwe> I am struggling with
2023-11-16 11:07:51 +0100 <bwe> return :: a -> State s a
2023-11-16 11:07:55 +0100chele(~chele@user/chele)
2023-11-16 11:08:04 +0100 <ski> return x = MkState (..x..)
2023-11-16 11:08:12 +0100 <ski> here we have the hole
2023-11-16 11:08:17 +0100 <ski> ..x.. :: s -> (a,s)
2023-11-16 11:08:19 +0100 <bwe> MkState :: (s -> (a, s)) -> State s a
2023-11-16 11:08:24 +0100 <ski> yes
2023-11-16 11:08:43 +0100 <ski> the type of this hole is a function type. so we *could* try to construct this function by using a lambda expression
2023-11-16 11:09:06 +0100 <ski> that is, replacing this `..x..' by `\x -> ..x..', for a new hole `..x..'
2023-11-16 11:09:10 +0100oo_miguel(~Thunderbi@78-11-179-96.static.ip.netia.com.pl)
2023-11-16 11:09:15 +0100 <ski> bwe : following ?
2023-11-16 11:09:40 +0100 <ski> well .. perhaps use a different variable name than `x' this time, since we already used `x'
2023-11-16 11:10:00 +0100 <ski> right, so replacing this `..x..' by `\y -> ..x..y..', for this new hole `..x..y..'
2023-11-16 11:10:18 +0100 <ski> return x = MkState (\y -> ..x..y..)
2023-11-16 11:10:19 +0100Flow(~none@gentoo/developer/flow) (Server closed connection)
2023-11-16 11:10:58 +0100Flow(~none@gentoo/developer/flow)
2023-11-16 11:11:52 +0100 <bwe> return x = MkState (\y -> _)
2023-11-16 11:11:52 +0100rncwnd(~quassel@2a01:4f8:221:27c6::1) (Server closed connection)
2023-11-16 11:11:56 +0100 <bwe> I've got this here
2023-11-16 11:12:04 +0100rncwnd(~quassel@2a01:4f8:221:27c6::1)
2023-11-16 11:12:09 +0100 <ski> right
2023-11-16 11:12:09 +0100 <bwe> Found hole: _ :: (a, s)
2023-11-16 11:12:16 +0100 <ski> so what's the type of `y' now ?
2023-11-16 11:12:28 +0100 <bwe> s
2023-11-16 11:12:32 +0100 <ski> yeh
2023-11-16 11:12:32 +0100hippoid(~hippoid@user/hippoid) (Server closed connection)
2023-11-16 11:12:45 +0100 <ski> and what kind of animal would fit in this new hole ?
2023-11-16 11:12:54 +0100hippoid(~hippoid@c-98-213-162-40.hsd1.il.comcast.net)
2023-11-16 11:13:03 +0100 <bwe> oh, it compiles
2023-11-16 11:13:06 +0100xff0x(~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp) (Ping timeout: 268 seconds)
2023-11-16 11:13:09 +0100skigrins
2023-11-16 11:13:10 +0100 <bwe> return x = MkState (\y -> (x, y))
2023-11-16 11:13:13 +0100 <ski> indeed
2023-11-16 11:13:36 +0100 <bwe> (I arrived there, yes, but I don't understand what I've done)
2023-11-16 11:13:40 +0100 <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
2023-11-16 11:14:21 +0100 <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
2023-11-16 11:14:35 +0100 <ski> so, the state is not changed. and the monadic result is `x'
2023-11-16 11:15:05 +0100 <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
2023-11-16 11:15:34 +0100 <bwe> wait, you are too fast for me :)
2023-11-16 11:15:45 +0100 <ski> <ski> `return' is supposed to "do nothing, apart from just giving back the argument as result", btw
2023-11-16 11:15:50 +0100 <ski> <ski> `return' creates a "trivial" or "no-op" monadic action
2023-11-16 11:16:03 +0100skiwaits
2023-11-16 11:17:07 +0100econo_(uid147250@id-147250.tinside.irccloud.com) (Quit: Connection closed for inactivity)
2023-11-16 11:17:08 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-11-16 11:18:22 +0100ft(~ft@p508db3bc.dip0.t-ipconnect.de) (Quit: leaving)
2023-11-16 11:19:43 +0100lieven(~mal@ns2.wyrd.be) (Server closed connection)
2023-11-16 11:19:56 +0100 <bwe> understood it
2023-11-16 11:19:57 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655)
2023-11-16 11:20:03 +0100lieven(~mal@ns2.wyrd.be)
2023-11-16 11:20:07 +0100 <bwe> s -> (a, s)
2023-11-16 11:20:10 +0100 <bwe> x is a
2023-11-16 11:20:17 +0100Ekho(~Ekho@user/ekho) (Server closed connection)
2023-11-16 11:20:18 +0100 <bwe> s -> (x, s)
2023-11-16 11:20:28 +0100 <bwe> (\z -> (x, z))
2023-11-16 11:20:47 +0100 <bwe> filling MkState _ hole with that
2023-11-16 11:20:58 +0100 <ski> well, you're somewhat mixing up the value and the type levels now .. but i get what you're aiming at
2023-11-16 11:20:59 +0100 <bwe> MkState (\z -> (x,z))
2023-11-16 11:21:11 +0100 <bwe> ski: I know but that helped me
2023-11-16 11:21:20 +0100 <ski> (`x' is not `a'. `x' has *type* `a')
2023-11-16 11:21:29 +0100 <ski> yes, that's why i didn't dismiss it entirely
2023-11-16 11:21:48 +0100 <bwe> puh, great
2023-11-16 11:21:54 +0100 <ski> you're still trying to get to grips with this all
2023-11-16 11:22:02 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 260 seconds)
2023-11-16 11:22:16 +0100 <bwe> yes
2023-11-16 11:22:18 +0100 <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
2023-11-16 11:22:19 +0100bwesighs
2023-11-16 11:22:40 +0100 <bwe> now, let's try enumerateTree with your example
2023-11-16 11:22:49 +0100 <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
2023-11-16 11:23:32 +0100 <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
2023-11-16 11:24:04 +0100idgaenagrees
2023-11-16 11:24:28 +0100 <ski> bwe : right
2023-11-16 11:24:36 +0100Ekho(~Ekho@user/ekho)
2023-11-16 11:26:33 +0100 <ski> bwe : .. so, does my suggested input data to `enumerateTree' run, now ?
2023-11-16 11:26:45 +0100 <bwe> yes it does
2023-11-16 11:26:54 +0100 <ski> and does the result look okay ?
2023-11-16 11:27:37 +0100 <bwe> yes like your spec said
2023-11-16 11:27:39 +0100 <bwe> https://gist.github.com/benjaminweb/ea91583983f5eceb10549ed25db03ec4
2023-11-16 11:27:40 +0100 <bwe> doctest
2023-11-16 11:27:45 +0100 <bwe> runs through fine
2023-11-16 11:28:52 +0100 <bwe> until here ok? next up would be replacing tickS with State, right?
2023-11-16 11:28:55 +0100_________(~nobody@user/noodly) (Server closed connection)
2023-11-16 11:29:17 +0100_________(~nobody@user/noodly)
2023-11-16 11:29:40 +0100 <ski> replacing, how ?
2023-11-16 11:29:44 +0100 <ski> it's already using `State'
2023-11-16 11:30:30 +0100 <Inst> still working on State?
2023-11-16 11:30:37 +0100 <Inst> or rather StateT
2023-11-16 11:30:41 +0100 <bwe> < dminuoso> bwe: By the way, somewhat but not entirely tangentially: to use your State, ideally dont manually construct with MkState
2023-11-16 11:32:06 +0100 <ski> Inst : `State'
2023-11-16 11:32:40 +0100 <ski> ah, you mean to replace the primitive `tickS' with the primitives `get' and `set'
2023-11-16 11:32:43 +0100 <ski> you can do that, if you want
2023-11-16 11:32:55 +0100 <ski> it's not strictly needed, but could be nice to see how it's done
2023-11-16 11:33:10 +0100 <bwe> before that I'd need to define them, right?
2023-11-16 11:33:18 +0100 <ski> bwe : however, you probably ought to add `pure = return' to the `Applicative' instance
2023-11-16 11:33:55 +0100 <ski> also, you might also (want to do that and) define `return', for `Maybee' as well
2023-11-16 11:35:35 +0100 <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)
2023-11-16 11:35:43 +0100 <ski> (or you can do both)
2023-11-16 11:38:13 +0100bramhaag7(~bramhaag@198.8.58.39) (Server closed connection)
2023-11-16 11:38:21 +0100gtdg(~gtdg@user/gtdg)
2023-11-16 11:38:23 +0100bramhaag7(~bramhaag@endeavour.server.bramh.me)
2023-11-16 11:40:06 +0100 <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)
2023-11-16 11:44:01 +0100 <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
2023-11-16 11:44:09 +0100 <bwe> ski: returns, pures both defined for Maybee and State s
2023-11-16 11:44:59 +0100 <danse-nr3> (i thought your conversation was finished, apologies ^^;)
2023-11-16 11:45:25 +0100 <ski> it ebbs and flows a bit
2023-11-16 11:46:08 +0100 <ski> danse-nr3 : can you elaborate on what you mean ?
2023-11-16 11:46:12 +0100tnks(sid412124@id-412124.helmsley.irccloud.com) (Server closed connection)
2023-11-16 11:46:23 +0100tnks(sid412124@id-412124.helmsley.irccloud.com)
2023-11-16 11:46:51 +0100 <ski> bwe : but not on the gist yet ?
2023-11-16 11:46:51 +0100 <danse-nr3> well i managed to get `traverse` from that `cons`, but maybe i did some calculation wrong?!
2023-11-16 11:47:15 +0100 <ski> danse-nr3 : does that work for `traverse'ing trees ?
2023-11-16 11:47:55 +0100 <ski> (say `data Tree a = Leaf | Node a (Tree a) (Tree a)', for concreteness' sake)
2023-11-16 11:47:59 +0100 <danse-nr3> now that you make me think about it, i worked with the types without checking the laws
2023-11-16 11:48:21 +0100 <danse-nr3> so... a flawed result i guess
2023-11-16 11:48:25 +0100 <bwe> ski: now
2023-11-16 11:48:59 +0100 <ski> right
2023-11-16 11:49:16 +0100 <ski> (`return = Justt' works too, btw)
2023-11-16 11:49:56 +0100 <bwe> yep
2023-11-16 11:50:05 +0100 <ski> (a matter of which you find most clear or simple, i guess. although, sometimes, this kind of thing can result in efficiency improvements)
2023-11-16 11:50:08 +0100 <bwe> now, tickS is just my get function, right?
2023-11-16 11:50:13 +0100 <ski> not quite
2023-11-16 11:50:26 +0100 <bwe> what's the type of get?
2023-11-16 11:50:51 +0100 <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
2023-11-16 11:51:15 +0100 <ski> you get a number, and the number in the machine is also incremented
2023-11-16 11:51:37 +0100 <ski> `get' takes a peek at the current state, and provides it for the user as the "monadic result type"
2023-11-16 11:51:44 +0100 <ski> (and doesn't change the state)
2023-11-16 11:51:47 +0100 <bwe> oh
2023-11-16 11:52:25 +0100 <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"
2023-11-16 11:52:32 +0100 <bwe> get :: State s a -> s ??
2023-11-16 11:52:36 +0100 <ski> no
2023-11-16 11:53:05 +0100 <ski> you're still something thinking "i need to get an input state, so i need to take an input of type `State .....'"
2023-11-16 11:53:12 +0100 <ski> s/something/sometimes/
2023-11-16 11:53:37 +0100 <ski> `get' is a single action, that, when performed/executed, will take a look at its *implicit* input state
2023-11-16 11:57:22 +0100 <bwe> get runs within the context of State s a
2023-11-16 11:57:48 +0100 <ski> `get' *is* an `State s'-action
2023-11-16 11:58:17 +0100Feuermagier(~Feuermagi@user/feuermagier) (Quit: Leaving)
2023-11-16 11:58:19 +0100 <ski> if you do
2023-11-16 11:58:21 +0100 <ski> do ...
2023-11-16 11:58:25 +0100 <ski> s <- get
2023-11-16 11:58:29 +0100 <ski> ..s..
2023-11-16 11:58:46 +0100 <ski> then `s' will be the current state at that point of executing the action `get'
2023-11-16 11:58:54 +0100glguy_(g@libera/staff/glguy)
2023-11-16 11:59:11 +0100 <ski> sometimes, you see people do
2023-11-16 11:59:16 +0100 <ski> do s <- get
2023-11-16 11:59:23 +0100 <ski> callSomething here
2023-11-16 11:59:26 +0100 <ski> put s
2023-11-16 11:59:49 +0100 <ski> to restore back the state, after `callSomething here' possibly changed it, for the purpose of some subcomputation
2023-11-16 12:00:34 +0100 <bwe> for State Int Int it will be then the first Int, right?
2023-11-16 12:00:43 +0100glguy(g@libera/staff/glguy) (Read error: Connection reset by peer)
2023-11-16 12:00:45 +0100g(g@libera/staff/glguy) (Read error: Connection reset by peer)
2023-11-16 12:00:54 +0100 <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)
2023-11-16 12:01:14 +0100 <ski> the first `Int' is the type of the state. the second is the type of the "monadic result"
2023-11-16 12:01:58 +0100 <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
2023-11-16 12:02:12 +0100 <bwe> get :: s
2023-11-16 12:02:43 +0100 <bwe> it just returns current state s
2023-11-16 12:02:45 +0100 <ski> `s' is the type of the implicit state. `get' is an an action, not a state. (it's a `State s'-action)
2023-11-16 12:03:10 +0100Pickchea(~private@user/pickchea) (Quit: Leaving)
2023-11-16 12:03:45 +0100 <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')
2023-11-16 12:04:46 +0100 <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)
2023-11-16 12:05:33 +0100g(g@libera/staff/glguy)
2023-11-16 12:06:07 +0100 <bwe> let's recap runState
2023-11-16 12:06:07 +0100anderson-(~anderson@user/anderson) (Server closed connection)
2023-11-16 12:06:13 +0100 <bwe> runState :: s -> (a, s)
2023-11-16 12:06:29 +0100 <ski> not quite (unfortunately)
2023-11-16 12:06:43 +0100bweis frustrated now
2023-11-16 12:06:52 +0100 <ski> (this is, imho, a wart of Haskell. i brought it up, briefly, yesterday)
2023-11-16 12:07:03 +0100 <ski> yea
2023-11-16 12:07:21 +0100 <ski> newtype State s a = MkState { runState :: s -> (a,s) }
2023-11-16 12:07:26 +0100 <ski> this much is right
2023-11-16 12:07:40 +0100 <ski> now, this says that the *field* `runState' has type `s -> (a,s)'
2023-11-16 12:07:44 +0100 <ski> *however*
2023-11-16 12:08:04 +0100 <bwe> the field of State s a
2023-11-16 12:08:12 +0100 <bwe> which is why
2023-11-16 12:08:13 +0100 <bwe> runState :: State s a -> s -> (a, s)
2023-11-16 12:08:19 +0100 <bwe> true?
2023-11-16 12:08:23 +0100 <ski> there's also an implicitly generated field *extraction* function, unhelpfully also named `runState', which if it was defined explicitly, would be defined as
2023-11-16 12:08:34 +0100 <ski> runState :: State s a -> (s -> (a,s))
2023-11-16 12:08:41 +0100 <ski> runState (MkState f) = f
2023-11-16 12:09:04 +0100 <ski> you have to keep the field itself, and its field extraction function, distinct, in your mind
2023-11-16 12:09:22 +0100 <ski> and it really does *not* help here, that Haskell spells both exactly the same :(
2023-11-16 12:10:03 +0100 <ski> (e.g. programming in SML, the field extraction function would be `#runState', so there's a syntactic distinction, making this much clearer)
2023-11-16 12:10:24 +0100 <bwe> so, what's the next step for me?
2023-11-16 12:10:51 +0100 <ski> well, figure out types for `get' and `put', implement `tickS' in terms of them, and implement `get' and `put' ?
2023-11-16 12:10:51 +0100 <bwe> I was trying to find out the type of get
2023-11-16 12:10:56 +0100 <ski> (not necessarily in that order)
2023-11-16 12:11:06 +0100 <ski> right
2023-11-16 12:11:30 +0100xff0x(~xff0x@2405:6580:b080:900:389:c68e:2e26:10bf)
2023-11-16 12:12:16 +0100 <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')
2023-11-16 12:12:26 +0100 <bwe> if I run get and put in the same Monad, that'd mean their return types should be same
2023-11-16 12:12:27 +0100puke(~puke@user/puke) (Ping timeout: 246 seconds)
2023-11-16 12:12:52 +0100 <ski> at least the monad part of them, yes. the monadic result type could be different
2023-11-16 12:12:59 +0100 <bwe> if I assume this correctly, State s a is the return type of get and put
2023-11-16 12:13:21 +0100 <bwe> while put changes the state and does not give it back
2023-11-16 12:13:24 +0100 <ski> for some type `a', yes. not necessarily the same `a', for `get' and `put
2023-11-16 12:13:25 +0100 <ski> '
2023-11-16 12:13:31 +0100 <bwe> get does not change it but give it back
2023-11-16 12:13:32 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Ping timeout: 268 seconds)
2023-11-16 12:13:56 +0100 <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))
2023-11-16 12:14:00 +0100 <ski> right
2023-11-16 12:15:57 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 246 seconds)
2023-11-16 12:16:12 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-11-16 12:17:53 +0100 <bwe> put :: s -> _ -- it's not returning anything or unit?
2023-11-16 12:19:10 +0100 <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"
2023-11-16 12:19:32 +0100 <ski> oh .. sorry, just realized that we apparently used both `set' and `put', to refer to the same operation
2023-11-16 12:20:00 +0100 <ski> but yes, "unit type" is how you specify "uninteresting result" in Haskell
2023-11-16 12:20:12 +0100 <ski> (this corresponds to `void' in C,C++,Java,C#,..)
2023-11-16 12:21:23 +0100 <bwe> put :: s -> _ ()
2023-11-16 12:21:42 +0100 <ski> yep, getting closer
2023-11-16 12:22:13 +0100 <bwe> so, it being a monadic result, it might be State s ()
2023-11-16 12:23:08 +0100 <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))
2023-11-16 12:23:33 +0100 <ski> so
2023-11-16 12:23:40 +0100 <ski> put :: s -> State s ()
2023-11-16 12:24:01 +0100 <ski> says : if `y' has type `s', then `put y' is a `State s'-action, with monadic result type `()'
2023-11-16 12:24:25 +0100 <ski> and we want `put y', when executed, to ignore/discard the current state (of type `s'), and replace it with `y'
2023-11-16 12:27:23 +0100 <bwe> btw where do I define put ?
2023-11-16 12:27:38 +0100 <bwe> it doesn't belong to Monad, the compiler complains
2023-11-16 12:27:46 +0100 <ski> well, you can just define it in the top-level of your module, so far
2023-11-16 12:28:08 +0100 <ski> (just as for `tickS')
2023-11-16 12:28:28 +0100 <bwe> goood
2023-11-16 12:28:33 +0100 <bwe> put y = _
2023-11-16 12:28:35 +0100 <bwe> Found hole: _ :: State s ()
2023-11-16 12:28:59 +0100lortabac(~lorenzo@2a01:e0a:541:b8f0:a708:6ef4:b35f:fb63) (Ping timeout: 256 seconds)
2023-11-16 12:29:42 +0100 <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))
2023-11-16 12:30:30 +0100 <bwe> put :: s -> State s () -- is this now correct or not?
2023-11-16 12:31:35 +0100 <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
2023-11-16 12:31:54 +0100 <ski> (so therefore it's not `put :: s0 -> State s1 ()' for `s0' and `s1' being different types)
2023-11-16 12:33:42 +0100flocks_(~flocks@134.122.90.60) (Server closed connection)
2023-11-16 12:33:57 +0100flocks(~flocks@134.122.90.60)
2023-11-16 12:34:43 +0100 <bwe> put y = MkState (\x -> ((), y))
2023-11-16 12:34:45 +0100 <bwe> it compiles
2023-11-16 12:35:57 +0100 <ski> so `x' is the current/input state. `()' is the monadic result. and you put `y' in place of the output state
2023-11-16 12:36:43 +0100Square2(~Square4@user/square)
2023-11-16 12:37:25 +0100sawilagar(~sawilagar@user/sawilagar)
2023-11-16 12:38:32 +0100 <bwe> how do I store y?
2023-11-16 12:39:07 +0100 <ski> store ?
2023-11-16 12:39:26 +0100 <bwe> ski: we discard current state, so I drop x and set it to y
2023-11-16 12:39:51 +0100 <bwe> so the implementation is right, right?
2023-11-16 12:40:32 +0100 <ski> yes
2023-11-16 12:42:12 +0100 <bwe> get :: State s a
2023-11-16 12:42:22 +0100cyphase(~cyphase@user/cyphase) (Ping timeout: 246 seconds)
2023-11-16 12:43:01 +0100 <bwe> MkState :: (s -> (a, s)) -> State s a
2023-11-16 12:43:10 +0100 <bwe> so MkState would be start
2023-11-16 12:43:13 +0100 <ski> yep
2023-11-16 12:43:26 +0100 <ski> however .. perhaps look twice at the type signature
2023-11-16 12:44:14 +0100 <bwe> I don't get it
2023-11-16 12:44:17 +0100 <bwe> sry
2023-11-16 12:44:20 +0100 <ski> get :: State s a
2023-11-16 12:44:22 +0100 <ski> what is `a' ?
2023-11-16 12:44:59 +0100 <bwe> it's the value we carry with us
2023-11-16 12:45:13 +0100puke(~puke@user/puke)
2023-11-16 12:45:15 +0100 <bwe> but are we interested in it when using get? no
2023-11-16 12:45:17 +0100thyriaen(~thyriaen@2a01:aea0:dd4:7550:6245:cbff:fe9f:48b1)
2023-11-16 12:45:20 +0100 <bwe> we want `s`
2023-11-16 12:45:23 +0100 <bwe> correct?
2023-11-16 12:45:30 +0100 <ski> the position `State s <here>' is the "monadic result type" position
2023-11-16 12:45:43 +0100 <bwe> so, it'd be State s s
2023-11-16 12:45:46 +0100 <ski> we want `get' to deliver the current state value/version as the monadic result
2023-11-16 12:45:47 +0100 <ski> yes
2023-11-16 12:45:49 +0100 <bwe> woooh
2023-11-16 12:46:03 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
2023-11-16 12:46:47 +0100 <bwe> get = MkState (\s -> (s, s))
2023-11-16 12:46:52 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-11-16 12:46:52 +0100 <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)
2023-11-16 12:46:54 +0100cyphase(~cyphase@user/cyphase)
2023-11-16 12:46:56 +0100 <bwe> that compiles at least
2023-11-16 12:47:05 +0100 <bwe> ski: true
2023-11-16 12:47:20 +0100 <ski> so, `s' is the current input state. then `s' is the monadic result. and finally `s' is also the output state
2023-11-16 12:47:31 +0100 <ski> so the state is not changed. and the state is delivered as monadic result
2023-11-16 12:48:18 +0100 <ski> ok, so `tickS' ?
2023-11-16 12:48:50 +0100 <bwe> tickS = MkState $ \s0 -> (s0, s0+1)
2023-11-16 12:49:01 +0100 <ski> can it be defined with `do'-notation ?
2023-11-16 12:49:02 +0100 <bwe> tickS :: State Int Int
2023-11-16 12:49:12 +0100 <ski> e.g. using `get' and `put' ?
2023-11-16 12:52:39 +0100 <bwe> tickS' :: State Int Int
2023-11-16 12:52:46 +0100 <bwe> tickS' = do
2023-11-16 12:52:50 +0100 <bwe> s0 <- get
2023-11-16 12:53:03 +0100 <bwe> _ <- put (s0 + 1)
2023-11-16 12:53:06 +0100 <bwe> get
2023-11-16 12:53:24 +0100 <ski> that's preincement
2023-11-16 12:53:49 +0100 <ski> if you want postincrement, the monadic result should be the value of the counter before incrementing
2023-11-16 12:53:56 +0100 <ski> (iow `s0')
2023-11-16 12:53:58 +0100 <bwe> return s0
2023-11-16 12:54:01 +0100 <ski> yep
2023-11-16 12:54:10 +0100remexre(~remexre@user/remexre) (Server closed connection)
2023-11-16 12:54:19 +0100 <ski> btw, it's possible to abbreviate `_ <- ...' as simply `...'
2023-11-16 12:54:20 +0100remexre(~remexre@user/remexre)
2023-11-16 12:54:27 +0100lortabac(~lorenzo@2a01:e0a:541:b8f0:710e:fea0:5caf:9833)
2023-11-16 12:54:49 +0100 <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)
2023-11-16 12:55:03 +0100kuribas(~user@ip-188-118-57-242.reverse.destiny.be) (Ping timeout: 256 seconds)
2023-11-16 12:55:22 +0100 <bwe> yup, done
2023-11-16 12:55:24 +0100 <ski> btw, imho, it would be very nice, if one could define `get' and `put' something like this :
2023-11-16 12:55:28 +0100 <ski> get :: State s s
2023-11-16 12:55:34 +0100 <ski> runState get s = (s,s)
2023-11-16 12:55:42 +0100 <ski> put :: s -> State s ()
2023-11-16 12:55:52 +0100 <ski> runState (put s) _ = ((),s)
2023-11-16 12:56:00 +0100 <ski> or, possibly using infix syntax, so
2023-11-16 12:56:02 +0100 <ncf> one can, in Agda :)
2023-11-16 12:56:09 +0100 <ski> get `runState` s = (s,s)
2023-11-16 12:56:12 +0100 <ski> and
2023-11-16 12:56:24 +0100 <ski> put s `runState` _ = ((),s)
2023-11-16 12:56:32 +0100 <ski> ncf : yep, i was just about to mention that :)
2023-11-16 12:57:12 +0100 <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 ?"
2023-11-16 12:57:42 +0100 <ncf> (although in Agda i don't think you'd need a State wrapper at all, because of higher-order unification)
2023-11-16 12:57:54 +0100 <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)
2023-11-16 12:58:17 +0100 <ski> years before Agda picked this up, i learned of this style of definition, in
2023-11-16 12:58:21 +0100 <ski> @where ErikPoll
2023-11-16 12:58:22 +0100 <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.
2023-11-16 12:58:22 +0100 <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.
2023-11-16 12:58:22 +0100 <lambdabot> pdf>
2023-11-16 12:58:37 +0100skinods to ncf
2023-11-16 12:59:16 +0100 <ski> bwe : this style also would be quite readable, for `return' and `(>>=)'
2023-11-16 12:59:31 +0100 <ski> return x `runState` s = (x,s)
2023-11-16 12:59:53 +0100 <ski> (ma >>= amb) `runState` s0 = (y,s2)
2023-11-16 12:59:55 +0100 <ski> where
2023-11-16 13:00:13 +0100 <ski> (x,s1) = ma `runState` s0
2023-11-16 13:00:23 +0100 <ski> (y,s2) = amb a `runState` s1
2023-11-16 13:00:36 +0100Goodbye_Vincent(cyvahl@freakshells.net) (Server closed connection)
2023-11-16 13:00:50 +0100Goodbye_Vincent(cyvahl@freakshells.net)
2023-11-16 13:01:05 +0100 <ski> .. but, at least so far, this remains pseudo-Haskell, something that's currently not supported
2023-11-16 13:01:30 +0100 <bwe> so, we've defined tickS' with get and put
2023-11-16 13:01:33 +0100 <ski> yes
2023-11-16 13:01:40 +0100 <ski> now
2023-11-16 13:02:04 +0100 <ski> it *could* be useful for you to reformulate the `do'-notation, in terms of explicit calls to `>>=' (with lambda expressions)
2023-11-16 13:02:17 +0100szkl(uid110435@id-110435.uxbridge.irccloud.com) (Quit: Connection closed for inactivity)
2023-11-16 13:02:18 +0100 <bwe> tickS'?
2023-11-16 13:02:24 +0100 <ski> to make it absolutely clear what's happening, to not hide any magic inside the `do'-notation
2023-11-16 13:02:37 +0100 <ski> that, and `enumerateTreeFrom' too
2023-11-16 13:03:18 +0100danse-nr3(~danse@151.43.161.172) (Ping timeout: 260 seconds)
2023-11-16 13:04:41 +0100 <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
2023-11-16 13:04:48 +0100 <ski> overall monadic result
2023-11-16 13:04:54 +0100 <bwe> get >>= put (\x -> x + 1) is one part
2023-11-16 13:05:12 +0100tcard(~tcard@2400:4051:5801:7500:cf17:befc:ff82:5303) (Remote host closed the connection)
2023-11-16 13:05:20 +0100 <bwe> I'd still need to return the value of get
2023-11-16 13:05:20 +0100zetef(~quassel@95.77.17.251)
2023-11-16 13:05:23 +0100 <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)
2023-11-16 13:05:27 +0100tcard(~tcard@2400:4051:5801:7500:cf17:befc:ff82:5303)
2023-11-16 13:05:47 +0100 <ski> or, strictly speaking, the second action is actually a function that will be given the intermediate result of the first action
2023-11-16 13:06:16 +0100 <ski> bwe : well, `put' doesn't want a lambda expression (a function), here
2023-11-16 13:06:31 +0100 <ski> but `>>=' *does* want a function (e.g. a lambda expression), as right operand
2023-11-16 13:06:48 +0100 <ski> so `get >>= \n -> ..n..' e.g.
2023-11-16 13:07:22 +0100anderson-(~anderson@user/anderson)
2023-11-16 13:07:28 +0100 <bwe> get >>= (\x -> x + 1) >>= put
2023-11-16 13:07:47 +0100 <ski> getting a bit closer
2023-11-16 13:07:53 +0100 <bwe> however the lambda will not work
2023-11-16 13:08:05 +0100 <ski> now, you want to pass the new state as an argument to `put'
2023-11-16 13:08:10 +0100 <ski> what is the new state, here ?
2023-11-16 13:08:43 +0100 <ski> (`x' is the old state, recall. it's the result that `get' delivers)
2023-11-16 13:09:08 +0100 <bwe> the lambda will result State s s
2023-11-16 13:09:20 +0100 <bwe> (x+1, x+1)
2023-11-16 13:09:28 +0100 <ski> yes, `>>=' expects its right operand to be a function that computes an action
2023-11-16 13:09:36 +0100 <bwe> that's what put receives
2023-11-16 13:09:53 +0100 <ski> in `tickS', the state is an `Int', a counter
2023-11-16 13:09:55 +0100 <ski> not a pair
2023-11-16 13:10:17 +0100 <bwe> what will be the type of x?
2023-11-16 13:10:22 +0100 <ski> `Int'
2023-11-16 13:10:53 +0100 <bwe> good, so I can send that through to put with >>= -- but you had a concern, right?
2023-11-16 13:11:09 +0100 <ski> `put' is a function
2023-11-16 13:11:18 +0100 <ski> you need to pass the intended new state to `put' as an argument
2023-11-16 13:12:09 +0100 <bwe> put (get >>= (\x -> x + 1))
2023-11-16 13:12:28 +0100 <ski> <ski> what is the new state, here ?
2023-11-16 13:12:43 +0100 <bwe> well, the interface between the paren and put is not correct, ofc
2023-11-16 13:13:36 +0100danse-nr3(~danse@151.43.161.172)
2023-11-16 13:13:41 +0100 <bwe> n' <- get >>= (\x -> x + 1)
2023-11-16 13:13:44 +0100 <bwe> put n'
2023-11-16 13:13:58 +0100 <bwe> that's where I am at now
2023-11-16 13:14:04 +0100 <bwe> do you agree with this?
2023-11-16 13:14:24 +0100 <ski> well, you're supposed to do away with `do' here. that means no `<-'
2023-11-16 13:14:33 +0100 <bwe> yes, I know
2023-11-16 13:14:34 +0100 <ski> <ski> (`x' is the old state, recall. it's the result that `get' delivers)
2023-11-16 13:14:36 +0100 <ski> agree ?
2023-11-16 13:14:40 +0100 <bwe> yes
2023-11-16 13:14:45 +0100 <ski> what is the new state, then ?
2023-11-16 13:14:52 +0100 <ski> (just the new state, nothing else)
2023-11-16 13:15:20 +0100 <bwe> I don't understand, the result after the lambda function: get >>= (\x -> x + 1)
2023-11-16 13:15:31 +0100 <ski> the purpose of `tickS' is to increment the state counter
2023-11-16 13:15:41 +0100 <ski> the old value of the counter state is `x'
2023-11-16 13:15:48 +0100 <ski> what is the intended new value of the counter state ?
2023-11-16 13:16:03 +0100 <bwe> x+1
2023-11-16 13:16:04 +0100 <ski> yes
2023-11-16 13:16:23 +0100 <ski> in order to effect *changing* the implicit state to this new state, we want to call `put'
2023-11-16 13:16:32 +0100 <ski> `put' wants the to-be new state as an argument
2023-11-16 13:16:41 +0100 <ski> how would such a call to `put' look like ?
2023-11-16 13:16:46 +0100 <ski> (again, just the call, nothing else)
2023-11-16 13:17:03 +0100CiaoSen(~Jura@2a05:5800:2cb:ad00:2a3a:4dff:fe84:dbd5) (Ping timeout: 268 seconds)
2023-11-16 13:17:17 +0100 <bwe> put (\x -> x + 1)
2023-11-16 13:17:24 +0100 <bwe> no no
2023-11-16 13:17:26 +0100 <ski> is `\x -> x + 1' the new state ?
2023-11-16 13:17:34 +0100 <ski> what was the new state, again ?
2023-11-16 13:17:41 +0100 <bwe> x + 1
2023-11-16 13:17:42 +0100 <ski> yes
2023-11-16 13:17:44 +0100 <ski> so ?
2023-11-16 13:18:41 +0100kuribas(~user@ip-188-118-57-242.reverse.destiny.be)
2023-11-16 13:19:40 +0100 <bwe> (\x -> x + 1) is clear but I don't know where to put it
2023-11-16 13:19:55 +0100 <ski> `\x -> x + 1' is not clear to me
2023-11-16 13:19:55 +0100 <bwe> put is not taking a function
2023-11-16 13:20:12 +0100 <ski> (or rather, it's not clear what purpose it would serve, here)
2023-11-16 13:20:14 +0100 <ski> right
2023-11-16 13:20:26 +0100 <ski> `btw' wants a state value/version. in this case, an `Int'
2023-11-16 13:20:36 +0100 <ski> er .. `put' wants
2023-11-16 13:20:58 +0100skiidly wonders how that serialization mixup occured
2023-11-16 13:21:03 +0100 <bwe> how do I give put the new version then?
2023-11-16 13:21:21 +0100 <ski> give it to `put' ?
2023-11-16 13:21:33 +0100 <ski> the new version is ?
2023-11-16 13:21:41 +0100 <bwe> x + 1
2023-11-16 13:21:46 +0100 <bwe> but I don't have x
2023-11-16 13:21:50 +0100 <ski> and passing that to `put' would like what ?
2023-11-16 13:21:58 +0100 <ski> doesn't matter. imagine you have `x' already
2023-11-16 13:22:09 +0100 <bwe> you're kidding
2023-11-16 13:22:10 +0100 <bwe> get >>= put (x + 1)
2023-11-16 13:22:24 +0100 <ski> getting closer still
2023-11-16 13:22:33 +0100bwesighs
2023-11-16 13:22:41 +0100 <ski> *now* is the time to ask where `x' comes from
2023-11-16 13:23:03 +0100 <ski> the answer to "how does it look like to pass `put' the (intended) new state ?" was `put (x + 1)'
2023-11-16 13:23:15 +0100 <ski> so, if
2023-11-16 13:23:18 +0100 <ski> x :: Int
2023-11-16 13:23:19 +0100 <bwe> we need a lift function that gets us the bare Int
2023-11-16 13:23:20 +0100 <ski> then
2023-11-16 13:23:25 +0100 <ski> put (x + 1) :: State Int ()
2023-11-16 13:23:41 +0100 <ski> but `>>=' still wants a function to its right
2023-11-16 13:24:09 +0100 <ski> (so we're back to `get >>= \x -> ..x..', no ?)
2023-11-16 13:24:09 +0100 <bwe> get >>= (\x -> put (x + 1))
2023-11-16 13:24:14 +0100 <ski> right, good ! :D
2023-11-16 13:24:50 +0100 <bwe> oh, inside we could use the x to return that
2023-11-16 13:25:23 +0100 <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
2023-11-16 13:25:34 +0100 <ski> there's only one detail left here now
2023-11-16 13:25:44 +0100 <bwe> giving back the current state
2023-11-16 13:25:56 +0100 <ski> the monadic result of `put (...)' is `()'. but we want `tickS' to give a monadic result of type `Int'
2023-11-16 13:25:59 +0100 <ski> right
2023-11-16 13:26:11 +0100 <bwe> so we can't do >>= get
2023-11-16 13:26:29 +0100 <ski> no .. but we can use `>>=' again, still (but not with another `get')
2023-11-16 13:26:52 +0100 <bwe> get >>= (\x -> put (x + 1)) >>= _
2023-11-16 13:26:56 +0100 <ski> yes
2023-11-16 13:27:05 +0100 <bwe> Found hole: _ :: () -> State Int Int
2023-11-16 13:27:13 +0100 <ski> (you'll want to insert extra brackets there ..
2023-11-16 13:27:25 +0100 <ski> (get >>= (\x -> put (x + 1))) >>= _
2023-11-16 13:27:25 +0100 <ski> )
2023-11-16 13:27:52 +0100 <ski> oh, actually, it doesn't matter
2023-11-16 13:28:05 +0100 <ski> right, `>>=' is left-associative, so you're fine
2023-11-16 13:28:30 +0100 <ski> "Found hole: _ :: () -> State Int Int" -- `()' here is the monadic result of the `put (x + 1)'
2023-11-16 13:29:04 +0100 <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.
2023-11-16 13:29:07 +0100 <bwe> so let's discard that unit and use get again
2023-11-16 13:29:40 +0100 <ski> dminuoso : it certainly helps to provide relatively simple, but instructive, combinations of effects
2023-11-16 13:29:44 +0100 <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.
2023-11-16 13:29:50 +0100 <dminuoso> Yup
2023-11-16 13:30:24 +0100 <ski> (not quite sure what you mean by "the transformer situation on the effect combination")
2023-11-16 13:31:02 +0100 <ski> dminuoso : well, now you're stepping/thinking ahead to `MonadState' (which we haven't touched yet). but good point
2023-11-16 13:31:07 +0100 <bwe> ski: (get >>= (\x -> put (x + 1)) >>= (\_ -> get))
2023-11-16 13:31:10 +0100 <bwe> heureka
2023-11-16 13:31:49 +0100 <ski> bwe : let me show you an equivalence of code, often used for refactoring
2023-11-16 13:31:58 +0100 <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.
2023-11-16 13:32:24 +0100 <ski> ma >>= (\a -> amb a) >>= (\b -> bmc b)
2023-11-16 13:32:27 +0100 <ski> which really means
2023-11-16 13:32:31 +0100 <ski> (ma >>= (\a -> amb a)) >>= (\b -> bmc b)
2023-11-16 13:32:35 +0100 <ski> is the same as
2023-11-16 13:32:41 +0100 <ski> ma >>= (\a -> amb a >>= (\b -> bmc b))
2023-11-16 13:32:44 +0100 <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.
2023-11-16 13:33:14 +0100 <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)
2023-11-16 13:33:54 +0100 <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)'
2023-11-16 13:34:07 +0100 <bwe> sk
2023-11-16 13:34:23 +0100 <bwe> ski: so I can remove some parens
2023-11-16 13:34:26 +0100 <ski> so
2023-11-16 13:34:29 +0100 <ski> your suggestion
2023-11-16 13:34:35 +0100 <ski> (get >>= (\x -> put (x + 1)) >>= (\_ -> get))
2023-11-16 13:34:53 +0100 <ski> is then equivalent to
2023-11-16 13:35:01 +0100 <bwe> tickS' = get >>= \x -> put (x + 1) >>= \_ -> get
2023-11-16 13:35:15 +0100 <ski> (get >>= (\x -> put (x + 1) >>= (\_ -> get)))
2023-11-16 13:35:31 +0100 <ski> and Haskell allows us to remove the brackets here, in fact, writing just
2023-11-16 13:35:41 +0100 <ski> get >>= \x -> put (x + 1) >>= \_ -> get
2023-11-16 13:35:49 +0100 <ski> bwe : right
2023-11-16 13:36:23 +0100 <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
2023-11-16 13:36:35 +0100 <bwe> yup
2023-11-16 13:36:37 +0100 <ski> what do you thing the result of getting the current value again will be ?
2023-11-16 13:36:42 +0100 <ski> s/thing/think/
2023-11-16 13:37:01 +0100 <bwe> type or value?
2023-11-16 13:37:52 +0100 <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
2023-11-16 13:38:01 +0100 <ski> bwe : value
2023-11-16 13:38:20 +0100 <bwe> x+1
2023-11-16 13:38:24 +0100 <ski> right
2023-11-16 13:38:33 +0100 <ski> so, `tickS' is now preincrementing again
2023-11-16 13:38:45 +0100 <ski> the original one, using `MkState' was postincrementing
2023-11-16 13:38:53 +0100 <ski> so there's a discrepancy in behaviour
2023-11-16 13:39:42 +0100 <bwe> right, we wanted to return the value before incrementing
2023-11-16 13:39:46 +0100 <ski> yea
2023-11-16 13:39:53 +0100 <ski> 'x+1' is the value after incrementing
2023-11-16 13:39:58 +0100 <ski> what's the value before incrementing ?
2023-11-16 13:40:22 +0100 <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
2023-11-16 13:40:43 +0100 <ski> well, `x-1' would be pre*decrementing*
2023-11-16 13:40:48 +0100 <bwe> :)
2023-11-16 13:40:50 +0100 <ski> (or something like that ..)
2023-11-16 13:41:22 +0100 <ski> we do know that the first `get' doesn't change the state, but does provide it as monadic result
2023-11-16 13:41:24 +0100 <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
2023-11-16 13:41:32 +0100 <ski> right
2023-11-16 13:41:42 +0100 <bwe> ofc we'd need to make a State out of it
2023-11-16 13:41:51 +0100 <bwe> but I'd type hole my way to that
2023-11-16 13:41:56 +0100 <ski> well, `return' already makes a `State ...'
2023-11-16 13:42:25 +0100 <bwe> so, it'd be *just* a return x
2023-11-16 13:42:30 +0100 <bwe> within the put lambda
2023-11-16 13:42:41 +0100skikinda thinks of type holes as luxury, instead of figuring out the types of the holes in your head (or on paper) ;)
2023-11-16 13:42:48 +0100 <ski> yes
2023-11-16 13:42:52 +0100 <ski> so ?
2023-11-16 13:43:21 +0100 <bwe> but how to put the return into the lambda without do notation?
2023-11-16 13:43:32 +0100 <ski> just do it ?
2023-11-16 13:43:56 +0100 <ski> (`return' is an ordinary function, has nothing, per se, to do with `do'-notation)
2023-11-16 13:44:09 +0100 <bwe> tickS' = get >>= \x -> put (x + 1) return x
2023-11-16 13:44:13 +0100 <bwe> this is not going to work
2023-11-16 13:44:20 +0100 <ski> <bwe> within the put lambda
2023-11-16 13:44:47 +0100 <ski> where did the second `>>=' go ?
2023-11-16 13:45:06 +0100 <bwe> I removed it because we get rid of the second get
2023-11-16 13:45:15 +0100 <ski> well, we still need it
2023-11-16 13:45:17 +0100 <ski> just not the `get'
2023-11-16 13:45:22 +0100 <bwe> wait
2023-11-16 13:45:43 +0100 <bwe> tickS' = get >>= (\x -> put (x + 1) >>= return x)
2023-11-16 13:45:50 +0100lisbeths(uid135845@id-135845.lymington.irccloud.com)
2023-11-16 13:45:51 +0100 <bwe> that's closer I feel but doesn't compile
2023-11-16 13:45:57 +0100 <ski> and the lambda ?
2023-11-16 13:46:09 +0100 <ski> where does the monadic result of `put (...)' go ?
2023-11-16 13:47:12 +0100 <bwe> we can discard it; now it goes to return x which makes no sense
2023-11-16 13:47:20 +0100 <ski> how do we discard it ?
2023-11-16 13:47:41 +0100 <ski> (recall you did discard it before, in the preincrement version)
2023-11-16 13:47:41 +0100 <bwe> tickS' = get >>= (\x -> put (x + 1) >>= (\_ -> return x))
2023-11-16 13:47:49 +0100 <ski> yep :)
2023-11-16 13:48:02 +0100bwesighs as it compiles
2023-11-16 13:48:06 +0100 <ski> note how
2023-11-16 13:48:10 +0100 <ski> tickS = do
2023-11-16 13:48:16 +0100 <ski> x <- get
2023-11-16 13:48:26 +0100 <ski> _ <- put (x + 1)
2023-11-16 13:48:30 +0100 <ski> return x
2023-11-16 13:48:35 +0100 <ski> becomes
2023-11-16 13:48:41 +0100 <ski> tickS =
2023-11-16 13:48:53 +0100 <ski> get >>= \x ->
2023-11-16 13:49:06 +0100 <ski> put (x + 1) >>= \_ ->
2023-11-16 13:49:10 +0100 <ski> return x
2023-11-16 13:49:18 +0100 <ski> or, if you want to be explicit with brackets
2023-11-16 13:49:24 +0100 <ski> tickS =
2023-11-16 13:49:28 +0100 <ski> get >>= (\x ->
2023-11-16 13:49:32 +0100 <ski> put (x + 1) >>= (\_ ->
2023-11-16 13:49:42 +0100 <ski> return x ))
2023-11-16 13:50:06 +0100kuribas(~user@ip-188-118-57-242.reverse.destiny.be) (Ping timeout: 246 seconds)
2023-11-16 13:50:08 +0100 <ski> note how the `<result> <- <action>' translates to `<action> >>= \<result> ->'
2023-11-16 13:50:30 +0100szkl(uid110435@id-110435.uxbridge.irccloud.com)
2023-11-16 13:50:51 +0100 <bwe> fine
2023-11-16 13:51:03 +0100 <bwe> enumerateTreeFrom?
2023-11-16 13:51:30 +0100Feuermagier(~Feuermagi@user/feuermagier)
2023-11-16 13:52:34 +0100 <ski> now, recall your earlier
2023-11-16 13:52:35 +0100 <ski> <bwe> ski: (get >>= (\x -> put (x + 1)) >>= (\_ -> get))
2023-11-16 13:53:22 +0100 <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
2023-11-16 13:53:24 +0100akegalj(~akegalj@141-136-147-15.dsl.iskon.hr)
2023-11-16 13:54:06 +0100 <bwe> yup
2023-11-16 13:54:19 +0100 <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
2023-11-16 13:55:10 +0100 <bwe> the key were the parentheses
2023-11-16 13:55:15 +0100 <ski> yes
2023-11-16 13:55:19 +0100 <bwe> brilliant
2023-11-16 13:55:25 +0100 <ski> (as always with associativity, it's about grouping)
2023-11-16 13:55:30 +0100 <ski> in terms of `do'-notation, the associative law says that
2023-11-16 13:55:54 +0100 <ski> do y <- do x <- blah
2023-11-16 13:56:04 +0100 <ski> bleh x
2023-11-16 13:56:11 +0100 <ski> bloh y
2023-11-16 13:56:14 +0100 <ski> is the same as
2023-11-16 13:56:20 +0100 <ski> do x <- blah
2023-11-16 13:56:27 +0100 <ski> do y <- bleh x
2023-11-16 13:56:33 +0100 <ski> bloh
2023-11-16 13:56:48 +0100 <ski> which by syntactic sugar can also be written as
2023-11-16 13:56:53 +0100 <ski> do x <- blah
2023-11-16 13:57:01 +0100 <ski> y <- bleh x
2023-11-16 13:57:05 +0100 <ski> bloh y
2023-11-16 13:58:05 +0100 <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
2023-11-16 13:58:07 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk)
2023-11-16 13:58:56 +0100 <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 ++ []'
2023-11-16 13:59:06 +0100 <ski> return x >>= k = k x
2023-11-16 13:59:22 +0100 <ski> mx >>= return = mx
2023-11-16 13:59:36 +0100 <ski> in terms of `do', these say that
2023-11-16 13:59:44 +0100 <ski> do ...
2023-11-16 13:59:51 +0100 <ski> y <- return x
2023-11-16 14:00:01 +0100 <ski> ..y..
2023-11-16 14:00:04 +0100 <ski> can be replaced by
2023-11-16 14:00:06 +0100 <ski> do ...
2023-11-16 14:00:09 +0100 <ski> ..x..
2023-11-16 14:00:16 +0100 <ski> and that
2023-11-16 14:00:21 +0100 <ski> do ...
2023-11-16 14:00:25 +0100 <ski> blah
2023-11-16 14:00:27 +0100 <ski> is the same as
2023-11-16 14:00:29 +0100 <ski> do ...
2023-11-16 14:00:35 +0100 <ski> x <- blah
2023-11-16 14:00:37 +0100 <ski> return x
2023-11-16 14:00:50 +0100 <ski> bwe : makes sense ?
2023-11-16 14:00:59 +0100 <thyriaen> no
2023-11-16 14:01:21 +0100 <ski> did you get the first part, associativity in terms of `do' ?
2023-11-16 14:01:27 +0100kuribas(~user@ip-188-118-57-242.reverse.destiny.be)
2023-11-16 14:02:20 +0100idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1)
2023-11-16 14:03:00 +0100 <bwe> ski: yes, think so
2023-11-16 14:03:13 +0100 <ski> ok
2023-11-16 14:03:32 +0100 <ski> so `return x' is an acion that "does nothing", a no-op. it only presents `x' back as monadic result
2023-11-16 14:03:40 +0100ChaiTRex(~ChaiTRex@user/chaitrex) (Ping timeout: 264 seconds)
2023-11-16 14:03:40 +0100 <ski> so, the `do'-command
2023-11-16 14:03:42 +0100 <ski> y <- return x
2023-11-16 14:03:59 +0100 <ski> then does nothing, except to take `x', and now (also) name it `y'
2023-11-16 14:04:23 +0100 <ski> so, we could just remove the `y <- return x' command in the `do', and replace the `y's after it by `x's
2023-11-16 14:04:34 +0100alp_(~alp@2001:861:5e02:eff0:1f45:1768:2920:edd0) (Remote host closed the connection)
2023-11-16 14:04:42 +0100 <bwe> yup
2023-11-16 14:04:56 +0100alp_(~alp@2001:861:5e02:eff0:6102:872f:f333:fe94)
2023-11-16 14:05:48 +0100 <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)
2023-11-16 14:06:23 +0100 <ski> but `return' and `Monad' came years before `Applicative' and `pure' was invented, and we're more or less stuck with it now
2023-11-16 14:07:21 +0100 <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)
2023-11-16 14:08:04 +0100 <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
2023-11-16 14:08:07 +0100 <danse-nr3> well one can use `pure` as well
2023-11-16 14:08:18 +0100 <ski> as i just said, yes :)
2023-11-16 14:08:19 +0100 <bwe> so, I am trying to use >>= to rewrite the enumerateTreeFrom now
2023-11-16 14:08:38 +0100 <danse-nr3> ops sorry i should stop reacting on single lines ... :P
2023-11-16 14:09:30 +0100 <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
2023-11-16 14:09:48 +0100 <bwe> Postorder looks now like
2023-11-16 14:09:48 +0100 <bwe> tickS >>= (\z -> return $ (Branch (z, x)) _l' _r'
2023-11-16 14:10:11 +0100 <bwe> my approach is similar to the one we did in tickS'
2023-11-16 14:10:13 +0100 <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'
2023-11-16 14:10:51 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711)
2023-11-16 14:10:59 +0100 <ski> bwe : right. so you also need to perform the actions of the two recursive calls
2023-11-16 14:13:18 +0100falafel_(~falafel@62.175.113.194.dyn.user.ono.com)
2023-11-16 14:16:16 +0100 <bwe> _l' is `Tree (Int, a)` but enumerateTreeFrom returns `State Int (Tree (Int, a))`
2023-11-16 14:16:34 +0100 <ski> yes
2023-11-16 14:16:47 +0100 <bwe> State s a -- I just want the a, out of the monad
2023-11-16 14:16:54 +0100 <ski> hehee :)
2023-11-16 14:17:10 +0100 <bwe> I am thinking of <$> _ <*> _
2023-11-16 14:17:23 +0100 <ski> you don't get it out of the monadic, you put the consumer of the result inside the monadic action
2023-11-16 14:17:29 +0100 <ski> that's what `>>=' is *for*
2023-11-16 14:17:52 +0100 <bwe> it's the parentheses again, right
2023-11-16 14:17:53 +0100 <ski> @quote /bin/ls
2023-11-16 14:17:53 +0100 <lambdabot> shachaf says: getLine :: IO String contains a String in the same way that /bin/ls contains a list of files
2023-11-16 14:18:00 +0100 <ski> could be ?
2023-11-16 14:19:06 +0100 <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)
2023-11-16 14:19:51 +0100geekosaur(sid609282@xmonad/geekosaur) (Server closed connection)
2023-11-16 14:19:57 +0100 <ski> (that node constructor you apparently renamed to `Branch', i see)
2023-11-16 14:20:00 +0100geekosaur(sid609282@xmonad/geekosaur)
2023-11-16 14:20:16 +0100L29Ah(~L29Ah@wikipedia/L29Ah) (Ping timeout: 268 seconds)
2023-11-16 14:22:19 +0100Inst(~Inst@120.244.192.250) (Ping timeout: 256 seconds)
2023-11-16 14:22:23 +0100 <bwe> enumarateTreeFrom l (and r) goes before >>= return $ Branch ...
2023-11-16 14:22:35 +0100 <bwe> Branch is the consumer
2023-11-16 14:22:36 +0100 <ski> yep
2023-11-16 14:24:35 +0100 <bwe> tickS >>= (\z -> enumerateTreeFrom l >>= (\l' -> enumerateTreeFrom r >>= ( \r' -> return $ (Branch (z, x) l' r'))))
2023-11-16 14:24:41 +0100 <bwe> wow it compiles
2023-11-16 14:24:47 +0100bwethrows confetti
2023-11-16 14:24:58 +0100 <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
2023-11-16 14:25:04 +0100 <ski> states, getting possibly different `a's as results)
2023-11-16 14:25:07 +0100 <ski> bwe : ok, that's preorder
2023-11-16 14:25:30 +0100 <bwe> let's move it to the right place
2023-11-16 14:25:45 +0100 <ski> tickS >>= (\z ->
2023-11-16 14:25:49 +0100 <ski> enumerateTreeFrom l >>= (\l' ->
2023-11-16 14:25:52 +0100 <ski> enumerateTreeFrom r >>= (\r' ->
2023-11-16 14:25:55 +0100waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
2023-11-16 14:26:13 +0100 <ski> return (Branch (z,x) l' r') )))
2023-11-16 14:26:22 +0100 <ski> or
2023-11-16 14:26:28 +0100 <ski> tickS >>= \z ->
2023-11-16 14:26:31 +0100 <ski> enumerateTreeFrom l >>= \l' ->
2023-11-16 14:26:34 +0100 <ski> enumerateTreeFrom r >>= \r' ->
2023-11-16 14:26:36 +0100 <ski> return (Branch (z,x) l' r')
2023-11-16 14:26:45 +0100 <ski> which is the same as
2023-11-16 14:26:50 +0100 <ski> do z <- tickS
2023-11-16 14:26:59 +0100 <ski> l' <- enumerateTreeFrom l
2023-11-16 14:27:03 +0100 <ski> r' <- enumerateTreeFrom r
2023-11-16 14:27:09 +0100 <ski> return (Branch (z,x) l' r')
2023-11-16 14:28:06 +0100 <ski> now, you *could* without too much clutter do this one (preorder), with `<$>' and `<*>' in place of `>>='
2023-11-16 14:28:15 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex) (Quit: = "")
2023-11-16 14:28:20 +0100 <ski> btw, if you have
2023-11-16 14:28:26 +0100 <ski> _ <- put (x + 1)
2023-11-16 14:28:33 +0100 <ski> i said you could simply write a command
2023-11-16 14:28:36 +0100 <ski> put (x + 1)
2023-11-16 14:28:42 +0100 <ski> this actually gets translated to
2023-11-16 14:28:53 +0100 <ski> put (x + 1) >>
2023-11-16 14:28:56 +0100 <ski> rather than to
2023-11-16 14:29:03 +0100 <ski> put (x + 1) >>= \_ ->
2023-11-16 14:29:09 +0100 <ski> but the meaning is the same
2023-11-16 14:29:43 +0100FeuermagierGuest6499
2023-11-16 14:29:43 +0100Feuermagier(~Feuermagi@user/feuermagier)
2023-11-16 14:29:52 +0100 <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 `>>=')
2023-11-16 14:30:15 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 256 seconds)
2023-11-16 14:30:55 +0100gtdg(~gtdg@user/gtdg) (Quit: Client closed)
2023-11-16 14:32:07 +0100 <bwe> ski: https://gist.github.com/benjaminweb/ea91583983f5eceb10549ed25db03ec4#file-monadt-hs-L108-L112
2023-11-16 14:32:14 +0100 <bwe> what do you seeV
2023-11-16 14:32:15 +0100 <bwe> ?
2023-11-16 14:32:26 +0100Guest6499(~Feuermagi@user/feuermagier) (Ping timeout: 260 seconds)
2023-11-16 14:33:40 +0100 <ski> looks okay
2023-11-16 14:34:33 +0100falafel_(~falafel@62.175.113.194.dyn.user.ono.com) (Ping timeout: 246 seconds)
2023-11-16 14:35:28 +0100 <bwe> what would be the next step to undertake after a break I am taking?
2023-11-16 14:35:56 +0100Inst(~Inst@120.244.192.250)
2023-11-16 14:37:26 +0100 <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
2023-11-16 14:37:32 +0100 <ski> weight hanging from the string
2023-11-16 14:38:01 +0100Logio(em@kapsi.fi) (Server closed connection)
2023-11-16 14:38:09 +0100Logio(em@kapsi.fi)
2023-11-16 14:38:28 +0100 <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
2023-11-16 14:38:30 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 260 seconds)
2023-11-16 14:38:38 +0100euleritian(~euleritia@dynamic-002-247-251-218.2.247.pool.telefonica.de)
2023-11-16 14:39:15 +0100 <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)
2023-11-16 14:39:28 +0100 <ski> or you could try the mobile one, if it sounds interesting
2023-11-16 14:39:57 +0100 <bwe> dminuoso: where were you heading me towards?
2023-11-16 14:40:08 +0100 <bwe> ski: the mobile sounds interesting, though
2023-11-16 14:40:18 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk)
2023-11-16 14:40:43 +0100 <probie> Does anyone here have strong opinions on http client libraries? Are there any real alternatives to Snoyman's?
2023-11-16 14:40:54 +0100 <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))
2023-11-16 14:41:13 +0100 <bwe> probie: my default is req
2023-11-16 14:42:09 +0100 <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)>
2023-11-16 14:43:54 +0100jmdaemon(~jmdaemon@user/jmdaemon) (Ping timeout: 256 seconds)
2023-11-16 14:44:25 +0100 <bwe> ski: thanks for taking me here!
2023-11-16 14:44:40 +0100 <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
2023-11-16 14:44:43 +0100 <ski> @where Typeclassopedia
2023-11-16 14:44:44 +0100 <lambdabot> http://www.haskell.org/haskellwiki/Typeclassopedia
2023-11-16 14:44:46 +0100 <ski> @where AAM
2023-11-16 14:44:46 +0100 <lambdabot> http://www.haskell.org/haskellwiki/All_About_Monads
2023-11-16 14:45:47 +0100 <ski> Typeclassopedia has many useful exercises to whet your appetite on, to better understand these concepts (and more)
2023-11-16 14:46:23 +0100 <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
2023-11-16 14:48:59 +0100 <ski> bwe : oh, and it's my delight
2023-11-16 14:49:06 +0100Rembane(~Rembane@li346-36.members.linode.com) (Server closed connection)
2023-11-16 14:49:13 +0100Rembane(~Rembane@li346-36.members.linode.com)
2023-11-16 14:50:59 +0100 <ddellacosta> probie: well, if you want low-level, req and wreq both sit on top of https://hackage.haskell.org/package/http-client
2023-11-16 14:53:33 +0100danse-nr3(~danse@151.43.161.172) (Read error: Connection reset by peer)
2023-11-16 14:54:34 +0100danse-nr3(~danse@151.57.198.230)
2023-11-16 14:59:08 +0100 <probie> ddellacosta: my problem is that I'm trying to avoid the `tls` package, and `http-client-tls` uses that
2023-11-16 14:59:09 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 256 seconds)
2023-11-16 14:59:43 +0100targetdisk(~daemonchi@45-33-4-162.ip.linodeusercontent.com) (Server closed connection)
2023-11-16 14:59:51 +0100targetdisk(~daemonchi@45-33-4-162.ip.linodeusercontent.com)
2023-11-16 14:59:52 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk)
2023-11-16 15:02:10 +0100zetef(~quassel@95.77.17.251) (Remote host closed the connection)
2023-11-16 15:03:35 +0100 <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?
2023-11-16 15:03:42 +0100 <ddellacosta> the tls lib I mean
2023-11-16 15:04:03 +0100 <ddellacosta> not that it helps you now
2023-11-16 15:04:13 +0100acidjnk(~acidjnk@p200300d6e72b9344700ee309897754f9.dip0.t-ipconnect.de) (Ping timeout: 260 seconds)
2023-11-16 15:05:23 +0100alp_(~alp@2001:861:5e02:eff0:6102:872f:f333:fe94) (Ping timeout: 256 seconds)
2023-11-16 15:05:34 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 260 seconds)
2023-11-16 15:06:19 +0100 <ddellacosta> probie: an opinion I read recently https://discourse.haskell.org/t/haskell-http-s-libraries-dont-work-well/8087/4
2023-11-16 15:06:28 +0100alp_(~alp@2001:861:5e02:eff0:ab2f:dcd1:5fa1:c307)
2023-11-16 15:07:31 +0100 <ddellacosta> that thread in general is probably useful for info about the state of HTTP clients in Haskell, wrt tls in particular
2023-11-16 15:08:03 +0100waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 268 seconds)
2023-11-16 15:08:07 +0100 <probie> I might see if I can get http-client to play with BearSSL
2023-11-16 15:08:44 +0100 <ddellacosta> good luck!
2023-11-16 15:09:08 +0100ChaiTRex(~ChaiTRex@user/chaitrex)
2023-11-16 15:10:06 +0100 <danse-nr3> % :t (.)
2023-11-16 15:10:06 +0100 <yahb2> (.) :: (b -> c) -> (a -> b) -> a -> c
2023-11-16 15:10:20 +0100 <danse-nr3> % :t (+) . (+1)
2023-11-16 15:10:20 +0100 <yahb2> (+) . (+1) :: Num b => b -> b -> b
2023-11-16 15:10:28 +0100 <danse-nr3> % :t (-1) . (+) . (+1)
2023-11-16 15:10:28 +0100 <yahb2> (-1) . (+) . (+1) :: (Num b, Num ((b -> b) -> c)) => b -> c
2023-11-16 15:11:23 +0100 <danse-nr3> .oO(i lost an argument with the last one)
2023-11-16 15:17:54 +0100 <danse-nr3> ops, - is special
2023-11-16 15:17:55 +0100 <danse-nr3> % :t (+1) . (+) . (+1)
2023-11-16 15:17:55 +0100 <yahb2> (+1) . (+) . (+1) :: (Num b, Num (b -> b)) => b -> b -> b
2023-11-16 15:18:40 +0100 <danse-nr3> something tells me this is not going to work either...
2023-11-16 15:18:41 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-11-16 15:23:30 +0100 <probie> Are you trying to get something equivalent to `\x y -> (x + 1) + (y + 1)`?
2023-11-16 15:23:46 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 260 seconds)
2023-11-16 15:24:16 +0100thegeekinside(~thegeekin@189.180.53.210)
2023-11-16 15:25:54 +0100 <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
2023-11-16 15:28:41 +0100 <exarkun> well, not with `.`. but see Data.Composition.
2023-11-16 15:29:05 +0100 <danse-nr3> >:-D
2023-11-16 15:29:23 +0100 <danse-nr3> well, possibly will be not as >:-D as compositions of dots, let us see
2023-11-16 15:31:45 +0100 <danse-nr3> oh yeah, had looked that before and then forgot, possibly for the best :P ... thanks anyway for the pointer!
2023-11-16 15:35:41 +0100Buggys(Buggys@Buggy.shelltalk.net) (Ping timeout: 240 seconds)
2023-11-16 15:38:04 +0100 <danse-nr3> i think i will use it actually, hoping other people will not frown about it
2023-11-16 15:39:41 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com)
2023-11-16 15:39:41 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
2023-11-16 15:39:41 +0100wroathe(~wroathe@user/wroathe)
2023-11-16 15:44:00 +0100Buggys(Buggys@Buggy.shelltalk.net)
2023-11-16 15:48:30 +0100danse-nr3(~danse@151.57.198.230) (Ping timeout: 256 seconds)
2023-11-16 15:49:27 +0100danse-nr3(~danse@151.57.198.230)
2023-11-16 15:55:30 +0100alp_(~alp@2001:861:5e02:eff0:ab2f:dcd1:5fa1:c307) (Quit: Leaving)
2023-11-16 16:00:02 +0100szkl(uid110435@id-110435.uxbridge.irccloud.com) (Quit: Connection closed for inactivity)
2023-11-16 16:07:12 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Ping timeout: 256 seconds)
2023-11-16 16:07:48 +0100L29Ah(~L29Ah@wikipedia/L29Ah)
2023-11-16 16:08:06 +0100wroathe(~wroathe@user/wroathe) (Ping timeout: 260 seconds)
2023-11-16 16:09:13 +0100welterde(welterde@thinkbase.srv.welterde.de) (Server closed connection)
2023-11-16 16:09:57 +0100welterde(welterde@thinkbase.srv.welterde.de)
2023-11-16 16:10:55 +0100fweht(uid404746@id-404746.lymington.irccloud.com)
2023-11-16 16:17:53 +0100xstill_(xstill@fimu/xstill) (Server closed connection)
2023-11-16 16:17:54 +0100Inst(~Inst@120.244.192.250) (Ping timeout: 260 seconds)
2023-11-16 16:18:13 +0100xstill_(xstill@fimu/xstill)
2023-11-16 16:19:54 +0100glguy_glguy
2023-11-16 16:20:31 +0100vglfr(~vglfr@78.26.242.160)
2023-11-16 16:26:09 +0100Inst(~Inst@120.244.192.250)
2023-11-16 16:26:21 +0100vglfr(~vglfr@78.26.242.160) (Quit: Quit)
2023-11-16 16:26:44 +0100vglfr(~vglfr@78.26.242.160)
2023-11-16 16:30:06 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-11-16 16:34:29 +0100erty(~user@user/aeroplane)
2023-11-16 16:37:20 +0100noctux(~noctux@user/noctux) (Read error: Connection reset by peer)
2023-11-16 16:39:42 +0100noctux(~noctux@user/noctux)
2023-11-16 16:40:41 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk)
2023-11-16 16:45:21 +0100micro(~micro@user/micro) (Server closed connection)
2023-11-16 16:45:28 +0100micro(~micro@user/micro)
2023-11-16 16:45:47 +0100lhpitn_(~tn@193.96.224.66)
2023-11-16 16:48:12 +0100vpan(~vpan@mail.elitnet.lt) (Quit: Leaving.)
2023-11-16 16:49:38 +0100lhpitn(~tn@193.96.224.66) (Ping timeout: 260 seconds)
2023-11-16 16:50:55 +0100idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
2023-11-16 16:53:46 +0100ChaiTRex(~ChaiTRex@user/chaitrex) (Quit: ChaiTRex)
2023-11-16 16:53:51 +0100misterfish(~misterfis@87.215.131.102) (Ping timeout: 246 seconds)
2023-11-16 16:55:15 +0100Typedfern(~Typedfern@220.red-83-37-25.dynamicip.rima-tde.net) (Server closed connection)
2023-11-16 16:55:38 +0100Typedfern(~Typedfern@220.red-83-37-25.dynamicip.rima-tde.net)
2023-11-16 16:58:06 +0100mechap(~mechap@user/mechap)
2023-11-16 16:58:26 +0100lortabac(~lorenzo@2a01:e0a:541:b8f0:710e:fea0:5caf:9833) (Quit: WeeChat 3.5)
2023-11-16 16:58:27 +0100zetef(~quassel@95.77.17.251)
2023-11-16 17:00:48 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-11-16 17:01:17 +0100bgamari_(~bgamari@64.223.173.10) (Server closed connection)
2023-11-16 17:02:36 +0100bgamari(~bgamari@64.223.173.10)
2023-11-16 17:03:18 +0100mechap(~mechap@user/mechap) (Ping timeout: 246 seconds)
2023-11-16 17:03:38 +0100ChaiTRex(~ChaiTRex@user/chaitrex)
2023-11-16 17:03:43 +0100rubin55(sid175221@id-175221.hampstead.irccloud.com) (Server closed connection)
2023-11-16 17:04:01 +0100rubin55(sid175221@id-175221.hampstead.irccloud.com)
2023-11-16 17:05:24 +0100mechap(~mechap@user/mechap)
2023-11-16 17:10:29 +0100kimiamania46(~b4f4a2ab@user/kimiamania) (Ping timeout: 240 seconds)
2023-11-16 17:12:18 +0100driib5(~driib@vmi931078.contaboserver.net) (Server closed connection)
2023-11-16 17:12:52 +0100driib5(~driib@vmi931078.contaboserver.net)
2023-11-16 17:14:34 +0100davetapley(sid666@id-666.uxbridge.irccloud.com) (Server closed connection)
2023-11-16 17:14:44 +0100davetapley(sid666@id-666.uxbridge.irccloud.com)
2023-11-16 17:15:44 +0100kimiamania46(~65804703@user/kimiamania)
2023-11-16 17:15:54 +0100zetef(~quassel@95.77.17.251) (Ping timeout: 246 seconds)
2023-11-16 17:16:56 +0100zetef(~quassel@95.77.17.251)
2023-11-16 17:19:29 +0100kimiamania46(~65804703@user/kimiamania) (Client Quit)
2023-11-16 17:20:29 +0100kimiamania46(~65804703@user/kimiamania)
2023-11-16 17:24:06 +0100Franciman(~Franciman@mx1.fracta.dev) (Server closed connection)
2023-11-16 17:24:19 +0100Franciman(~Franciman@mx1.fracta.dev)
2023-11-16 17:25:00 +0100kimiamania46(~65804703@user/kimiamania) (Client Quit)
2023-11-16 17:25:21 +0100lisbeths(uid135845@id-135845.lymington.irccloud.com) (Quit: Connection closed for inactivity)
2023-11-16 17:26:23 +0100todi(~todi@p4fd1a3e6.dip0.t-ipconnect.de) (Ping timeout: 260 seconds)
2023-11-16 17:26:39 +0100akegalj(~akegalj@141-136-147-15.dsl.iskon.hr) (Quit: leaving)
2023-11-16 17:26:42 +0100kimiamania46(~65804703@user/kimiamania)
2023-11-16 17:30:05 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Remote host closed the connection)
2023-11-16 17:30:18 +0100pierrot(~pi@user/pierrot) (Server closed connection)
2023-11-16 17:30:25 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711)
2023-11-16 17:30:27 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk)
2023-11-16 17:30:35 +0100pierrot(~pi@user/pierrot)
2023-11-16 17:30:44 +0100Unode(~Unode@fg-ext-220.embl.de) (Server closed connection)
2023-11-16 17:30:56 +0100Unode(~Unode@fg-ext-220.embl.de)
2023-11-16 17:38:23 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 256 seconds)
2023-11-16 17:39:29 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk)
2023-11-16 17:40:08 +0100ddellacosta(~ddellacos@ool-44c738de.dyn.optonline.net) (Ping timeout: 256 seconds)
2023-11-16 17:49:30 +0100Sgeo(~Sgeo@user/sgeo)
2023-11-16 17:49:53 +0100__monty__(~toonn@user/toonn) (Quit: leaving)
2023-11-16 17:51:59 +0100lhpitn(~tn@ipv6-2d1e9090b42fa986.nowe.clients.hamburg.freifunk.net)
2023-11-16 17:54:58 +0100lhpitn_(~tn@193.96.224.66) (Ping timeout: 260 seconds)
2023-11-16 17:57:18 +0100acidjnk(~acidjnk@p200300d6e72b9344349e196aee999b14.dip0.t-ipconnect.de)
2023-11-16 18:00:06 +0100zetef(~quassel@95.77.17.251) (Ping timeout: 260 seconds)
2023-11-16 18:02:18 +0100ddellacosta(~ddellacos@ool-44c738de.dyn.optonline.net)
2023-11-16 18:02:51 +0100cawfee_(~root@2406:3003:2077:2758::babe) (Server closed connection)
2023-11-16 18:03:11 +0100cawfee_(~root@2406:3003:2077:2758::babe)
2023-11-16 18:04:18 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 260 seconds)
2023-11-16 18:05:20 +0100econo_(uid147250@id-147250.tinside.irccloud.com)
2023-11-16 18:09:28 +0100AlexZenon(~alzenon@178.34.162.228) (Ping timeout: 255 seconds)
2023-11-16 18:09:39 +0100jbalint(~jbalint@071-090-119-177.res.spectrum.com) (Server closed connection)
2023-11-16 18:09:50 +0100jbalint(~jbalint@2600:6c44:117f:e98a:816a:9488:fb1:7b7)
2023-11-16 18:11:02 +0100mjrosenb_(~mjrosenb@pool-96-232-177-77.nycmny.fios.verizon.net) (Server closed connection)
2023-11-16 18:11:11 +0100mjrosenb(~mjrosenb@pool-96-232-177-77.nycmny.fios.verizon.net)
2023-11-16 18:13:28 +0100dispater(~dispater@mail.brprice.uk) (Server closed connection)
2023-11-16 18:13:39 +0100machinedgod(~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 246 seconds)
2023-11-16 18:13:42 +0100glider(~glider@user/glider) (Server closed connection)
2023-11-16 18:13:48 +0100dispater(~dispater@mail.brprice.uk)
2023-11-16 18:13:50 +0100pavonia(~user@user/siracusa) (Quit: Bye!)
2023-11-16 18:15:14 +0100zetef(~quassel@95.77.17.251)
2023-11-16 18:15:34 +0100 <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])
2023-11-16 18:15:41 +0100 <erty> λ> putStrLn.show.length $ ([1..5] :: [Int])
2023-11-16 18:15:54 +0100tzh(~tzh@c-71-193-181-0.hsd1.or.comcast.net)
2023-11-16 18:16:18 +0100glider(~glider@user/glider)
2023-11-16 18:16:28 +0100_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl)
2023-11-16 18:16:41 +0100 <ski> yea
2023-11-16 18:16:43 +0100 <ski> @src print
2023-11-16 18:16:43 +0100 <lambdabot> print x = putStrLn (show x)
2023-11-16 18:16:48 +0100hippoid(~hippoid@c-98-213-162-40.hsd1.il.comcast.net) (Ping timeout: 246 seconds)
2023-11-16 18:17:12 +0100hippoid(~hippoid@c-98-213-162-40.hsd1.il.comcast.net)
2023-11-16 18:17:20 +0100 <erty> ski: thanks I did not know about `print`
2023-11-16 18:18:17 +0100skifigured
2023-11-16 18:20:05 +0100AlexZenon(~alzenon@178.34.162.228)
2023-11-16 18:21:21 +0100tzh(~tzh@c-71-193-181-0.hsd1.or.comcast.net) (Ping timeout: 246 seconds)
2023-11-16 18:21:34 +0100lhpitn(~tn@ipv6-2d1e9090b42fa986.nowe.clients.hamburg.freifunk.net) (Ping timeout: 260 seconds)
2023-11-16 18:26:22 +0100tzh(~tzh@c-71-193-181-0.hsd1.or.comcast.net)
2023-11-16 18:27:08 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk)
2023-11-16 18:29:53 +0100chele(~chele@user/chele) (Quit: Leaving)
2023-11-16 18:32:52 +0100euleritian(~euleritia@dynamic-002-247-251-218.2.247.pool.telefonica.de) (Read error: Connection reset by peer)
2023-11-16 18:33:09 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-11-16 18:33:24 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 268 seconds)
2023-11-16 18:39:03 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
2023-11-16 18:39:25 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-11-16 18:40:40 +0100cstml(~cstml@user/cstml) (Quit: WeeChat 2.3)
2023-11-16 18:43:17 +0100cstml(~cstml@user/cstml)
2023-11-16 18:44:08 +0100kuribas(~user@ip-188-118-57-242.reverse.destiny.be) (Remote host closed the connection)
2023-11-16 18:44:53 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Remote host closed the connection)
2023-11-16 18:45:10 +0100sord937(~sord937@gateway/tor-sasl/sord937) (Remote host closed the connection)
2023-11-16 18:46:50 +0100sord937(~sord937@gateway/tor-sasl/sord937)
2023-11-16 18:47:39 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl)
2023-11-16 18:47:42 +0100danse-nr3(~danse@151.57.198.230) (Ping timeout: 260 seconds)
2023-11-16 18:49:39 +0100 <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.
2023-11-16 18:49:47 +0100zetef(~quassel@95.77.17.251) (Ping timeout: 256 seconds)
2023-11-16 18:50:01 +0100 <dminuoso> It's much more enjoyable when you can visibly trace and control where lazyness occurs
2023-11-16 18:50:02 +0100fendor(~fendor@2a02:8388:1640:be00:2528:5dc7:a36e:9b87) (Ping timeout: 260 seconds)
2023-11-16 18:50:03 +0100 <duncan> You like that? That behaviour enrages me
2023-11-16 18:50:05 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com)
2023-11-16 18:50:06 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
2023-11-16 18:50:06 +0100wroathe(~wroathe@user/wroathe)
2023-11-16 18:50:42 +0100fweht(uid404746@id-404746.lymington.irccloud.com) (Quit: Connection closed for inactivity)
2023-11-16 18:50:48 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk)
2023-11-16 18:51:12 +0100 <dminuoso> duncan: It seems preferrable to when it invisibly happens across your entire program, except when it doesnt.
2023-11-16 18:51:44 +0100 <exarkun> How about when you accidentally try to iterate a map twice and you just get no elements the second time
2023-11-16 18:52:02 +0100 <exarkun> So you're forced to consume the whole thing before the first iteration and lose all laziness
2023-11-16 18:52:37 +0100 <dminuoso> exarkun: You are not?
2023-11-16 18:52:51 +0100 <dminuoso> You can map over iterables in Python and Ruby.
2023-11-16 18:52:52 +0100 <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.
2023-11-16 18:52:52 +0100 <EvanR> at least we're not as bad as clojure which mixes both
2023-11-16 18:53:24 +0100 <exarkun> dminuoso: We might be talking past each other. I meant the thing you get back from `map`.
2023-11-16 18:53:34 +0100 <exarkun> dminuoso: But more generally, the iterator protocol has no guarantee of reusability.
2023-11-16 18:53:36 +0100 <dminuoso> exarkun: Yes, you can write map(foo, map(foo, [1,2,3])) just fine.
2023-11-16 18:53:55 +0100 <exarkun> dminuoso: Right - but that only consumes each `map` result once. I mean `x = map(f, g); y(x); y(x)`
2023-11-16 18:54:26 +0100 <exarkun> dminuoso: It destroys the ability to reason locally about code which I usually frown on.
2023-11-16 18:54:31 +0100 <dminuoso> Oh you mean there is non sharing, yes.
2023-11-16 18:54:44 +0100 <dminuoso> The thing is just, lazyness in Haskell is not a built-in feature.
2023-11-16 18:54:53 +0100 <dminuoso> It's in reality just a lose and unwritten promise of GHC.
2023-11-16 18:55:42 +0100 <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.
2023-11-16 18:55:43 +0100 <EvanR> are you doubting the normal order evaluation
2023-11-16 18:55:50 +0100 <dminuoso> But nothing is ever really under your control
2023-11-16 18:55:52 +0100 <EvanR> which guarantees that if there is a normal form, it will find it
2023-11-16 18:56:00 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 246 seconds)
2023-11-16 18:56:35 +0100 <dminuoso> Haskell by its very definition is not lazy, its only non-strict.
2023-11-16 18:56:54 +0100 <dminuoso> If we assume the Haskell reports to be some valuable sense of definition, anyway
2023-11-16 18:57:12 +0100 <dminuoso> I just greatly dislike lazyness being so implicit and hidden away.
2023-11-16 18:57:19 +0100 <dminuoso> You can notice the pain with this with unsafeInterleaveIO
2023-11-16 18:57:33 +0100 <dminuoso> There's good reason why we *all* immediately switch to streaming libraries
2023-11-16 18:57:37 +0100 <EvanR> I'm glad you finally got around to that, you're trying to do I/O
2023-11-16 18:57:43 +0100 <dminuoso> No, not just IO.
2023-11-16 18:58:07 +0100 <dminuoso> Im suggesting we use streaming libraries precisely because its not clear where sharing happens, where lazyness happens, how its unraveled.
2023-11-16 18:58:24 +0100 <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
2023-11-16 18:58:27 +0100 <dminuoso> Why we just silently accept it in all the pure parts instead is a bit strange.
2023-11-16 18:58:33 +0100 <EvanR> er, do you agree
2023-11-16 18:58:36 +0100 <dminuoso> Perhaps its because at least the result should always be the same
2023-11-16 18:59:11 +0100 <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.
2023-11-16 18:59:13 +0100 <EvanR> ok you're really concerned about guarantees (or not) about when sharing happens
2023-11-16 18:59:32 +0100 <dminuoso> Sure, or where lazyness occurs.
2023-11-16 18:59:34 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl)
2023-11-16 18:59:36 +0100 <EvanR> that part is definitely not in the report
2023-11-16 18:59:53 +0100 <dminuoso> Like, seq is often too shallow, deepseq is often too strict.
2023-11-16 19:00:42 +0100 <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
2023-11-16 19:01:16 +0100 <EvanR> I haven't had a problem is understanding when laziness happens
2023-11-16 19:01:18 +0100 <dminuoso> Another thing is, you really dont see when things are strict.
2023-11-16 19:01:29 +0100 <dminuoso> I give you `f :: Int -> Int -> [Int] -> [Int]`
2023-11-16 19:01:39 +0100 <dminuoso> Do you know whether it will force the spine? Will it force the numbers?
2023-11-16 19:01:41 +0100 <dminuoso> Who knows
2023-11-16 19:02:03 +0100 <dminuoso> Look at the implementation, because strictness is rarely documented well
2023-11-16 19:02:08 +0100 <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.
2023-11-16 19:03:00 +0100 <EvanR> that won't help with the last point, documenting somehow the behavior of library code
2023-11-16 19:03:24 +0100 <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.
2023-11-16 19:03:45 +0100 <EvanR> but guaranteeing quality of library code sounds like some next level shit
2023-11-16 19:04:23 +0100 <EvanR> maybe in 10 years it will be moot because AI writes all your documentation
2023-11-16 19:04:37 +0100natto(~natto@129.154.243.159) (Server closed connection)
2023-11-16 19:05:19 +0100 <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.
2023-11-16 19:05:41 +0100 <dminuoso> Because a type signature lets you infer so much, it gives incentive to not write haddock docs.
2023-11-16 19:05:53 +0100 <monochrom> Well, it is actually more widespread than that.
2023-11-16 19:06:06 +0100 <monochrom> Look around all language standards.
2023-11-16 19:06:16 +0100 <EvanR> libraries in web land which have no documentation nor type signatures xD
2023-11-16 19:06:29 +0100 <EvanR> at best a readme with 1 example
2023-11-16 19:06:29 +0100analoq(~yashi@user/dies)
2023-11-16 19:06:42 +0100 <monochrom> Only C++ STL bothers to write "map lookup is lg time".
2023-11-16 19:07:54 +0100 <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).
2023-11-16 19:08:03 +0100natto(~natto@129.154.243.159)
2023-11-16 19:08:20 +0100 <monochrom> All other language standards simply leave it unsaid.
2023-11-16 19:08:28 +0100 <int-e> `containers` is one of the libraries that does document time complexity of most functions.
2023-11-16 19:08:59 +0100 <EvanR> I think it also explains uh "strictness"
2023-11-16 19:09:13 +0100 <EvanR> if that's even the right word
2023-11-16 19:09:24 +0100 <EvanR> "does this evaluate your stuff"
2023-11-16 19:10:42 +0100Square2(~Square4@user/square) (Ping timeout: 246 seconds)
2023-11-16 19:11:34 +0100johnw(~johnw@69.62.242.138)
2023-11-16 19:11:39 +0100 <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.
2023-11-16 19:12:36 +0100smalltalkman(uid545680@id-545680.hampstead.irccloud.com) (Server closed connection)
2023-11-16 19:12:45 +0100smalltalkman(uid545680@id-545680.hampstead.irccloud.com)
2023-11-16 19:13:28 +0100 <monochrom> And then in the case of Perl and Python, we are simply grateful that their dictators did not make you suffer.
2023-11-16 19:13:41 +0100 <EvanR> much
2023-11-16 19:14:43 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 256 seconds)
2023-11-16 19:15:12 +0100 <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.
2023-11-16 19:15:31 +0100 <monochrom> The other 1% is just to give a concrete model when teaching.
2023-11-16 19:16:00 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711)
2023-11-16 19:16:20 +0100 <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
2023-11-16 19:16:49 +0100 <EvanR> I would settle for type sigs and a minor amount of docs
2023-11-16 19:17:02 +0100 <EvanR> which a lot of stuff that I've used on hackage has
2023-11-16 19:17:38 +0100 <probie> If the type sig and mediocre docs don't suffice, just look at the source. It's pretty reliable documentation
2023-11-16 19:17:48 +0100 <monochrom> Clearly, it should be a 10-page essay and a 10-page type sig. Haven't you seen, like, servant and lens? >:)
2023-11-16 19:18:52 +0100Square(~Square@user/square)
2023-11-16 19:19:31 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk)
2023-11-16 19:19:40 +0100 <EvanR> in that case just make it a 10-page type sig
2023-11-16 19:19:53 +0100 <EvanR> soup up the type system to support everything you need to say
2023-11-16 19:20:06 +0100 <geekosaur> and a 10-page error message when you make a mistake, like C++
2023-11-16 19:20:11 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-11-16 19:20:21 +0100 <geekosaur> enterprise grade
2023-11-16 19:20:50 +0100 <probie> I have vague recollections of reading a paper on including time complexity in types in agda
2023-11-16 19:21:02 +0100 <darkling> No, Enterprise-grade is 10-page function names, like Java.
2023-11-16 19:21:33 +0100 <monochrom> We can surely do all of the above. :)
2023-11-16 19:22:05 +0100Tuplanolla(~Tuplanoll@91-159-68-236.elisa-laajakaista.fi)
2023-11-16 19:23:01 +0100 <probie> I'm 95% sure it was this https://projekter.aau.dk/projekter/files/335444832/pt101f20thesis.pdf
2023-11-16 19:24:21 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 256 seconds)
2023-11-16 19:24:35 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Remote host closed the connection)
2023-11-16 19:24:44 +0100euleritian(~euleritia@dynamic-002-247-251-218.2.247.pool.telefonica.de)
2023-11-16 19:24:50 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711)
2023-11-16 19:24:58 +0100 <EvanR> monochrom, you could use the competition card to solve anything. Library has zero documentation? No one would use it right??
2023-11-16 19:25:02 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 260 seconds)
2023-11-16 19:25:30 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 260 seconds)
2023-11-16 19:26:06 +0100 <monochrom> Heh.
2023-11-16 19:26:27 +0100 <monochrom> But let me go bonkers on this.
2023-11-16 19:27:18 +0100 <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.
2023-11-16 19:28:11 +0100 <monochrom> Libraries have two opposing competitions, even if commercial. Getting users on board, vs the users themselves wanting job security via barrier to entrance.
2023-11-16 19:29:00 +0100 <EvanR> job security through obscurity
2023-11-16 19:29:18 +0100lg188(~lg188@82.18.98.230)
2023-11-16 19:30:02 +0100 <monochrom> Ever wonder why all the senior experienced engineers are so smug about "this is field experience you won't learn from school"?
2023-11-16 19:30:18 +0100 <monochrom> I bet 80% of their experience are teachable in school.
2023-11-16 19:30:31 +0100 <monochrom> But where is the fun if school actually teaches it?
2023-11-16 19:30:31 +0100mjacob(~mjacob@adrastea.uberspace.de) (Read error: Connection reset by peer)
2023-11-16 19:30:49 +0100 <mauke> teachable, sure. but taught?
2023-11-16 19:31:37 +0100 <monochrom> I am exactly hypothesizing when it is not taught: No incentive to, actually much incentive against.
2023-11-16 19:31:43 +0100 <monochrom> s/when/why/
2023-11-16 19:31:57 +0100 <Inst> hmmm
2023-11-16 19:32:28 +0100 <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)
2023-11-16 19:33:28 +0100L29Ah(~L29Ah@wikipedia/L29Ah) ()
2023-11-16 19:34:24 +0100 <Inst> to someone new to computer science, would you recommend, as an adjunct to Thinking Functionally in Haskell, HaskellBook or Effective Haskell?
2023-11-16 19:35:14 +0100jathan(~jathan@69.61.93.38)
2023-11-16 19:35:20 +0100 <Inst> ehh, i've answered my own question, effective haskell is probably the better book
2023-11-16 19:35:40 +0100Unicorn_Princess(~Unicorn_P@user/Unicorn-Princess/x-3540542)
2023-11-16 19:35:57 +0100 <EvanR> affirming the consequent, haskell logic
2023-11-16 19:36:37 +0100mjacob(~mjacob@adrastea.uberspace.de)
2023-11-16 19:36:55 +0100lg188(~lg188@82.18.98.230) (Quit: Bye.)
2023-11-16 19:37:24 +0100kawzeg_(kawzeg@2a01:7e01::f03c:92ff:fee2:ec34) (Server closed connection)
2023-11-16 19:37:25 +0100 <EvanR> I still think the haskell course notes with exercises beat any book if you want to get into it
2023-11-16 19:37:43 +0100kawzeg_(kawzeg@2a01:7e01::f03c:92ff:fee2:ec34)
2023-11-16 19:38:00 +0100stefan-_(~cri@42dots.de) (Server closed connection)
2023-11-16 19:38:04 +0100 <EvanR> https://www.seas.upenn.edu/~cis1940/fall16/index.html ?
2023-11-16 19:38:16 +0100stefan-_(~cri@42dots.de)
2023-11-16 19:38:33 +0100 <EvanR> Functional Reactive Programming Homework 11 xD
2023-11-16 19:38:48 +0100 <Inst> I got a response from BadVortex
2023-11-16 19:38:58 +0100 <probie> Inst: SICP, and then teach them Haskell later
2023-11-16 19:39:13 +0100 <Inst> i'm recommending HTDP, SICP, Thinking Functionally with Hasklel, Effective Haskell, and need to pick up a Py book
2023-11-16 19:39:23 +0100adamCS(~adamCS@ec2-34-207-160-255.compute-1.amazonaws.com) (Server closed connection)
2023-11-16 19:40:09 +0100adamCS(~adamCS@ec2-34-207-160-255.compute-1.amazonaws.com)
2023-11-16 19:40:37 +0100cawfee_(~root@2406:3003:2077:2758::babe) (Ping timeout: 268 seconds)
2023-11-16 19:43:19 +0100lg188(~lg188@82.18.98.230)
2023-11-16 19:43:20 +0100 <ski> (SICP using Scheme, rather than Javascript)
2023-11-16 19:43:37 +0100wroathe(~wroathe@user/wroathe) (Ping timeout: 256 seconds)
2023-11-16 19:43:44 +0100 <dolio> Did they rewrite SICP with javascript?
2023-11-16 19:43:57 +0100 <EvanR> D:
2023-11-16 19:44:03 +0100target_i(~target_i@217.175.14.39)
2023-11-16 19:44:18 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Remote host closed the connection)
2023-11-16 19:44:53 +0100cawfee_(~root@2406:3003:2077:2758::babe)
2023-11-16 19:46:57 +0100cstml(~cstml@user/cstml) (Quit: WeeChat 2.3)
2023-11-16 19:49:10 +0100 <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>
2023-11-16 19:49:30 +0100thyriaen(~thyriaen@2a01:aea0:dd4:7550:6245:cbff:fe9f:48b1) (Remote host closed the connection)
2023-11-16 19:51:38 +0100 <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
2023-11-16 19:52:21 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 246 seconds)
2023-11-16 19:52:51 +0100 <ski> .. no idea
2023-11-16 19:55:09 +0100 <EvanR> if their version of js has proper tail calls I'd be interested
2023-11-16 19:55:11 +0100 <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/
2023-11-16 19:55:45 +0100 <ddellacosta> sounds like they keep to the same topics though
2023-11-16 19:56:00 +0100 <ddellacosta> with some additions?
2023-11-16 20:01:15 +0100hololeap(~quassel@user/hololeap) (Server closed connection)
2023-11-16 20:01:32 +0100hololeap(~quassel@user/hololeap)
2023-11-16 20:04:36 +0100zer0bitz_(~zer0bitz@user/zer0bitz)
2023-11-16 20:05:04 +0100 <EvanR> how about haskell edition
2023-11-16 20:08:19 +0100haskellbridge(~haskellbr@069-135-003-034.biz.spectrum.com) (Remote host closed the connection)
2023-11-16 20:08:50 +0100zer0bitz(~zer0bitz@user/zer0bitz) (Ping timeout: 252 seconds)
2023-11-16 20:10:00 +0100haskellbridge(~haskellbr@069-135-003-034.biz.spectrum.com)
2023-11-16 20:10:00 +0100ChanServ+v haskellbridge
2023-11-16 20:10:15 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 256 seconds)
2023-11-16 20:11:38 +0100ChaiTRex(~ChaiTRex@user/chaitrex) (Remote host closed the connection)
2023-11-16 20:11:40 +0100 <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)
2023-11-16 20:15:15 +0100ChaiTRex(~ChaiTRex@user/chaitrex)
2023-11-16 20:16:12 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk)
2023-11-16 20:16:19 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl)
2023-11-16 20:17:03 +0100 <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.
2023-11-16 20:17:06 +0100ggVGc(~ggVGc@a.lowtech.earth) (Ping timeout: 256 seconds)
2023-11-16 20:17:28 +0100ggVGc(~ggVGc@a.lowtech.earth)
2023-11-16 20:19:15 +0100euleritian(~euleritia@dynamic-002-247-251-218.2.247.pool.telefonica.de) (Read error: Connection reset by peer)
2023-11-16 20:19:24 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711)
2023-11-16 20:19:37 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-11-16 20:20:30 +0100ft(~ft@p508db3bc.dip0.t-ipconnect.de)
2023-11-16 20:23:28 +0100 <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.
2023-11-16 20:23:41 +0100tomboy64(~tomboy64@user/tomboy64) (Ping timeout: 240 seconds)
2023-11-16 20:23:54 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 256 seconds)
2023-11-16 20:24:50 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-11-16 20:28:23 +0100trev(~trev@user/trev) (Quit: trev)
2023-11-16 20:29:08 +0100tomboy64(~tomboy64@user/tomboy64)
2023-11-16 20:30:08 +0100waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
2023-11-16 20:31:39 +0100Simikando(~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Remote host closed the connection)
2023-11-16 20:35:16 +0100 <probie> As in something like `data NonEmpty' a b = Cons' a (NonEmpty'' a b); data NonEmpty'' a b = End | Cons'' b (NonEmpty' a b)`?
2023-11-16 20:38:05 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net)
2023-11-16 20:38:49 +0100pierrot(~pi@user/pierrot) (Read error: Connection reset by peer)
2023-11-16 20:38:52 +0100Nixkernal(~Nixkernal@115.16.194.178.dynamic.wline.res.cust.swisscom.ch) (Quit: No Ping reply in 180 seconds.)
2023-11-16 20:39:50 +0100 <kaol> I'm not quite sure about that representation. Basically I have one a and a list [(a,b)].
2023-11-16 20:40:16 +0100 <monochrom> I think you should write it. :)
2023-11-16 20:40:19 +0100Nixkernal(~Nixkernal@115.16.194.178.dynamic.wline.res.cust.swisscom.ch)
2023-11-16 20:40:49 +0100 <kaol> It's not too difficult to handle the list as a list and stick the extra a in front where needed.
2023-11-16 20:41:22 +0100 <kaol> I can't build NonEmpty like a :| [(a,b)].
2023-11-16 20:42:41 +0100pierrot(~pi@user/pierrot)
2023-11-16 20:44:03 +0100stilgart(~Christoph@chezlefab.net) (Server closed connection)
2023-11-16 20:44:11 +0100stilgart(~Christoph@chezlefab.net)
2023-11-16 20:45:22 +0100SanchayanMaity(sid478177@id-478177.hampstead.irccloud.com) (Server closed connection)
2023-11-16 20:45:32 +0100SanchayanMaity(sid478177@id-478177.hampstead.irccloud.com)
2023-11-16 20:49:58 +0100 <kaol> I guess I'll go with a list of type [(b,(a,a))]. Never mind me, just thinking on IRC.
2023-11-16 20:50:57 +0100thegman(~thegman@072-239-207-086.res.spectrum.com)
2023-11-16 20:54:02 +0100 <ski> kaol : hm, reminds me of `data SkipList a b = Nil | Cons a (SkipList b a)'
2023-11-16 20:54:42 +0100 <ski> but in your case, you always have one more `a's than `b's
2023-11-16 20:56:06 +0100 <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')
2023-11-16 20:56:52 +0100 <monochrom> "<a href="https://en.wikipedia.org/wiki/Skip_list">This</a> is not the skip list you're looking for." >:)
2023-11-16 20:57:09 +0100 <ski> hah, nah, not that one ;)
2023-11-16 20:58:32 +0100cheater_(~Username@user/cheater)
2023-11-16 20:58:33 +0100 <monochrom> We need an IETF central registry of data structure names, like they have one for domain names. :)
2023-11-16 21:00:19 +0100 <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
2023-11-16 21:00:25 +0100 <mauke> we should also avoid homophones
2023-11-16 21:00:25 +0100 <ski> `([a],[a])'
2023-11-16 21:00:40 +0100maukeannoyed that 'tree' and 'trie' are pronounced the same
2023-11-16 21:00:48 +0100 <kaol> 1+2*3 isn't that far off from what I'm modeling.
2023-11-16 21:01:38 +0100 <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'
2023-11-16 21:01:45 +0100 <monochrom> But I don't model 1+2*3 as a list.
2023-11-16 21:01:51 +0100 <ski> (and if you can map back, you could move back and forth)
2023-11-16 21:02:08 +0100 <ski> iirc, this is the "Clowns to the left of me, Jokers to the right" paper ?
2023-11-16 21:02:20 +0100cheater(~Username@user/cheater) (Ping timeout: 268 seconds)
2023-11-16 21:02:26 +0100 <monochrom> OK I lied. Sometimes I do. Then I just use (1, [("+", 2), ("*", 3)]).
2023-11-16 21:02:29 +0100cheater_cheater
2023-11-16 21:03:24 +0100 <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>
2023-11-16 21:03:33 +0100 <kaol> [("+",(1,2)),("*",(2,3))]
2023-11-16 21:04:19 +0100 <ski> kaol : wouldn't `[(b,(a,a))]' be something different from your NonEmpty' a b ?
2023-11-16 21:04:27 +0100 <monochrom> And the only use case I have met is writing chainl1 to use foldl instead of its own recursion.
2023-11-16 21:04:47 +0100 <ski> mauke : not more like "try-e" ?
2023-11-16 21:05:10 +0100 <ski> kaol : oh .. you're duplicating intermediate nodes ?
2023-11-16 21:05:14 +0100 <monochrom> more detailedly, chainl1 in terms of only Alternative and foldl, so that I don't have to use >>=.
2023-11-16 21:05:35 +0100 <mauke> ski: it's called "trie" because it's a data structure optimized for re-trie-val :-(
2023-11-16 21:05:35 +0100 <kaol> Good old zip xs $ tail xs
2023-11-16 21:05:37 +0100 <monochrom> (I still need my own recursion.)
2023-11-16 21:05:41 +0100 <ski> perhaps your expressions should be graphs, where the atomic components are the nodes, and the binary infix operators are edges ?
2023-11-16 21:05:55 +0100 <ski> mauke : oh, TIL
2023-11-16 21:06:13 +0100 <monochrom> ski: That one is also on Wikipedia. >:)
2023-11-16 21:06:43 +0100 <ski> apparently i never bothered to look the etymology up
2023-11-16 21:06:52 +0100 <ski> (but i had heard of the other type of skip list before)
2023-11-16 21:07:04 +0100 <monochrom> I got curious one day. "trie" is such a strange name.
2023-11-16 21:07:12 +0100 <ski> 'tis
2023-11-16 21:07:29 +0100 <kaol> zip <*> tail if I'm feeling evil.
2023-11-16 21:08:04 +0100 <ski> anyway this infix operator expression business makes me want to think about my idea of using composable continuations for parsing them
2023-11-16 21:10:10 +0100 <ski> @quote aztec.god
2023-11-16 21:10:10 +0100 <lambdabot> quicksilver says: zip`ap`tail - the Aztec god of consecutive numbers
2023-11-16 21:10:20 +0100 <ski> (for the incognoscenti)
2023-11-16 21:11:55 +0100 <erty> I've created this very simple algo to find min element in a list [http://ix.io/4LGC/haskell], does this looks good?
2023-11-16 21:12:00 +0100 <erty> I mean, does those pattern matching statements supposed to go inside guard statements
2023-11-16 21:12:26 +0100 <EvanR> data Chain a b = Node a | Link b (Chain a b)
2023-11-16 21:12:35 +0100 <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'
2023-11-16 21:12:55 +0100 <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 )
2023-11-16 21:13:04 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-11-16 21:13:14 +0100sord937(~sord937@gateway/tor-sasl/sord937) (Quit: sord937)
2023-11-16 21:13:32 +0100 <ski> EvanR : that's `([b],a)' .. sometimes useful thing, actually
2023-11-16 21:14:00 +0100 <EvanR> no...
2023-11-16 21:14:15 +0100 <ski> monochrom : i've heard the name, but haven't checked the details
2023-11-16 21:14:19 +0100 <mauke> erty: I wouldn't have written it this way, but that looks correct
2023-11-16 21:14:47 +0100 <EvanR> you can have more than one a in the chain
2023-11-16 21:14:57 +0100 <ski> EvanR : or did you mean to flip the parameters in the recursion ?
2023-11-16 21:15:05 +0100 <EvanR> no
2023-11-16 21:15:28 +0100 <EvanR> er, but I did make a big mistake
2023-11-16 21:15:39 +0100 <EvanR> data Chain a b = Node a | Link b (Chain a b) (Chain a b)
2023-11-16 21:15:56 +0100 <ski> ah, that makes more sense then
2023-11-16 21:16:11 +0100 <ski> ok, so it's a tree with one type of element in internal nodes, and another type at leaves
2023-11-16 21:16:17 +0100 <EvanR> yeah
2023-11-16 21:16:18 +0100 <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.
2023-11-16 21:16:32 +0100 <erty> mauke: If I may ask, how you would have written that function :-), Thanks ?
2023-11-16 21:16:44 +0100 <erty> *-?
2023-11-16 21:16:52 +0100 <monochrom> Because it goes like "upon seeing this operator, here is the new precedence interval to parse for".
2023-11-16 21:16:53 +0100 <EvanR> if you flatten it out it's like that puncuated list type from earlier
2023-11-16 21:17:31 +0100 <monochrom> with the main loop being basically a case analysis on precedence interval.
2023-11-16 21:17:38 +0100 <ski> monochrom : hm, i'll try to recall looking in that, for comparision
2023-11-16 21:18:08 +0100 <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
2023-11-16 21:18:27 +0100 <mauke> erty: basically, pulling out the "current minimum" element into its own function parameter
2023-11-16 21:18:46 +0100 <kaol> foldr1 min
2023-11-16 21:18:54 +0100 <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'
2023-11-16 21:18:56 +0100Pickchea(~private@user/pickchea)
2023-11-16 21:19:03 +0100 <ski> (to avoid consing all the time)
2023-11-16 21:19:04 +0100 <mauke> then I'd realize that 'if x < m then x else m' is just 'min x m'
2023-11-16 21:19:30 +0100 <ski> EvanR : hmm, except that it also has nesting structure now
2023-11-16 21:19:30 +0100 <mauke> and then the whole thing collapses into a fold, as kaol said :-)
2023-11-16 21:19:37 +0100 <ski> EvanR : s/nesting/grouping/
2023-11-16 21:19:45 +0100 <EvanR> "parentheses" ?
2023-11-16 21:19:54 +0100 <ski> yea
2023-11-16 21:19:59 +0100 <EvanR> you could say the basic list has that too...
2023-11-16 21:20:08 +0100 <EvanR> x:(y:(z:...
2023-11-16 21:20:20 +0100 <monochrom> ski: This is beautiful and evil at the same time that n+1 = 2^n for partial-order morphisms!
2023-11-16 21:21:12 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-11-16 21:21:19 +0100 <EvanR> but in that case there's now way to represent the "same list" multiple ways
2023-11-16 21:21:21 +0100 <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
2023-11-16 21:21:28 +0100 <monochrom> Also dangerously close to combinatorics which is the only area of math that I hate (because I fear it --- "fear begets hate" amirite?)
2023-11-16 21:21:59 +0100 <EvanR> and hate begets unironic use of unsafeCoerce
2023-11-16 21:22:11 +0100 <monochrom> fear leads to hate, hate leads to switching major to CS. :)
2023-11-16 21:22:41 +0100 <ski> EvanR : yea, but basic lists are fully right-associated (`x * y * z' is `x * (y * (z * 1))'), but your `Chain' allows different associations
2023-11-16 21:23:01 +0100 <mauke> CS - it's a gas
2023-11-16 21:23:02 +0100 <ski> (number of associations of a list of length `n' is Catalan number)
2023-11-16 21:23:35 +0100 <EvanR> I based it on the "JList" structure data JList a = Empty | Single a | Join (JList a) (JList a)
2023-11-16 21:24:13 +0100 <erty> mauke: unfortunately ,that line looks complicated for me. I will save it and will analyze it later
2023-11-16 21:24:14 +0100 <EvanR> which has even more equivalents
2023-11-16 21:25:02 +0100 <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
2023-11-16 21:26:54 +0100 <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)')
2023-11-16 21:27:34 +0100 <EvanR> that is looking better in some sense
2023-11-16 21:27:41 +0100 <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 ?
2023-11-16 21:28:35 +0100 <monochrom> It does? I thought it was rambling on Newton's method only. >:)
2023-11-16 21:29:07 +0100 <ski> oh, i guess i meant alpha-beta pruning
2023-11-16 21:29:12 +0100 <ski> @where whyfp
2023-11-16 21:29:12 +0100 <lambdabot> "Why Functional Programming Matters" by John Hughes in 1984 at <http://www.cse.chalmers.se/~rjmh/Papers/whyfp.html>
2023-11-16 21:29:20 +0100 <erty> ski: In your previous comment to me, what do you mean by `unbounded` space?
2023-11-16 21:29:54 +0100 <erty> min function would scan all elemetns of the list
2023-11-16 21:29:57 +0100 <monochrom> OK yeah found it.
2023-11-16 21:30:01 +0100 <mauke> erty: it looks a lot better with proper formatting :-)
2023-11-16 21:30:11 +0100 <ski> erty : do you understand what i meant by "direct recursion", rather than accumulator ?
2023-11-16 21:30:42 +0100 <ski> monochrom : p. 19
2023-11-16 21:31:53 +0100 <erty> ski: No, I dont understand, but I am sorry, but am I not using recursion?
2023-11-16 21:31:54 +0100 <ski> erty : but, i guess, if not, perhaps first understand mauke's version, and suggested improvements (sans the `foldl' one)
2023-11-16 21:32:00 +0100 <ski> you are
2023-11-16 21:32:17 +0100 <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.
2023-11-16 21:32:24 +0100 <ski> you are using the first element of the list as an accumulator, accumulating the least element you've seen, so far
2023-11-16 21:32:35 +0100 <mauke> findMin (x : xs) = min x (findMin xs) -- this one?
2023-11-16 21:32:41 +0100 <ski> in mauke's version, the first argument of `go' is the accumulator
2023-11-16 21:33:05 +0100cheater_(~Username@user/cheater)
2023-11-16 21:33:55 +0100 <EvanR> findMin = head -- sometimes
2023-11-16 21:34:03 +0100 <ski> monochrom : i don't think it helps just `minTree' ? you have to have both `min' and `max', right ?
2023-11-16 21:34:24 +0100 <ski> er
2023-11-16 21:34:27 +0100 <ski> mauke ^
2023-11-16 21:35:45 +0100 <monochrom> Too many "min"s. We need 10-page function names, yes. >:)
2023-11-16 21:35:49 +0100 <ski> erty : anyway, have you implemented `length' or `sum' yourself ?
2023-11-16 21:36:01 +0100 <ski> monochrom : one min.
2023-11-16 21:36:47 +0100 <erty> ski: yes I have, those accumulate results
2023-11-16 21:37:13 +0100 <ski> well, the most direct definitions would be
2023-11-16 21:37:19 +0100 <ski> length [ ] = 0
2023-11-16 21:37:25 +0100 <ski> length (x:xs) = 1 + length xs
2023-11-16 21:37:26 +0100 <ski> and
2023-11-16 21:37:31 +0100cheater(~Username@user/cheater) (Ping timeout: 256 seconds)
2023-11-16 21:37:31 +0100 <ski> sum [ ] = 0
2023-11-16 21:37:32 +0100cheater_cheater
2023-11-16 21:37:41 +0100 <ski> sum (n:ns) = n + sum ns
2023-11-16 21:37:48 +0100 <ski> (and similarly for `product')
2023-11-16 21:38:12 +0100 <ski> (although, one could special-case so that one stops traversing in `product', if one sees a `0' ..)
2023-11-16 21:38:25 +0100 <ski> erty : do you understand how these definitions would unfold ?
2023-11-16 21:39:02 +0100 <erty> yes i have implemented them and understand them very well, (thanks fo typing :-)
2023-11-16 21:39:14 +0100 <erty> are those using unbounded space?
2023-11-16 21:39:17 +0100 <ski> let's try `sum [2,3,5,7]'
2023-11-16 21:39:23 +0100 <ski> sum [2,3,5,7]
2023-11-16 21:39:31 +0100 <ski> = 2 + sum [3,5,7]
2023-11-16 21:39:37 +0100 <ski> = 2 + (3 + sum [5,7])
2023-11-16 21:39:49 +0100 <ski> = 2 + (3 + (5 + sum [7]))
2023-11-16 21:39:56 +0100 <ski> = 2 + (3 + (5 + (7 + sum [])))
2023-11-16 21:39:59 +0100 <ski> = 2 + (3 + (5 + (7 + sum 0)))
2023-11-16 21:40:02 +0100 <ski> er
2023-11-16 21:40:04 +0100 <ski> = 2 + (3 + (5 + (7 + 0)))
2023-11-16 21:40:07 +0100 <ski> = 2 + (3 + (5 + 7))
2023-11-16 21:40:09 +0100 <ski> = 2 + (3 + 12)
2023-11-16 21:40:13 +0100 <ski> = 2 + 15
2023-11-16 21:40:15 +0100 <ski> = 17
2023-11-16 21:40:38 +0100 <erty> you are accumulating and recursing
2023-11-16 21:40:41 +0100 <ski> note how we get deeper and deeper, the recursive call gets embedded inside a growing context. this is basically "the stack"
2023-11-16 21:41:14 +0100 <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"
2023-11-16 21:41:16 +0100 <mauke> not really accumulating
2023-11-16 21:41:21 +0100 <ski> no, there's no accumulator here
2023-11-16 21:41:36 +0100 <ski> here's the accumulator version, for comparision
2023-11-16 21:41:53 +0100 <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
2023-11-16 21:42:00 +0100 <ski> sum ns = sumPlus 0 ns
2023-11-16 21:42:06 +0100 <ski> sumPlus acc [ ] = acc
2023-11-16 21:42:20 +0100 <ski> sumPlus acc (n:ns) = sumPlus (acc + n) ns
2023-11-16 21:42:34 +0100 <ski> now, imagine the following reduction/"evaulation" trace
2023-11-16 21:42:41 +0100 <ski> sum [2,3,5,7]
2023-11-16 21:42:50 +0100 <ski> = sumPlus 0 [2,3,5,7]
2023-11-16 21:42:58 +0100 <ski> = sumPlus (0 + 2) [3,5,7]
2023-11-16 21:43:02 +0100 <ski> = sumPlus 2 [3,5,7]
2023-11-16 21:43:08 +0100 <ski> = sumPlus (2 + 3) [5,7]
2023-11-16 21:43:12 +0100 <ski> = sumPlus 5 [5,7]
2023-11-16 21:43:19 +0100 <ski> = sumPlus (5 + 5) [7]
2023-11-16 21:43:22 +0100 <ski> = sumPlus 10 [7]
2023-11-16 21:43:28 +0100 <ski> = sumPlus (10 + 7) []
2023-11-16 21:43:32 +0100 <ski> = sumPlus 17 []
2023-11-16 21:43:34 +0100 <ski> = 17
2023-11-16 21:43:44 +0100 <erty> ok
2023-11-16 21:43:49 +0100 <ski> here, there's no growth of the context around the recursion
2023-11-16 21:43:54 +0100 <ski> however !
2023-11-16 21:44:06 +0100 <EvanR> that's the javascript edition
2023-11-16 21:44:08 +0100 <ski> this is actually not how this would work, in a lazy implementation of Haskell
2023-11-16 21:44:16 +0100 <ski> yea, this is how it would work, in a strict language
2023-11-16 21:44:16 +0100matijja(~matijja@193.77.181.201) (Server closed connection)
2023-11-16 21:44:22 +0100 <ski> in Haskell, you actually get
2023-11-16 21:44:28 +0100 <ski> sum [2,3,5,7]
2023-11-16 21:44:35 +0100 <ski> = sumPlus 0 [2,3,5,7]
2023-11-16 21:44:41 +0100 <ski> = sumPlus (0 + 2) [3,5,7]
2023-11-16 21:44:44 +0100 <mauke> or if ghc -O2 figures out the function is strict in its first argument :-)
2023-11-16 21:44:48 +0100 <ski> = sumPlus ((0 + 2) + 3) [5,7]
2023-11-16 21:44:56 +0100 <ski> = sumPlus (((0 + 2) + 3) + 5) [7]
2023-11-16 21:45:02 +0100matijja(~matijja@193.77.181.201)
2023-11-16 21:45:02 +0100 <ski> = sumPlus ((((0 + 2) + 3) + 5) + 7) []
2023-11-16 21:45:10 +0100 <ski> = (((0 + 2) + 3) + 5) + 7
2023-11-16 21:45:14 +0100 <ski> = ((2 + 3) + 5) + 7
2023-11-16 21:45:18 +0100 <ski> = (5 + 5) + 7
2023-11-16 21:45:21 +0100 <ski> = 10 + 7
2023-11-16 21:45:22 +0100 <ski> = 17
2023-11-16 21:45:44 +0100 <erty> ok
2023-11-16 21:45:53 +0100 <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
2023-11-16 21:46:31 +0100 <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)
2023-11-16 21:46:57 +0100 <ski> but if you don't want to rely on optimizations, you should make sure the accumulator gets demanded, as we go
2023-11-16 21:47:10 +0100 <ski> simplest way is to use a strict pattern
2023-11-16 21:47:15 +0100 <erty> ok
2023-11-16 21:47:23 +0100 <ski> sumPlus !acc (n:ns) = sumPlus (acc + n) ns
2023-11-16 21:47:32 +0100 <ski> you could also use the `seq' function
2023-11-16 21:47:41 +0100 <ski> sumPlus acc (n:ns) = acc `seq` sumPlus (acc + n) ns
2023-11-16 21:48:18 +0100 <mauke> ... = (sumPlus $! (acc + n)) ns
2023-11-16 21:48:52 +0100 <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'
2023-11-16 21:49:04 +0100 <ski> yea, `$!' is another option
2023-11-16 21:49:30 +0100 <EvanR> :t f $! x y
2023-11-16 21:49:31 +0100 <lambdabot> error:
2023-11-16 21:49:31 +0100 <lambdabot> • Couldn't match expected type ‘Expr -> a0’ with actual type ‘Expr’
2023-11-16 21:49:31 +0100 <lambdabot> • The function ‘x’ is applied to one argument,
2023-11-16 21:49:45 +0100 <EvanR> why are parentheses needed
2023-11-16 21:49:57 +0100 <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)
2023-11-16 21:50:00 +0100 <mauke> application beats infix operators
2023-11-16 21:50:33 +0100 <mauke> :t \f x y -> f $! x $ y
2023-11-16 21:50:34 +0100 <lambdabot> (a -> b) -> (t -> a) -> t -> b
2023-11-16 21:50:49 +0100 <ski> .. and unfortunately `$' and `$!' are right-associative, not left-associative. otherwise you could have said `sumPlus $! (acc + n) $ ns'
2023-11-16 21:50:52 +0100 <mauke> yeah, that's f (x y)
2023-11-16 21:50:57 +0100pavonia(~user@user/siracusa)
2023-11-16 21:50:59 +0100 <EvanR> yeesh
2023-11-16 21:51:28 +0100 <ski> (well, even without the brackets, so `sumPlus $! acc + n $ ns', i guess)
2023-11-16 21:52:03 +0100mechap(~mechap@user/mechap) (Ping timeout: 246 seconds)
2023-11-16 21:52:04 +0100 <ski> erty : anyway .. hopefully it's clear what i meant by "direct recursive" version of `findMin', now ?
2023-11-16 21:53:17 +0100 <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
2023-11-16 21:54:05 +0100 <ski> yw
2023-11-16 21:54:48 +0100 <EvanR> in the first version of sum given above, the one with sum (n:ns) = n + sum ns, which "stack" is growing.
2023-11-16 21:55:11 +0100 <ski> "the stack"
2023-11-16 21:55:19 +0100 <EvanR> lol
2023-11-16 21:55:32 +0100 <ski> (Felleisen evaluation contexts)
2023-11-16 21:56:27 +0100 <EvanR> which level of abstraction do we need to be on to see the stack
2023-11-16 21:56:30 +0100 <ski> E[] ::= [] | E[] E | case E[] of P -> E; ...
2023-11-16 21:56:47 +0100 <ski> but *not* including `E E[]' as an alternative !
2023-11-16 21:57:48 +0100 <EvanR> a context is an empty context, or a context with E appended, or a case....?
2023-11-16 21:57:49 +0100 <ski> so we have reduction steps like
2023-11-16 21:58:37 +0100imdoor(~imdoor@balticom-142-78-50.balticom.lv)
2023-11-16 21:58:54 +0100 <ski> E[(\x -> E1) E0] ~> E[ E1{x := E0} ]
2023-11-16 21:59:29 +0100 <ski> yea, the `E[] E' case says that to reduce an application, we *need* to reduce the operator position
2023-11-16 21:59:53 +0100 <mauke> TIL Felleisen is an archaic word meaning knapsack and is related to valise
2023-11-16 21:59:55 +0100 <ski> so, pushing the operand expression on the stack, to later pass into the resulting lambda
2023-11-16 22:00:01 +0100imdoor(~imdoor@balticom-142-78-50.balticom.lv) (Client Quit)
2023-11-16 22:00:19 +0100imdoor(~imdoor@balticom-142-78-50.balticom.lv)
2023-11-16 22:00:35 +0100skithought the "sen" was a version of "son", common surname ending
2023-11-16 22:00:45 +0100 <ski> @wn valise
2023-11-16 22:00:46 +0100 <lambdabot> *** "valise" wn "WordNet (r) 3.0 (2006)"
2023-11-16 22:00:46 +0100 <lambdabot> valise
2023-11-16 22:00:46 +0100 <lambdabot> n 1: a small overnight bag for short trips
2023-11-16 22:01:41 +0100 <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
2023-11-16 22:02:44 +0100 <EvanR> so there's an argument stack for the application, and a continuation stack for case
2023-11-16 22:03:01 +0100 <ski> yep. or just a common stack for both
2023-11-16 22:03:43 +0100 <EvanR> remembering the context you are in when delving into an expression tree sounds like a zipper
2023-11-16 22:04:20 +0100 <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
2023-11-16 22:05:03 +0100 <ski> yea, you can represent the evaluation context "inside-out", like you'd commonly do with zippers
2023-11-16 22:05:22 +0100 <dolio> It doesn't have all the cases the zipper would, though.
2023-11-16 22:05:36 +0100 <ski> i guess the evaluation context restricts which paths are valid, as compared to all possible paths
2023-11-16 22:05:56 +0100 <dolio> It's like a zipper for neutral terms.
2023-11-16 22:06:28 +0100 <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))
2023-11-16 22:06:30 +0100 <dolio> Focused on the part making it neutral.
2023-11-16 22:07:50 +0100 <ski> dolio : hm, reminds me, do you know off hand a nice paper (perhaps the originating source) to read about neutral terms ?
2023-11-16 22:08:08 +0100 <dolio> Not off hand.
2023-11-16 22:08:22 +0100skiwas thinking it was related to uniform derivations and goal-directedness & focusing
2023-11-16 22:09:30 +0100 <ski> EvanR : anyway, iirc, Felleisen contexts originate from Matthias Felleisen's thesis (on continuations, iirc)
2023-11-16 22:13:50 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 256 seconds)
2023-11-16 22:14:13 +0100target_i(~target_i@217.175.14.39) (Quit: leaving)
2023-11-16 22:14:46 +0100euleritian(~euleritia@dynamic-002-247-251-218.2.247.pool.telefonica.de)
2023-11-16 22:18:10 +0100 <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"
2023-11-16 22:19:02 +0100califax(~califax@user/califx) (Remote host closed the connection)
2023-11-16 22:19:57 +0100califax(~califax@user/califx)
2023-11-16 22:20:42 +0100 <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/iclp90paresch…>
2023-11-16 22:20:46 +0100 <ski> )
2023-11-16 22:21:30 +0100 <ski> (this is computational linguistics. well, the paper is the intersection of that, and logic programming)
2023-11-16 22:21:48 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-11-16 22:23:12 +0100 <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
2023-11-16 22:23:14 +0100 <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?
2023-11-16 22:24:38 +0100 <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]"
2023-11-16 22:26:21 +0100pounce(~pounce@user/cute/pounce) (Server closed connection)
2023-11-16 22:26:35 +0100pounce(~pounce@user/cute/pounce)
2023-11-16 22:27:36 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-11-16 22:28:33 +0100 <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
2023-11-16 22:28:43 +0100cheater_(~Username@user/cheater)
2023-11-16 22:29:30 +0100cheater(~Username@user/cheater) (Ping timeout: 246 seconds)
2023-11-16 22:29:39 +0100cheater_cheater
2023-11-16 22:30:22 +0100 <dolio> Oh, perhaps.
2023-11-16 22:32:36 +0100 <dolio> I'm not really familiar with how different linguistic stuff is encoded into formal languages.
2023-11-16 22:33:36 +0100cheater_(~Username@user/cheater)
2023-11-16 22:35:30 +0100mc47(~mc47@xmonad/TheMC47) (Remote host closed the connection)
2023-11-16 22:35:53 +0100cheater(~Username@user/cheater) (Ping timeout: 256 seconds)
2023-11-16 22:36:01 +0100cheater_cheater
2023-11-16 22:36:13 +0100 <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.
2023-11-16 22:37:01 +0100 <dolio> I don't know how 'redexes' arise in linguistics, though.
2023-11-16 22:39:00 +0100mastarija(~mastarija@42-10.dsl.iskon.hr)
2023-11-16 22:40:49 +0100fendor(~fendor@2a02:8388:1640:be00:2528:5dc7:a36e:9b87)
2023-11-16 22:49:27 +0100cheater_(~Username@user/cheater)
2023-11-16 22:50:53 +0100takuan(~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection)
2023-11-16 22:51:14 +0100jmdaemon(~jmdaemon@user/jmdaemon)
2023-11-16 22:53:10 +0100oo_miguel(~Thunderbi@78-11-179-96.static.ip.netia.com.pl) (Ping timeout: 260 seconds)
2023-11-16 22:53:30 +0100cheater(~Username@user/cheater) (Ping timeout: 256 seconds)
2023-11-16 22:53:33 +0100cheater_cheater
2023-11-16 22:54:04 +0100ubert(~Thunderbi@178.115.42.132.wireless.dyn.drei.com) (Ping timeout: 256 seconds)
2023-11-16 22:54:38 +0100elkcl(~elkcl@broadband-95-84-226-240.ip.moscow.rt.ru) (Ping timeout: 256 seconds)
2023-11-16 22:56:19 +0100_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Remote host closed the connection)
2023-11-16 22:57:43 +0100CiaoSen(~Jura@2a05:5800:2cb:ad00:2a3a:4dff:fe84:dbd5)
2023-11-16 22:59:28 +0100fendor(~fendor@2a02:8388:1640:be00:2528:5dc7:a36e:9b87) (Remote host closed the connection)
2023-11-16 22:59:31 +0100idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1)
2023-11-16 23:00:23 +0100rekahsoft(~rekahsoft@bas1-sudbury98-67-70-201-226.dsl.bell.ca)
2023-11-16 23:00:35 +0100rekahsoft(~rekahsoft@bas1-sudbury98-67-70-201-226.dsl.bell.ca) (Remote host closed the connection)
2023-11-16 23:01:13 +0100rekahsoft(~rekahsoft@67.70.201.226)
2023-11-16 23:03:47 +0100elkcl(~elkcl@broadband-95-84-226-240.ip.moscow.rt.ru)
2023-11-16 23:06:14 +0100sawilagar(~sawilagar@user/sawilagar) (Ping timeout: 260 seconds)
2023-11-16 23:07:33 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-11-16 23:07:40 +0100rekahsoft(~rekahsoft@67.70.201.226) (Ping timeout: 256 seconds)
2023-11-16 23:09:45 +0100EsoAlgo81(~EsoAlgo@129.146.136.145) (Server closed connection)
2023-11-16 23:10:06 +0100EsoAlgo81(~EsoAlgo@129.146.136.145)
2023-11-16 23:10:09 +0100mastarija(~mastarija@42-10.dsl.iskon.hr) (Quit: Client closed)
2023-11-16 23:14:43 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5)
2023-11-16 23:14:59 +0100notzmv(~zmv@user/notzmv) (Ping timeout: 256 seconds)
2023-11-16 23:15:02 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 256 seconds)
2023-11-16 23:15:14 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655)
2023-11-16 23:17:00 +0100cheater_(~Username@user/cheater)
2023-11-16 23:17:26 +0100CiaoSen(~Jura@2a05:5800:2cb:ad00:2a3a:4dff:fe84:dbd5) (Ping timeout: 260 seconds)
2023-11-16 23:19:12 +0100CiaoSen(~Jura@2a05:5800:2be:2c00:2a3a:4dff:fe84:dbd5)
2023-11-16 23:20:42 +0100cheater(~Username@user/cheater) (Ping timeout: 260 seconds)
2023-11-16 23:20:47 +0100cheater_cheater
2023-11-16 23:21:06 +0100mastarija(~mastarija@42-10.dsl.iskon.hr)
2023-11-16 23:21:42 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-11-16 23:21:47 +0100Pickchea(~private@user/pickchea) (Quit: Leaving)
2023-11-16 23:23:39 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5)
2023-11-16 23:26:20 +0100 <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-return…
2023-11-16 23:26:46 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 260 seconds)
2023-11-16 23:26:51 +0100thegman(~thegman@072-239-207-086.res.spectrum.com) (Read error: Connection reset by peer)
2023-11-16 23:27:12 +0100 <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)"
2023-11-16 23:32:02 +0100cheater_(~Username@user/cheater)
2023-11-16 23:34:20 +0100cheater(~Username@user/cheater) (Ping timeout: 268 seconds)
2023-11-16 23:34:28 +0100cheater_cheater
2023-11-16 23:35:57 +0100CiaoSen(~Jura@2a05:5800:2be:2c00:2a3a:4dff:fe84:dbd5) (Ping timeout: 256 seconds)
2023-11-16 23:40:43 +0100thegeekinside(~thegeekin@189.180.53.210) (Remote host closed the connection)
2023-11-16 23:44:38 +0100Guest|94(~Guest|94@62.151.227.157)
2023-11-16 23:45:52 +0100Guest|94(~Guest|94@62.151.227.157) (Client Quit)
2023-11-16 23:47:10 +0100imdoor(~imdoor@balticom-142-78-50.balticom.lv) (Quit: imdoor)
2023-11-16 23:47:39 +0100imdoor(~imdoor@balticom-142-78-50.balticom.lv)
2023-11-16 23:47:45 +0100imdoor(~imdoor@balticom-142-78-50.balticom.lv) (Remote host closed the connection)
2023-11-16 23:48:05 +0100wroathe(~wroathe@50.205.197.50)
2023-11-16 23:48:06 +0100wroathe(~wroathe@50.205.197.50) (Changing host)
2023-11-16 23:48:06 +0100wroathe(~wroathe@user/wroathe)
2023-11-16 23:49:09 +0100wroathe(~wroathe@user/wroathe) (Client Quit)
2023-11-16 23:49:14 +0100caryhartline(~caryhartl@168.182.58.169) (Quit: caryhartline)
2023-11-16 23:50:27 +0100michalz(~michalz@185.246.207.193) (Remote host closed the connection)
2023-11-16 23:52:39 +0100L29Ah(~L29Ah@wikipedia/L29Ah)
2023-11-16 23:56:16 +0100gmg(~user@user/gehmehgeh) (Quit: Leaving)
2023-11-16 23:56:53 +0100Square2(~Square4@user/square)
2023-11-16 23:57:45 +0100mastarija(~mastarija@42-10.dsl.iskon.hr) (Quit: Client closed)
2023-11-16 23:59:45 +0100Square(~Square@user/square) (Ping timeout: 256 seconds)