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 +0100 | jmdaemon | (~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 +0100 | coot | (~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot) |
2023-11-16 00:07:44 +0100 | coot | (~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 +0100 | jmdaemon | (~jmdaemon@user/jmdaemon) |
2023-11-16 00:10:11 +0100 | chomwitt | (~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 +0100 | santiagopim | (~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 +0100 | ski | was just trying to fix the `get >>= runReaderT r' one (which obviously already presupposed `Monad') |
2023-11-16 00:18:30 +0100 | vilya_ | (~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 +0100 | vilya | (~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 +0100 | misterfish | (~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 268 seconds) |
2023-11-16 00:22:40 +0100 | coot | (~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 +0100 | caryhartline | (~caryhartl@168.182.58.169) |
2023-11-16 00:31:38 +0100 | wroathe | (~wroathe@user/wroathe) (Ping timeout: 256 seconds) |
2023-11-16 00:36:10 +0100 | mechap | (~mechap@user/mechap) (Ping timeout: 256 seconds) |
2023-11-16 00:37:52 +0100 | stiell | (~stiell@gateway/tor-sasl/stiell) (Ping timeout: 264 seconds) |
2023-11-16 00:38:34 +0100 | idgaen | (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1) |
2023-11-16 00:38:58 +0100 | tremon | (~tremon@83.80.159.219) (Quit: getting boxed in) |
2023-11-16 00:39:31 +0100 | Pickchea | (~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 +0100 | hueso | (~root@user/hueso) (Quit: hueso) |
2023-11-16 00:46:19 +0100 | hueso | (~root@user/hueso) |
2023-11-16 00:50:52 +0100 | hueso | (~root@user/hueso) (Client Quit) |
2023-11-16 00:53:27 +0100 | zetef | (~quassel@5.2.182.98) (Ping timeout: 246 seconds) |
2023-11-16 00:53:55 +0100 | falafel_ | (~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 +0100 | megaTherion | (~therion@unix.io) (Server closed connection) |
2023-11-16 00:54:07 +0100 | hueso | (~root@user/hueso) |
2023-11-16 00:54:13 +0100 | megaTherion | (~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 +0100 | CiaoSen | (~Jura@2a05:5800:289:5000:2a3a:4dff:fe84:dbd5) (Ping timeout: 245 seconds) |
2023-11-16 00:58:15 +0100 | Tuplanolla | (~Tuplanoll@91-159-68-236.elisa-laajakaista.fi) (Quit: Leaving.) |
2023-11-16 00:58:16 +0100 | falafel_ | (~falafel@62.175.113.194.dyn.user.ono.com) (Ping timeout: 256 seconds) |
2023-11-16 01:01:37 +0100 | jmdaemon | (~jmdaemon@user/jmdaemon) (Quit: ZNC 1.8.2 - https://znc.in) |
2023-11-16 01:02:04 +0100 | acidjnk | (~acidjnk@p200300d6e72b93446103f524bf4ee276.dip0.t-ipconnect.de) (Read error: Connection reset by peer) |
2023-11-16 01:04:27 +0100 | jmdaemon | (~jmdaemon@user/jmdaemon) |
2023-11-16 01:05:04 +0100 | machinedgod | (~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 +0100 | fun-safe-math | (~fun-safe-@c-24-21-106-247.hsd1.or.comcast.net) |
2023-11-16 01:07:35 +0100 | geekosaur | doesn'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 +0100 | alp_ | (~alp@static-176-175-7-165.ftth.abo.bbox.fr) |
2023-11-16 01:12:22 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580) |
2023-11-16 01:16:31 +0100 | vilya_ | vilya |
2023-11-16 01:16:47 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580) (Ping timeout: 268 seconds) |
2023-11-16 01:19:01 +0100 | dsrt^ | (~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 +0100 | sawilagar | (~sawilagar@user/sawilagar) (Ping timeout: 246 seconds) |
2023-11-16 01:31:14 +0100 | jinsun | (~jinsun@user/jinsun) |
2023-11-16 01:32:49 +0100 | fun-safe-math | (~fun-safe-@c-24-21-106-247.hsd1.or.comcast.net) () |
2023-11-16 01:34:30 +0100 | fun-safe-math | (~fun-safe-@c-24-21-106-247.hsd1.or.comcast.net) |
2023-11-16 01:44:17 +0100 | machinedgod | (~machinedg@d198-53-218-113.abhsia.telus.net) |
2023-11-16 01:45:46 +0100 | jmdaemon | (~jmdaemon@user/jmdaemon) (Ping timeout: 268 seconds) |
2023-11-16 01:51:11 +0100 | jmdaemon | (~jmdaemon@user/jmdaemon) |
2023-11-16 01:53:07 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580) |
2023-11-16 01:56:06 +0100 | alp_ | (~alp@static-176-175-7-165.ftth.abo.bbox.fr) (Ping timeout: 246 seconds) |
2023-11-16 02:09:06 +0100 | jmdaemon | (~jmdaemon@user/jmdaemon) (Ping timeout: 256 seconds) |
2023-11-16 02:09:49 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580) (Ping timeout: 268 seconds) |
2023-11-16 02:14:06 +0100 | Feuermagier | (~Feuermagi@user/feuermagier) (Ping timeout: 245 seconds) |
2023-11-16 02:17:30 +0100 | wroathe | (~wroathe@207-153-38-140.fttp.usinternet.com) |
2023-11-16 02:17:30 +0100 | wroathe | (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host) |
2023-11-16 02:17:30 +0100 | wroathe | (~wroathe@user/wroathe) |
2023-11-16 02:18:38 +0100 | emmanuelux_ | (~emmanuelu@user/emmanuelux) |
2023-11-16 02:18:55 +0100 | emmanuelux_ | (~emmanuelu@user/emmanuelux) (Remote host closed the connection) |
2023-11-16 02:19:28 +0100 | Feuermagier | (~Feuermagi@user/feuermagier) |
2023-11-16 02:19:54 +0100 | emmanuelux | (~emmanuelu@user/emmanuelux) (Ping timeout: 246 seconds) |
2023-11-16 02:29:59 +0100 | emmanuelux | (~emmanuelu@user/emmanuelux) |
2023-11-16 02:38:00 +0100 | arahael | (~arahael@119-18-2-212.771202.syd.nbn.aussiebb.net) (Ping timeout: 256 seconds) |
2023-11-16 02:43:28 +0100 | rosco | (~rosco@175.136.157.149) |
2023-11-16 02:58:16 +0100 | califax | (~califax@user/califx) (Ping timeout: 264 seconds) |
2023-11-16 02:59:13 +0100 | califax | (~califax@user/califx) |
2023-11-16 03:00:04 +0100 | ec | (~ec@gateway/tor-sasl/ec) (Ping timeout: 264 seconds) |
2023-11-16 03:00:18 +0100 | FinnElija | (~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection) |
2023-11-16 03:01:03 +0100 | FinnElija | (~finn_elij@user/finn-elija/x-0085643) |
2023-11-16 03:01:20 +0100 | jmdaemon | (~jmdaemon@user/jmdaemon) |
2023-11-16 03:02:02 +0100 | ec | (~ec@gateway/tor-sasl/ec) |
2023-11-16 03:11:37 +0100 | otto_s | (~user@p5b044a1d.dip0.t-ipconnect.de) (Ping timeout: 260 seconds) |
2023-11-16 03:13:09 +0100 | otto_s | (~user@p4ff275a7.dip0.t-ipconnect.de) |
2023-11-16 03:17:40 +0100 | xff0x | (~xff0x@2405:6580:b080:900:3141:d1c2:46a9:b11c) (Ping timeout: 256 seconds) |
2023-11-16 03:22:47 +0100 | Fangs | (sid141280@id-141280.hampstead.irccloud.com) (Server closed connection) |
2023-11-16 03:23:01 +0100 | Fangs | (sid141280@id-141280.hampstead.irccloud.com) |
2023-11-16 03:23:12 +0100 | ystael | (~ystael@user/ystael) (Ping timeout: 268 seconds) |
2023-11-16 03:24:28 +0100 | Square2 | (~Square4@user/square) (Ping timeout: 256 seconds) |
2023-11-16 03:31:39 +0100 | machinedgod | (~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 246 seconds) |
2023-11-16 03:41:03 +0100 | ystael | (~ystael@user/ystael) |
2023-11-16 03:48:00 +0100 | Boarders___ | (sid425905@id-425905.lymington.irccloud.com) (Server closed connection) |
2023-11-16 03:48:20 +0100 | Boarders___ | (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 +0100 | kiriakos_ | (~kiriakos@p57b65bf0.dip0.t-ipconnect.de) |
2023-11-16 03:54:59 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580) |
2023-11-16 03:55:38 +0100 | kiriakos | (~kiriakos@p57b647b8.dip0.t-ipconnect.de) (Ping timeout: 256 seconds) |
2023-11-16 03:55:38 +0100 | kiriakos_ | kiriakos |
2023-11-16 04:01:16 +0100 | thegman | (~thegman@072-239-207-086.res.spectrum.com) (Read error: Connection reset by peer) |
2023-11-16 04:02:28 +0100 | xff0x | (~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp) |
2023-11-16 04:03:05 +0100 | degraafk | (sid71464@id-71464.lymington.irccloud.com) (Server closed connection) |
2023-11-16 04:03:14 +0100 | degraafk | (sid71464@id-71464.lymington.irccloud.com) |
2023-11-16 04:04:08 +0100 | superbil | (~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 +0100 | bitdex | (~bitdex@gateway/tor-sasl/bitdex) |
2023-11-16 04:08:51 +0100 | pretty_dumm_guy | (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5) |
2023-11-16 04:15:16 +0100 | nate4 | (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
2023-11-16 04:16:55 +0100 | califax | (~califax@user/califx) (Remote host closed the connection) |
2023-11-16 04:16:55 +0100 | FinnElija | (~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection) |
2023-11-16 04:16:55 +0100 | ec | (~ec@gateway/tor-sasl/ec) (Read error: Connection reset by peer) |
2023-11-16 04:17:10 +0100 | califax | (~califax@user/califx) |
2023-11-16 04:17:15 +0100 | ec | (~ec@gateway/tor-sasl/ec) |
2023-11-16 04:17:27 +0100 | FinnElija | (~finn_elij@user/finn-elija/x-0085643) |
2023-11-16 04:21:42 +0100 | td_ | (~td@i53870930.versanet.de) (Ping timeout: 256 seconds) |
2023-11-16 04:23:21 +0100 | td_ | (~td@i53870904.versanet.de) |
2023-11-16 04:25:01 +0100 | finn_elija | (~finn_elij@user/finn-elija/x-0085643) |
2023-11-16 04:25:01 +0100 | FinnElija | (~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija))) |
2023-11-16 04:25:01 +0100 | finn_elija | FinnElija |
2023-11-16 04:34:52 +0100 | califax | (~califax@user/califx) (Ping timeout: 264 seconds) |
2023-11-16 04:36:04 +0100 | FinnElija | (~finn_elij@user/finn-elija/x-0085643) (Ping timeout: 264 seconds) |
2023-11-16 04:36:40 +0100 | chiselfuse | (~chiselfus@user/chiselfuse) (Ping timeout: 264 seconds) |
2023-11-16 04:36:40 +0100 | adanwan | (~adanwan@gateway/tor-sasl/adanwan) (Ping timeout: 264 seconds) |
2023-11-16 04:37:29 +0100 | alphastate | (~alphastat@176.254.244.83) (Ping timeout: 260 seconds) |
2023-11-16 04:48:27 +0100 | califax | (~califax@user/califx) |
2023-11-16 04:48:28 +0100 | chiselfuse | (~chiselfus@user/chiselfuse) |
2023-11-16 04:48:33 +0100 | adanwan | (~adanwan@gateway/tor-sasl/adanwan) |
2023-11-16 04:49:31 +0100 | chiselfuse | (~chiselfus@user/chiselfuse) (Remote host closed the connection) |
2023-11-16 04:51:49 +0100 | FinnElija | (~finn_elij@user/finn-elija/x-0085643) |
2023-11-16 04:53:32 +0100 | chiselfuse | (~chiselfus@user/chiselfuse) |
2023-11-16 04:54:39 +0100 | lexi-lambda | (sid92601@id-92601.hampstead.irccloud.com) (Server closed connection) |
2023-11-16 04:54:49 +0100 | lexi-lambda | (sid92601@id-92601.hampstead.irccloud.com) |
2023-11-16 04:58:34 +0100 | edr | (~edr@user/edr) (Quit: Leaving) |
2023-11-16 04:59:43 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:94fb:a56c:1b8b:c580) (Remote host closed the connection) |
2023-11-16 05:06:48 +0100 | ddellacosta | (~ddellacos@ool-44c738de.dyn.optonline.net) (Ping timeout: 268 seconds) |
2023-11-16 05:07:09 +0100 | pr0ton | (~pr0ton@176.254.244.83) |
2023-11-16 05:07:22 +0100 | ddellacosta | (~ddellacos@ool-44c738de.dyn.optonline.net) |
2023-11-16 05:09:41 +0100 | aforemny | (~aforemny@2001:9e8:6cf2:3800:48da:c417:67b:551b) (Ping timeout: 240 seconds) |
2023-11-16 05:10:26 +0100 | aforemny | (~aforemny@2001:9e8:6cd7:8c00:47af:9d09:fce9:5fc4) |
2023-11-16 05:13:01 +0100 | Yumemi | (~Yumemi@2001:bc8:47a0:1b14::1) (Server closed connection) |
2023-11-16 05:13:21 +0100 | Yumemi | (~Yumemi@chamoin.net) |
2023-11-16 05:17:29 +0100 | yvan-sraka | (sid419690@id-419690.lymington.irccloud.com) (Server closed connection) |
2023-11-16 05:17:40 +0100 | yvan-sraka | (sid419690@id-419690.lymington.irccloud.com) |
2023-11-16 05:18:56 +0100 | nate4 | (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 256 seconds) |
2023-11-16 05:20:59 +0100 | ddellacosta | (~ddellacos@ool-44c738de.dyn.optonline.net) (Ping timeout: 268 seconds) |
2023-11-16 05:22:36 +0100 | ddellacosta | (~ddellacos@ool-44c738de.dyn.optonline.net) |
2023-11-16 05:25:02 +0100 | rosco | (~rosco@175.136.157.149) (Quit: Lost terminal) |
2023-11-16 05:25:17 +0100 | rosco | (~rosco@175.136.157.149) |
2023-11-16 05:26:21 +0100 | Inst | (~Inst@120.244.192.250) |
2023-11-16 05:26:47 +0100 | nrr______ | (sid20938@id-20938.lymington.irccloud.com) (Server closed connection) |
2023-11-16 05:27:04 +0100 | nrr______ | (sid20938@id-20938.lymington.irccloud.com) |
2023-11-16 05:29:42 +0100 | wroathe | (~wroathe@user/wroathe) (Ping timeout: 256 seconds) |
2023-11-16 05:35:15 +0100 | trev | (~trev@user/trev) |
2023-11-16 05:38:51 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) |
2023-11-16 05:40:44 +0100 | lightandlight | (sid135476@id-135476.helmsley.irccloud.com) (Server closed connection) |
2023-11-16 05:40:53 +0100 | lightandlight | (sid135476@id-135476.helmsley.irccloud.com) |
2023-11-16 05:41:09 +0100 | Lycurgus | (~georg@user/Lycurgus) (Server closed connection) |
2023-11-16 05:41:25 +0100 | Lycurgus | (~georg@user/Lycurgus) |
2023-11-16 05:47:27 +0100 | ubert | (~Thunderbi@178.165.182.252.wireless.dyn.drei.com) (Ping timeout: 246 seconds) |
2023-11-16 05:50:09 +0100 | sham | (~sham@2605:a601:a98c:be00:fdc4:4550:60c7:3408) |
2023-11-16 05:52:00 +0100 | dmj` | (sid72307@id-72307.hampstead.irccloud.com) (Server closed connection) |
2023-11-16 05:52:25 +0100 | dmj` | (sid72307@id-72307.hampstead.irccloud.com) |
2023-11-16 05:53:07 +0100 | wroathe | (~wroathe@207-153-38-140.fttp.usinternet.com) |
2023-11-16 05:53:07 +0100 | wroathe | (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host) |
2023-11-16 05:53:07 +0100 | wroathe | (~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 +0100 | waleee | (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 268 seconds) |
2023-11-16 06:06:47 +0100 | superbil | (~superbil@1-34-176-171.hinet-ip.hinet.net) |
2023-11-16 06:08:02 +0100 | emmanuelux | (~emmanuelu@user/emmanuelux) (Quit: au revoir) |
2023-11-16 06:12:33 +0100 | sham | (~sham@2605:a601:a98c:be00:fdc4:4550:60c7:3408) (Quit: Ping timeout (120 seconds)) |
2023-11-16 06:17:52 +0100 | kiriakos | (~kiriakos@p57b65bf0.dip0.t-ipconnect.de) (Ping timeout: 256 seconds) |
2023-11-16 06:18:52 +0100 | czy | (~user@180.116.181.15) |
2023-11-16 06:18:52 +0100 | stiell | (~stiell@gateway/tor-sasl/stiell) |
2023-11-16 06:19:13 +0100 | kiriakos | (~kiriakos@p5b03ee49.dip0.t-ipconnect.de) |
2023-11-16 06:21:50 +0100 | Inst | (~Inst@120.244.192.250) (Ping timeout: 256 seconds) |
2023-11-16 06:25:23 +0100 | michalz | (~michalz@185.246.207.193) |
2023-11-16 06:30:38 +0100 | Inst | (~Inst@120.244.192.250) |
2023-11-16 06:33:08 +0100 | wroathe | (~wroathe@user/wroathe) (Ping timeout: 268 seconds) |
2023-11-16 06:33:46 +0100 | chomwitt | (~chomwitt@2a02:587:7a03:f500:1ac0:4dff:fedb:a3f1) |
2023-11-16 06:40:32 +0100 | Unicorn_Princess | (~Unicorn_P@user/Unicorn-Princess/x-3540542) (Quit: Leaving) |
2023-11-16 06:42:40 +0100 | czy | (~user@180.116.181.15) (Remote host closed the connection) |
2023-11-16 06:48:56 +0100 | mhatta | (~mhatta@www21123ui.sakura.ne.jp) (Server closed connection) |
2023-11-16 06:49:38 +0100 | mhatta | (~mhatta@www21123ui.sakura.ne.jp) |
2023-11-16 06:55:00 +0100 | euleritian | (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 246 seconds) |
2023-11-16 06:55:43 +0100 | euleritian | (~euleritia@dynamic-089-204-130-029.89.204.130.pool.telefonica.de) |
2023-11-16 07:04:51 +0100 | AlexZenon | (~alzenon@178.34.162.228) (Server closed connection) |
2023-11-16 07:05:09 +0100 | AlexZenon | (~alzenon@178.34.162.228) |
2023-11-16 07:07:40 +0100 | euleritian | (~euleritia@dynamic-089-204-130-029.89.204.130.pool.telefonica.de) (Ping timeout: 268 seconds) |
2023-11-16 07:09:27 +0100 | misterfish | (~misterfis@84-53-85-146.bbserv.nl) |
2023-11-16 07:11:35 +0100 | zetef | (~quassel@95.77.17.251) |
2023-11-16 07:13:16 +0100 | notzmv | (~zmv@user/notzmv) (Ping timeout: 245 seconds) |
2023-11-16 07:13:44 +0100 | AlexNoo | (~AlexNoo@178.34.162.228) (Server closed connection) |
2023-11-16 07:14:07 +0100 | AlexNoo | (~AlexNoo@178.34.162.228) |
2023-11-16 07:16:41 +0100 | acidjnk | (~acidjnk@p200300d6e72b9344700ee309897754f9.dip0.t-ipconnect.de) |
2023-11-16 07:17:37 +0100 | euleritian | (~euleritia@dynamic-002-247-248-051.2.247.pool.telefonica.de) |
2023-11-16 07:19:07 +0100 | euleritian | (~euleritia@dynamic-002-247-248-051.2.247.pool.telefonica.de) (Read error: Connection reset by peer) |
2023-11-16 07:19:24 +0100 | euleritian | (~euleritia@77.22.252.56) |
2023-11-16 07:22:58 +0100 | takuan | (~takuan@178-116-218-225.access.telenet.be) |
2023-11-16 07:27:34 +0100 | euleritian | (~euleritia@77.22.252.56) (Ping timeout: 256 seconds) |
2023-11-16 07:28:05 +0100 | euleritian | (~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 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
2023-11-16 07:44:00 +0100 | zetef | (~quassel@95.77.17.251) (Ping timeout: 246 seconds) |
2023-11-16 07:47:45 +0100 | misterfish | (~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 268 seconds) |
2023-11-16 07:54:53 +0100 | xxpor | (~xxpor@user/xxpor) |
2023-11-16 07:59:09 +0100 | zetef | (~quassel@95.77.17.251) |
2023-11-16 08:03:00 +0100 | nitrix | (~nitrix@user/nitrix) (Server closed connection) |
2023-11-16 08:03:19 +0100 | nitrix | (~nitrix@user/nitrix) |
2023-11-16 08:05:16 +0100 | gmg | (~user@user/gehmehgeh) |
2023-11-16 08:10:44 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
2023-11-16 08:12:20 +0100 | qqq | (~qqq@92.43.167.61) (Ping timeout: 256 seconds) |
2023-11-16 08:14:36 +0100 | sord937 | (~sord937@gateway/tor-sasl/sord937) |
2023-11-16 08:15:54 +0100 | xxpor | (~xxpor@user/xxpor) (Quit: WeeChat 4.1.1) |
2023-11-16 08:29:54 +0100 | zetef | (~quassel@95.77.17.251) (Ping timeout: 256 seconds) |
2023-11-16 08:36:33 +0100 | mc47 | (~mc47@xmonad/TheMC47) (Remote host closed the connection) |
2023-11-16 08:46:45 +0100 | sord937 | (~sord937@gateway/tor-sasl/sord937) (Remote host closed the connection) |
2023-11-16 08:47:00 +0100 | thegeekinside | (~thegeekin@189.180.53.210) (Ping timeout: 246 seconds) |
2023-11-16 08:47:09 +0100 | sord937 | (~sord937@gateway/tor-sasl/sord937) |
2023-11-16 08:47:19 +0100 | euleritian | (~euleritia@dynamic-002-247-248-051.2.247.pool.telefonica.de) (Read error: Connection reset by peer) |
2023-11-16 08:47:38 +0100 | euleritian | (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
2023-11-16 08:48:02 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
2023-11-16 08:49:02 +0100 | lortabac | (~lorenzo@2a01:e0a:541:b8f0:a708:6ef4:b35f:fb63) |
2023-11-16 08:50:06 +0100 | meejah | (~meejah@rutas.meejah.ca) (Server closed connection) |
2023-11-16 08:50:15 +0100 | meejah | (~meejah@rutas.meejah.ca) |
2023-11-16 09:00:05 +0100 | dsrt^ | (~cd@12.206.76.226) (Remote host closed the connection) |
2023-11-16 09:00:34 +0100 | mc47 | (~mc47@xmonad/TheMC47) |
2023-11-16 09:01:57 +0100 | danza | (~francesco@151.57.147.208) |
2023-11-16 09:06:08 +0100 | qqq | (~qqq@92.43.167.61) |
2023-11-16 09:06:52 +0100 | lhpitn | (~tn@193.96.224.66) |
2023-11-16 09:08:53 +0100 | jrm | (~jrm@user/jrm) (Ping timeout: 240 seconds) |
2023-11-16 09:11:53 +0100 | misterfish | (~misterfis@87.215.131.102) |
2023-11-16 09:14:12 +0100 | fendor | (~fendor@2a02:8388:1640:be00:2528:5dc7:a36e:9b87) |
2023-11-16 09:14:18 +0100 | Feuermagier | (~Feuermagi@user/feuermagier) (Ping timeout: 246 seconds) |
2023-11-16 09:14:36 +0100 | Feuermagier | (~Feuermagi@user/feuermagier) |
2023-11-16 09:15:37 +0100 | jrm | (~jrm@user/jrm) |
2023-11-16 09:16:14 +0100 | idgaen | (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) |
2023-11-16 09:18:00 +0100 | mikko | (~mikko@user/mikko) (Server closed connection) |
2023-11-16 09:18:22 +0100 | mikko | (~mikko@dsl-trebng22-58c1a8-185.dhcp.inet.fi) |
2023-11-16 09:18:22 +0100 | mikko | (~mikko@dsl-trebng22-58c1a8-185.dhcp.inet.fi) (Changing host) |
2023-11-16 09:18:22 +0100 | mikko | (~mikko@user/mikko) |
2023-11-16 09:22:06 +0100 | notzmv | (~zmv@user/notzmv) |
2023-11-16 09:28:53 +0100 | Inst | (~Inst@120.244.192.250) (Ping timeout: 268 seconds) |
2023-11-16 09:30:24 +0100 | aku | (~aku@65.108.245.241) (Server closed connection) |
2023-11-16 09:30:32 +0100 | aku | (~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 +0100 | minigrim0 | (~minigrim0@2a01:4f9:6b:3416:68ba:8dff:fe58:a5ea) (Server closed connection) |
2023-11-16 09:40:59 +0100 | minigrim0 | (~minigrim0@2a01:4f9:6b:3416:68ba:8dff:fe58:a5ea) |
2023-11-16 09:43:04 +0100 | Lord_of_Life | (~Lord@user/lord-of-life/x-2819915) (Ping timeout: 268 seconds) |
2023-11-16 09:44:40 +0100 | Lord_of_Life | (~Lord@user/lord-of-life/x-2819915) |
2023-11-16 09:44:56 +0100 | vpan | (~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 +0100 | machinedgod | (~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 +0100 | Inst | (~Inst@120.244.192.250) |
2023-11-16 09:49:34 +0100 | <ski> | <ski> in your case |
2023-11-16 09:50:17 +0100 | alp_ | (~alp@2001:861:5e02:eff0:1f45:1768:2920:edd0) |
2023-11-16 09:51:12 +0100 | Jackneill | (~Jackneill@20014C4E1E1AA2009B34AF74A9557C2A.dsl.pool.telekom.hu) |
2023-11-16 09:52:26 +0100 | danza | (~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 +0100 | danse-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 +0100 | coot | (~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 +0100 | DigitalKiwi | (~kiwi@2604:a880:400:d0::1ca0:e001) (Server closed connection) |
2023-11-16 10:07:33 +0100 | DigitalKiwi | (~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 +0100 | leeb | (~leeb@tk2-243-31079.vs.sakura.ne.jp) (Server closed connection) |
2023-11-16 10:08:33 +0100 | ski | started doing exercises like this, with holes, before holes were a technical feature in GHC |
2023-11-16 10:08:48 +0100 | leeb | (~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 +0100 | idgaen | thinks 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 +0100 | eggplantade | (~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 +0100 | ubert | (~Thunderbi@178.115.42.132.wireless.dyn.drei.com) |
2023-11-16 10:16:07 +0100 | ski | would also suggest not so reflexively reaching for `$' .. `_ $ MkState' is just the same as `_ MkState' |
2023-11-16 10:16:47 +0100 | ski | thinks `$' is quite seldom warranted to use at all |
2023-11-16 10:16:56 +0100 | tromp | (~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 +0100 | kuribas | (~user@ip-188-118-57-242.reverse.destiny.be) |
2023-11-16 10:33:21 +0100 | tolt | (~weechat-h@li219-154.members.linode.com) (Server closed connection) |
2023-11-16 10:33:48 +0100 | tolt | (~weechat-h@li219-154.members.linode.com) |
2023-11-16 10:36:00 +0100 | CiaoSen | (~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 +0100 | szkl | (uid110435@id-110435.uxbridge.irccloud.com) |
2023-11-16 10:43:44 +0100 | eggplantade | (~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 +0100 | FinnElija | (~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 +0100 | FinnElija | (~finn_elij@user/finn-elija/x-0085643) |
2023-11-16 10:53:48 +0100 | danse-nr3 | (~danse@151.57.147.208) (Read error: Connection reset by peer) |
2023-11-16 10:54:13 +0100 | danse-nr3 | (~danse@151.43.161.172) |
2023-11-16 10:55:18 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
2023-11-16 10:57:02 +0100 | tzh | (~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 +0100 | Pickchea | (~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 +0100 | quintasan | (~quassel@quintasan.pl) (Server closed connection) |
2023-11-16 10:58:44 +0100 | quintasan | (~quassel@quintasan.pl) |
2023-11-16 10:58:45 +0100 | rosco | (~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 +0100 | Sgeo | (~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 +0100 | FinnElija | (~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 +0100 | FinnElija | (~finn_elij@user/finn-elija/x-0085643) |
2023-11-16 11:07:30 +0100 | zaquest | (~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 +0100 | chele | (~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 +0100 | oo_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 +0100 | Flow | (~none@gentoo/developer/flow) (Server closed connection) |
2023-11-16 11:10:58 +0100 | Flow | (~none@gentoo/developer/flow) |
2023-11-16 11:11:52 +0100 | <bwe> | return x = MkState (\y -> _) |
2023-11-16 11:11:52 +0100 | rncwnd | (~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 +0100 | rncwnd | (~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 +0100 | hippoid | (~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 +0100 | hippoid | (~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 +0100 | xff0x | (~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp) (Ping timeout: 268 seconds) |
2023-11-16 11:13:09 +0100 | ski | grins |
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 +0100 | ski | waits |
2023-11-16 11:17:07 +0100 | econo_ | (uid147250@id-147250.tinside.irccloud.com) (Quit: Connection closed for inactivity) |
2023-11-16 11:17:08 +0100 | nate4 | (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
2023-11-16 11:18:22 +0100 | ft | (~ft@p508db3bc.dip0.t-ipconnect.de) (Quit: leaving) |
2023-11-16 11:19:43 +0100 | lieven | (~mal@ns2.wyrd.be) (Server closed connection) |
2023-11-16 11:19:56 +0100 | <bwe> | understood it |
2023-11-16 11:19:57 +0100 | pretty_dumm_guy | (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) |
2023-11-16 11:20:03 +0100 | lieven | (~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 +0100 | Ekho | (~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 +0100 | nate4 | (~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 +0100 | bwe | sighs |
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 +0100 | idgaen | agrees |
2023-11-16 11:24:28 +0100 | <ski> | bwe : right |
2023-11-16 11:24:36 +0100 | Ekho | (~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 +0100 | bramhaag7 | (~bramhaag@198.8.58.39) (Server closed connection) |
2023-11-16 11:38:21 +0100 | gtdg | (~gtdg@user/gtdg) |
2023-11-16 11:38:23 +0100 | bramhaag7 | (~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 +0100 | tnks | (sid412124@id-412124.helmsley.irccloud.com) (Server closed connection) |
2023-11-16 11:46:23 +0100 | tnks | (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 +0100 | Feuermagier | (~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 +0100 | glguy_ | (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 +0100 | glguy | (g@libera/staff/glguy) (Read error: Connection reset by peer) |
2023-11-16 12:00:45 +0100 | g | (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 +0100 | Pickchea | (~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 +0100 | g | (g@libera/staff/glguy) |
2023-11-16 12:06:07 +0100 | <bwe> | let's recap runState |
2023-11-16 12:06:07 +0100 | anderson- | (~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 +0100 | bwe | is 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 +0100 | xff0x | (~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 +0100 | puke | (~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 +0100 | eggplantade | (~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 +0100 | euleritian | (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 246 seconds) |
2023-11-16 12:16:12 +0100 | euleritian | (~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 +0100 | lortabac | (~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 +0100 | flocks_ | (~flocks@134.122.90.60) (Server closed connection) |
2023-11-16 12:33:57 +0100 | flocks | (~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 +0100 | Square2 | (~Square4@user/square) |
2023-11-16 12:37:25 +0100 | sawilagar | (~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 +0100 | cyphase | (~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 +0100 | puke | (~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 +0100 | thyriaen | (~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 +0100 | euleritian | (~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 +0100 | euleritian | (~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 +0100 | cyphase | (~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 +0100 | remexre | (~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 +0100 | remexre | (~remexre@user/remexre) |
2023-11-16 12:54:27 +0100 | lortabac | (~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 +0100 | kuribas | (~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 +0100 | ski | nods 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 +0100 | Goodbye_Vincent | (cyvahl@freakshells.net) (Server closed connection) |
2023-11-16 13:00:50 +0100 | Goodbye_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 +0100 | szkl | (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 +0100 | danse-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 +0100 | tcard | (~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 +0100 | zetef | (~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 +0100 | tcard | (~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 +0100 | anderson- | (~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 +0100 | danse-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 +0100 | CiaoSen | (~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 +0100 | kuribas | (~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 +0100 | ski | idly 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 +0100 | bwe | sighs |
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 +0100 | ski | kinda 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 +0100 | lisbeths | (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 +0100 | bwe | sighs 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 +0100 | kuribas | (~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 +0100 | szkl | (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 +0100 | Feuermagier | (~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 +0100 | akegalj | (~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 +0100 | Simikando | (~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 +0100 | kuribas | (~user@ip-188-118-57-242.reverse.destiny.be) |
2023-11-16 14:02:20 +0100 | idgaen | (~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 +0100 | ChaiTRex | (~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 +0100 | alp_ | (~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 +0100 | alp_ | (~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 +0100 | eggplantade | (~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 +0100 | falafel_ | (~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 +0100 | geekosaur | (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 +0100 | geekosaur | (sid609282@xmonad/geekosaur) |
2023-11-16 14:20:16 +0100 | L29Ah | (~L29Ah@wikipedia/L29Ah) (Ping timeout: 268 seconds) |
2023-11-16 14:22:19 +0100 | Inst | (~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 +0100 | bwe | throws 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 +0100 | waleee | (~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 +0100 | bitdex | (~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 +0100 | Feuermagier | Guest6499 |
2023-11-16 14:29:43 +0100 | Feuermagier | (~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 +0100 | Simikando | (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 256 seconds) |
2023-11-16 14:30:55 +0100 | gtdg | (~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 +0100 | Guest6499 | (~Feuermagi@user/feuermagier) (Ping timeout: 260 seconds) |
2023-11-16 14:33:40 +0100 | <ski> | looks okay |
2023-11-16 14:34:33 +0100 | falafel_ | (~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 +0100 | Inst | (~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 +0100 | Logio | (em@kapsi.fi) (Server closed connection) |
2023-11-16 14:38:09 +0100 | Logio | (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 +0100 | euleritian | (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 260 seconds) |
2023-11-16 14:38:38 +0100 | euleritian | (~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 +0100 | Simikando | (~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 +0100 | jmdaemon | (~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 +0100 | Rembane | (~Rembane@li346-36.members.linode.com) (Server closed connection) |
2023-11-16 14:49:13 +0100 | Rembane | (~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 +0100 | danse-nr3 | (~danse@151.43.161.172) (Read error: Connection reset by peer) |
2023-11-16 14:54:34 +0100 | danse-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 +0100 | Simikando | (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 256 seconds) |
2023-11-16 14:59:43 +0100 | targetdisk | (~daemonchi@45-33-4-162.ip.linodeusercontent.com) (Server closed connection) |
2023-11-16 14:59:51 +0100 | targetdisk | (~daemonchi@45-33-4-162.ip.linodeusercontent.com) |
2023-11-16 14:59:52 +0100 | Simikando | (~Simikando@adsl-dyn216.91-127-84.t-com.sk) |
2023-11-16 15:02:10 +0100 | zetef | (~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 +0100 | acidjnk | (~acidjnk@p200300d6e72b9344700ee309897754f9.dip0.t-ipconnect.de) (Ping timeout: 260 seconds) |
2023-11-16 15:05:23 +0100 | alp_ | (~alp@2001:861:5e02:eff0:6102:872f:f333:fe94) (Ping timeout: 256 seconds) |
2023-11-16 15:05:34 +0100 | Simikando | (~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 +0100 | alp_ | (~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 +0100 | waleee | (~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 +0100 | ChaiTRex | (~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 +0100 | nate4 | (~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 +0100 | nate4 | (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 260 seconds) |
2023-11-16 15:24:16 +0100 | thegeekinside | (~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 +0100 | Buggys | (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 +0100 | wroathe | (~wroathe@207-153-38-140.fttp.usinternet.com) |
2023-11-16 15:39:41 +0100 | wroathe | (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host) |
2023-11-16 15:39:41 +0100 | wroathe | (~wroathe@user/wroathe) |
2023-11-16 15:44:00 +0100 | Buggys | (Buggys@Buggy.shelltalk.net) |
2023-11-16 15:48:30 +0100 | danse-nr3 | (~danse@151.57.198.230) (Ping timeout: 256 seconds) |
2023-11-16 15:49:27 +0100 | danse-nr3 | (~danse@151.57.198.230) |
2023-11-16 15:55:30 +0100 | alp_ | (~alp@2001:861:5e02:eff0:ab2f:dcd1:5fa1:c307) (Quit: Leaving) |
2023-11-16 16:00:02 +0100 | szkl | (uid110435@id-110435.uxbridge.irccloud.com) (Quit: Connection closed for inactivity) |
2023-11-16 16:07:12 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Ping timeout: 256 seconds) |
2023-11-16 16:07:48 +0100 | L29Ah | (~L29Ah@wikipedia/L29Ah) |
2023-11-16 16:08:06 +0100 | wroathe | (~wroathe@user/wroathe) (Ping timeout: 260 seconds) |
2023-11-16 16:09:13 +0100 | welterde | (welterde@thinkbase.srv.welterde.de) (Server closed connection) |
2023-11-16 16:09:57 +0100 | welterde | (welterde@thinkbase.srv.welterde.de) |
2023-11-16 16:10:55 +0100 | fweht | (uid404746@id-404746.lymington.irccloud.com) |
2023-11-16 16:17:53 +0100 | xstill_ | (xstill@fimu/xstill) (Server closed connection) |
2023-11-16 16:17:54 +0100 | Inst | (~Inst@120.244.192.250) (Ping timeout: 260 seconds) |
2023-11-16 16:18:13 +0100 | xstill_ | (xstill@fimu/xstill) |
2023-11-16 16:19:54 +0100 | glguy_ | glguy |
2023-11-16 16:20:31 +0100 | vglfr | (~vglfr@78.26.242.160) |
2023-11-16 16:26:09 +0100 | Inst | (~Inst@120.244.192.250) |
2023-11-16 16:26:21 +0100 | vglfr | (~vglfr@78.26.242.160) (Quit: Quit) |
2023-11-16 16:26:44 +0100 | vglfr | (~vglfr@78.26.242.160) |
2023-11-16 16:30:06 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
2023-11-16 16:34:29 +0100 | erty | (~user@user/aeroplane) |
2023-11-16 16:37:20 +0100 | noctux | (~noctux@user/noctux) (Read error: Connection reset by peer) |
2023-11-16 16:39:42 +0100 | noctux | (~noctux@user/noctux) |
2023-11-16 16:40:41 +0100 | Simikando | (~Simikando@adsl-dyn216.91-127-84.t-com.sk) |
2023-11-16 16:45:21 +0100 | micro | (~micro@user/micro) (Server closed connection) |
2023-11-16 16:45:28 +0100 | micro | (~micro@user/micro) |
2023-11-16 16:45:47 +0100 | lhpitn_ | (~tn@193.96.224.66) |
2023-11-16 16:48:12 +0100 | vpan | (~vpan@mail.elitnet.lt) (Quit: Leaving.) |
2023-11-16 16:49:38 +0100 | lhpitn | (~tn@193.96.224.66) (Ping timeout: 260 seconds) |
2023-11-16 16:50:55 +0100 | idgaen | (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) |
2023-11-16 16:53:46 +0100 | ChaiTRex | (~ChaiTRex@user/chaitrex) (Quit: ChaiTRex) |
2023-11-16 16:53:51 +0100 | misterfish | (~misterfis@87.215.131.102) (Ping timeout: 246 seconds) |
2023-11-16 16:55:15 +0100 | Typedfern | (~Typedfern@220.red-83-37-25.dynamicip.rima-tde.net) (Server closed connection) |
2023-11-16 16:55:38 +0100 | Typedfern | (~Typedfern@220.red-83-37-25.dynamicip.rima-tde.net) |
2023-11-16 16:58:06 +0100 | mechap | (~mechap@user/mechap) |
2023-11-16 16:58:26 +0100 | lortabac | (~lorenzo@2a01:e0a:541:b8f0:710e:fea0:5caf:9833) (Quit: WeeChat 3.5) |
2023-11-16 16:58:27 +0100 | zetef | (~quassel@95.77.17.251) |
2023-11-16 17:00:48 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
2023-11-16 17:01:17 +0100 | bgamari_ | (~bgamari@64.223.173.10) (Server closed connection) |
2023-11-16 17:02:36 +0100 | bgamari | (~bgamari@64.223.173.10) |
2023-11-16 17:03:18 +0100 | mechap | (~mechap@user/mechap) (Ping timeout: 246 seconds) |
2023-11-16 17:03:38 +0100 | ChaiTRex | (~ChaiTRex@user/chaitrex) |
2023-11-16 17:03:43 +0100 | rubin55 | (sid175221@id-175221.hampstead.irccloud.com) (Server closed connection) |
2023-11-16 17:04:01 +0100 | rubin55 | (sid175221@id-175221.hampstead.irccloud.com) |
2023-11-16 17:05:24 +0100 | mechap | (~mechap@user/mechap) |
2023-11-16 17:10:29 +0100 | kimiamania46 | (~b4f4a2ab@user/kimiamania) (Ping timeout: 240 seconds) |
2023-11-16 17:12:18 +0100 | driib5 | (~driib@vmi931078.contaboserver.net) (Server closed connection) |
2023-11-16 17:12:52 +0100 | driib5 | (~driib@vmi931078.contaboserver.net) |
2023-11-16 17:14:34 +0100 | davetapley | (sid666@id-666.uxbridge.irccloud.com) (Server closed connection) |
2023-11-16 17:14:44 +0100 | davetapley | (sid666@id-666.uxbridge.irccloud.com) |
2023-11-16 17:15:44 +0100 | kimiamania46 | (~65804703@user/kimiamania) |
2023-11-16 17:15:54 +0100 | zetef | (~quassel@95.77.17.251) (Ping timeout: 246 seconds) |
2023-11-16 17:16:56 +0100 | zetef | (~quassel@95.77.17.251) |
2023-11-16 17:19:29 +0100 | kimiamania46 | (~65804703@user/kimiamania) (Client Quit) |
2023-11-16 17:20:29 +0100 | kimiamania46 | (~65804703@user/kimiamania) |
2023-11-16 17:24:06 +0100 | Franciman | (~Franciman@mx1.fracta.dev) (Server closed connection) |
2023-11-16 17:24:19 +0100 | Franciman | (~Franciman@mx1.fracta.dev) |
2023-11-16 17:25:00 +0100 | kimiamania46 | (~65804703@user/kimiamania) (Client Quit) |
2023-11-16 17:25:21 +0100 | lisbeths | (uid135845@id-135845.lymington.irccloud.com) (Quit: Connection closed for inactivity) |
2023-11-16 17:26:23 +0100 | todi | (~todi@p4fd1a3e6.dip0.t-ipconnect.de) (Ping timeout: 260 seconds) |
2023-11-16 17:26:39 +0100 | akegalj | (~akegalj@141-136-147-15.dsl.iskon.hr) (Quit: leaving) |
2023-11-16 17:26:42 +0100 | kimiamania46 | (~65804703@user/kimiamania) |
2023-11-16 17:30:05 +0100 | Simikando | (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Remote host closed the connection) |
2023-11-16 17:30:18 +0100 | pierrot | (~pi@user/pierrot) (Server closed connection) |
2023-11-16 17:30:25 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) |
2023-11-16 17:30:27 +0100 | Simikando | (~Simikando@adsl-dyn216.91-127-84.t-com.sk) |
2023-11-16 17:30:35 +0100 | pierrot | (~pi@user/pierrot) |
2023-11-16 17:30:44 +0100 | Unode | (~Unode@fg-ext-220.embl.de) (Server closed connection) |
2023-11-16 17:30:56 +0100 | Unode | (~Unode@fg-ext-220.embl.de) |
2023-11-16 17:38:23 +0100 | Simikando | (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 256 seconds) |
2023-11-16 17:39:29 +0100 | Simikando | (~Simikando@adsl-dyn216.91-127-84.t-com.sk) |
2023-11-16 17:40:08 +0100 | ddellacosta | (~ddellacos@ool-44c738de.dyn.optonline.net) (Ping timeout: 256 seconds) |
2023-11-16 17:49:30 +0100 | Sgeo | (~Sgeo@user/sgeo) |
2023-11-16 17:49:53 +0100 | __monty__ | (~toonn@user/toonn) (Quit: leaving) |
2023-11-16 17:51:59 +0100 | lhpitn | (~tn@ipv6-2d1e9090b42fa986.nowe.clients.hamburg.freifunk.net) |
2023-11-16 17:54:58 +0100 | lhpitn_ | (~tn@193.96.224.66) (Ping timeout: 260 seconds) |
2023-11-16 17:57:18 +0100 | acidjnk | (~acidjnk@p200300d6e72b9344349e196aee999b14.dip0.t-ipconnect.de) |
2023-11-16 18:00:06 +0100 | zetef | (~quassel@95.77.17.251) (Ping timeout: 260 seconds) |
2023-11-16 18:02:18 +0100 | ddellacosta | (~ddellacos@ool-44c738de.dyn.optonline.net) |
2023-11-16 18:02:51 +0100 | cawfee_ | (~root@2406:3003:2077:2758::babe) (Server closed connection) |
2023-11-16 18:03:11 +0100 | cawfee_ | (~root@2406:3003:2077:2758::babe) |
2023-11-16 18:04:18 +0100 | Simikando | (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 260 seconds) |
2023-11-16 18:05:20 +0100 | econo_ | (uid147250@id-147250.tinside.irccloud.com) |
2023-11-16 18:09:28 +0100 | AlexZenon | (~alzenon@178.34.162.228) (Ping timeout: 255 seconds) |
2023-11-16 18:09:39 +0100 | jbalint | (~jbalint@071-090-119-177.res.spectrum.com) (Server closed connection) |
2023-11-16 18:09:50 +0100 | jbalint | (~jbalint@2600:6c44:117f:e98a:816a:9488:fb1:7b7) |
2023-11-16 18:11:02 +0100 | mjrosenb_ | (~mjrosenb@pool-96-232-177-77.nycmny.fios.verizon.net) (Server closed connection) |
2023-11-16 18:11:11 +0100 | mjrosenb | (~mjrosenb@pool-96-232-177-77.nycmny.fios.verizon.net) |
2023-11-16 18:13:28 +0100 | dispater | (~dispater@mail.brprice.uk) (Server closed connection) |
2023-11-16 18:13:39 +0100 | machinedgod | (~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 246 seconds) |
2023-11-16 18:13:42 +0100 | glider | (~glider@user/glider) (Server closed connection) |
2023-11-16 18:13:48 +0100 | dispater | (~dispater@mail.brprice.uk) |
2023-11-16 18:13:50 +0100 | pavonia | (~user@user/siracusa) (Quit: Bye!) |
2023-11-16 18:15:14 +0100 | zetef | (~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 +0100 | tzh | (~tzh@c-71-193-181-0.hsd1.or.comcast.net) |
2023-11-16 18:16:18 +0100 | glider | (~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 +0100 | hippoid | (~hippoid@c-98-213-162-40.hsd1.il.comcast.net) (Ping timeout: 246 seconds) |
2023-11-16 18:17:12 +0100 | hippoid | (~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 +0100 | ski | figured |
2023-11-16 18:20:05 +0100 | AlexZenon | (~alzenon@178.34.162.228) |
2023-11-16 18:21:21 +0100 | tzh | (~tzh@c-71-193-181-0.hsd1.or.comcast.net) (Ping timeout: 246 seconds) |
2023-11-16 18:21:34 +0100 | lhpitn | (~tn@ipv6-2d1e9090b42fa986.nowe.clients.hamburg.freifunk.net) (Ping timeout: 260 seconds) |
2023-11-16 18:26:22 +0100 | tzh | (~tzh@c-71-193-181-0.hsd1.or.comcast.net) |
2023-11-16 18:27:08 +0100 | Simikando | (~Simikando@adsl-dyn216.91-127-84.t-com.sk) |
2023-11-16 18:29:53 +0100 | chele | (~chele@user/chele) (Quit: Leaving) |
2023-11-16 18:32:52 +0100 | euleritian | (~euleritia@dynamic-002-247-251-218.2.247.pool.telefonica.de) (Read error: Connection reset by peer) |
2023-11-16 18:33:09 +0100 | euleritian | (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
2023-11-16 18:33:24 +0100 | Simikando | (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 268 seconds) |
2023-11-16 18:39:03 +0100 | euleritian | (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer) |
2023-11-16 18:39:25 +0100 | euleritian | (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
2023-11-16 18:40:40 +0100 | cstml | (~cstml@user/cstml) (Quit: WeeChat 2.3) |
2023-11-16 18:43:17 +0100 | cstml | (~cstml@user/cstml) |
2023-11-16 18:44:08 +0100 | kuribas | (~user@ip-188-118-57-242.reverse.destiny.be) (Remote host closed the connection) |
2023-11-16 18:44:53 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Remote host closed the connection) |
2023-11-16 18:45:10 +0100 | sord937 | (~sord937@gateway/tor-sasl/sord937) (Remote host closed the connection) |
2023-11-16 18:46:50 +0100 | sord937 | (~sord937@gateway/tor-sasl/sord937) |
2023-11-16 18:47:39 +0100 | misterfish | (~misterfis@84-53-85-146.bbserv.nl) |
2023-11-16 18:47:42 +0100 | danse-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 +0100 | zetef | (~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 +0100 | fendor | (~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 +0100 | wroathe | (~wroathe@207-153-38-140.fttp.usinternet.com) |
2023-11-16 18:50:06 +0100 | wroathe | (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host) |
2023-11-16 18:50:06 +0100 | wroathe | (~wroathe@user/wroathe) |
2023-11-16 18:50:42 +0100 | fweht | (uid404746@id-404746.lymington.irccloud.com) (Quit: Connection closed for inactivity) |
2023-11-16 18:50:48 +0100 | Simikando | (~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 +0100 | misterfish | (~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 +0100 | misterfish | (~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 +0100 | natto | (~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 +0100 | analoq | (~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 +0100 | natto | (~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 +0100 | Square2 | (~Square4@user/square) (Ping timeout: 246 seconds) |
2023-11-16 19:11:34 +0100 | johnw | (~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 +0100 | smalltalkman | (uid545680@id-545680.hampstead.irccloud.com) (Server closed connection) |
2023-11-16 19:12:45 +0100 | smalltalkman | (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 +0100 | Simikando | (~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 +0100 | eggplantade | (~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 +0100 | Square | (~Square@user/square) |
2023-11-16 19:19:31 +0100 | Simikando | (~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 +0100 | nate4 | (~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 +0100 | Tuplanolla | (~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 +0100 | euleritian | (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 256 seconds) |
2023-11-16 19:24:35 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Remote host closed the connection) |
2023-11-16 19:24:44 +0100 | euleritian | (~euleritia@dynamic-002-247-251-218.2.247.pool.telefonica.de) |
2023-11-16 19:24:50 +0100 | eggplantade | (~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 +0100 | nate4 | (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 260 seconds) |
2023-11-16 19:25:30 +0100 | misterfish | (~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 +0100 | lg188 | (~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 +0100 | mjacob | (~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 +0100 | L29Ah | (~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 +0100 | jathan | (~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 +0100 | Unicorn_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 +0100 | mjacob | (~mjacob@adrastea.uberspace.de) |
2023-11-16 19:36:55 +0100 | lg188 | (~lg188@82.18.98.230) (Quit: Bye.) |
2023-11-16 19:37:24 +0100 | kawzeg_ | (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 +0100 | kawzeg_ | (kawzeg@2a01:7e01::f03c:92ff:fee2:ec34) |
2023-11-16 19:38:00 +0100 | stefan-_ | (~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 +0100 | stefan-_ | (~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 +0100 | adamCS | (~adamCS@ec2-34-207-160-255.compute-1.amazonaws.com) (Server closed connection) |
2023-11-16 19:40:09 +0100 | adamCS | (~adamCS@ec2-34-207-160-255.compute-1.amazonaws.com) |
2023-11-16 19:40:37 +0100 | cawfee_ | (~root@2406:3003:2077:2758::babe) (Ping timeout: 268 seconds) |
2023-11-16 19:43:19 +0100 | lg188 | (~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 +0100 | wroathe | (~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 +0100 | target_i | (~target_i@217.175.14.39) |
2023-11-16 19:44:18 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) (Remote host closed the connection) |
2023-11-16 19:44:53 +0100 | cawfee_ | (~root@2406:3003:2077:2758::babe) |
2023-11-16 19:46:57 +0100 | cstml | (~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 +0100 | thyriaen | (~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 +0100 | dcoutts | (~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 +0100 | hololeap | (~quassel@user/hololeap) (Server closed connection) |
2023-11-16 20:01:32 +0100 | hololeap | (~quassel@user/hololeap) |
2023-11-16 20:04:36 +0100 | zer0bitz_ | (~zer0bitz@user/zer0bitz) |
2023-11-16 20:05:04 +0100 | <EvanR> | how about haskell edition |
2023-11-16 20:08:19 +0100 | haskellbridge | (~haskellbr@069-135-003-034.biz.spectrum.com) (Remote host closed the connection) |
2023-11-16 20:08:50 +0100 | zer0bitz | (~zer0bitz@user/zer0bitz) (Ping timeout: 252 seconds) |
2023-11-16 20:10:00 +0100 | haskellbridge | (~haskellbr@069-135-003-034.biz.spectrum.com) |
2023-11-16 20:10:00 +0100 | ChanServ | +v haskellbridge |
2023-11-16 20:10:15 +0100 | Simikando | (~Simikando@adsl-dyn216.91-127-84.t-com.sk) (Ping timeout: 256 seconds) |
2023-11-16 20:11:38 +0100 | ChaiTRex | (~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 +0100 | ChaiTRex | (~ChaiTRex@user/chaitrex) |
2023-11-16 20:16:12 +0100 | Simikando | (~Simikando@adsl-dyn216.91-127-84.t-com.sk) |
2023-11-16 20:16:19 +0100 | misterfish | (~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 +0100 | ggVGc | (~ggVGc@a.lowtech.earth) (Ping timeout: 256 seconds) |
2023-11-16 20:17:28 +0100 | ggVGc | (~ggVGc@a.lowtech.earth) |
2023-11-16 20:19:15 +0100 | euleritian | (~euleritia@dynamic-002-247-251-218.2.247.pool.telefonica.de) (Read error: Connection reset by peer) |
2023-11-16 20:19:24 +0100 | eggplantade | (~Eggplanta@2600:1700:38c5:d800:2945:3959:f06e:7711) |
2023-11-16 20:19:37 +0100 | euleritian | (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
2023-11-16 20:20:30 +0100 | ft | (~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 +0100 | tomboy64 | (~tomboy64@user/tomboy64) (Ping timeout: 240 seconds) |
2023-11-16 20:23:54 +0100 | euleritian | (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 256 seconds) |
2023-11-16 20:24:50 +0100 | euleritian | (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
2023-11-16 20:28:23 +0100 | trev | (~trev@user/trev) (Quit: trev) |
2023-11-16 20:29:08 +0100 | tomboy64 | (~tomboy64@user/tomboy64) |
2023-11-16 20:30:08 +0100 | waleee | (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) |
2023-11-16 20:31:39 +0100 | Simikando | (~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 +0100 | dcoutts | (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) |
2023-11-16 20:38:49 +0100 | pierrot | (~pi@user/pierrot) (Read error: Connection reset by peer) |
2023-11-16 20:38:52 +0100 | Nixkernal | (~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 +0100 | Nixkernal | (~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 +0100 | pierrot | (~pi@user/pierrot) |
2023-11-16 20:44:03 +0100 | stilgart | (~Christoph@chezlefab.net) (Server closed connection) |
2023-11-16 20:44:11 +0100 | stilgart | (~Christoph@chezlefab.net) |
2023-11-16 20:45:22 +0100 | SanchayanMaity | (sid478177@id-478177.hampstead.irccloud.com) (Server closed connection) |
2023-11-16 20:45:32 +0100 | SanchayanMaity | (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 +0100 | thegman | (~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 +0100 | cheater_ | (~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 +0100 | mauke | annoyed 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 +0100 | cheater | (~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 +0100 | cheater_ | 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 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
2023-11-16 21:13:14 +0100 | sord937 | (~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 +0100 | Pickchea | (~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 +0100 | tromp | (~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 +0100 | cheater_ | (~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 +0100 | cheater | (~Username@user/cheater) (Ping timeout: 256 seconds) |
2023-11-16 21:37:31 +0100 | <ski> | sum [ ] = 0 |
2023-11-16 21:37:32 +0100 | cheater_ | 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 +0100 | matijja | (~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 +0100 | matijja | (~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 +0100 | pavonia | (~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 +0100 | mechap | (~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 +0100 | imdoor | (~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 +0100 | imdoor | (~imdoor@balticom-142-78-50.balticom.lv) (Client Quit) |
2023-11-16 22:00:19 +0100 | imdoor | (~imdoor@balticom-142-78-50.balticom.lv) |
2023-11-16 22:00:35 +0100 | ski | thought 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 +0100 | ski | was 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 +0100 | euleritian | (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 256 seconds) |
2023-11-16 22:14:13 +0100 | target_i | (~target_i@217.175.14.39) (Quit: leaving) |
2023-11-16 22:14:46 +0100 | euleritian | (~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 +0100 | califax | (~califax@user/califx) (Remote host closed the connection) |
2023-11-16 22:19:57 +0100 | califax | (~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 +0100 | tromp | (~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 +0100 | pounce | (~pounce@user/cute/pounce) (Server closed connection) |
2023-11-16 22:26:35 +0100 | pounce | (~pounce@user/cute/pounce) |
2023-11-16 22:27:36 +0100 | tromp | (~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 +0100 | cheater_ | (~Username@user/cheater) |
2023-11-16 22:29:30 +0100 | cheater | (~Username@user/cheater) (Ping timeout: 246 seconds) |
2023-11-16 22:29:39 +0100 | cheater_ | 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 +0100 | cheater_ | (~Username@user/cheater) |
2023-11-16 22:35:30 +0100 | mc47 | (~mc47@xmonad/TheMC47) (Remote host closed the connection) |
2023-11-16 22:35:53 +0100 | cheater | (~Username@user/cheater) (Ping timeout: 256 seconds) |
2023-11-16 22:36:01 +0100 | cheater_ | 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 +0100 | mastarija | (~mastarija@42-10.dsl.iskon.hr) |
2023-11-16 22:40:49 +0100 | fendor | (~fendor@2a02:8388:1640:be00:2528:5dc7:a36e:9b87) |
2023-11-16 22:49:27 +0100 | cheater_ | (~Username@user/cheater) |
2023-11-16 22:50:53 +0100 | takuan | (~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection) |
2023-11-16 22:51:14 +0100 | jmdaemon | (~jmdaemon@user/jmdaemon) |
2023-11-16 22:53:10 +0100 | oo_miguel | (~Thunderbi@78-11-179-96.static.ip.netia.com.pl) (Ping timeout: 260 seconds) |
2023-11-16 22:53:30 +0100 | cheater | (~Username@user/cheater) (Ping timeout: 256 seconds) |
2023-11-16 22:53:33 +0100 | cheater_ | cheater |
2023-11-16 22:54:04 +0100 | ubert | (~Thunderbi@178.115.42.132.wireless.dyn.drei.com) (Ping timeout: 256 seconds) |
2023-11-16 22:54:38 +0100 | elkcl | (~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 +0100 | CiaoSen | (~Jura@2a05:5800:2cb:ad00:2a3a:4dff:fe84:dbd5) |
2023-11-16 22:59:28 +0100 | fendor | (~fendor@2a02:8388:1640:be00:2528:5dc7:a36e:9b87) (Remote host closed the connection) |
2023-11-16 22:59:31 +0100 | idgaen | (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1) |
2023-11-16 23:00:23 +0100 | rekahsoft | (~rekahsoft@bas1-sudbury98-67-70-201-226.dsl.bell.ca) |
2023-11-16 23:00:35 +0100 | rekahsoft | (~rekahsoft@bas1-sudbury98-67-70-201-226.dsl.bell.ca) (Remote host closed the connection) |
2023-11-16 23:01:13 +0100 | rekahsoft | (~rekahsoft@67.70.201.226) |
2023-11-16 23:03:47 +0100 | elkcl | (~elkcl@broadband-95-84-226-240.ip.moscow.rt.ru) |
2023-11-16 23:06:14 +0100 | sawilagar | (~sawilagar@user/sawilagar) (Ping timeout: 260 seconds) |
2023-11-16 23:07:33 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
2023-11-16 23:07:40 +0100 | rekahsoft | (~rekahsoft@67.70.201.226) (Ping timeout: 256 seconds) |
2023-11-16 23:09:45 +0100 | EsoAlgo81 | (~EsoAlgo@129.146.136.145) (Server closed connection) |
2023-11-16 23:10:06 +0100 | EsoAlgo81 | (~EsoAlgo@129.146.136.145) |
2023-11-16 23:10:09 +0100 | mastarija | (~mastarija@42-10.dsl.iskon.hr) (Quit: Client closed) |
2023-11-16 23:14:43 +0100 | pretty_dumm_guy | (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5) |
2023-11-16 23:14:59 +0100 | notzmv | (~zmv@user/notzmv) (Ping timeout: 256 seconds) |
2023-11-16 23:15:02 +0100 | misterfish | (~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 256 seconds) |
2023-11-16 23:15:14 +0100 | pretty_dumm_guy | (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) |
2023-11-16 23:17:00 +0100 | cheater_ | (~Username@user/cheater) |
2023-11-16 23:17:26 +0100 | CiaoSen | (~Jura@2a05:5800:2cb:ad00:2a3a:4dff:fe84:dbd5) (Ping timeout: 260 seconds) |
2023-11-16 23:19:12 +0100 | CiaoSen | (~Jura@2a05:5800:2be:2c00:2a3a:4dff:fe84:dbd5) |
2023-11-16 23:20:42 +0100 | cheater | (~Username@user/cheater) (Ping timeout: 260 seconds) |
2023-11-16 23:20:47 +0100 | cheater_ | cheater |
2023-11-16 23:21:06 +0100 | mastarija | (~mastarija@42-10.dsl.iskon.hr) |
2023-11-16 23:21:42 +0100 | nate4 | (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
2023-11-16 23:21:47 +0100 | Pickchea | (~private@user/pickchea) (Quit: Leaving) |
2023-11-16 23:23:39 +0100 | pretty_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 +0100 | nate4 | (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 260 seconds) |
2023-11-16 23:26:51 +0100 | thegman | (~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 +0100 | cheater_ | (~Username@user/cheater) |
2023-11-16 23:34:20 +0100 | cheater | (~Username@user/cheater) (Ping timeout: 268 seconds) |
2023-11-16 23:34:28 +0100 | cheater_ | cheater |
2023-11-16 23:35:57 +0100 | CiaoSen | (~Jura@2a05:5800:2be:2c00:2a3a:4dff:fe84:dbd5) (Ping timeout: 256 seconds) |
2023-11-16 23:40:43 +0100 | thegeekinside | (~thegeekin@189.180.53.210) (Remote host closed the connection) |
2023-11-16 23:44:38 +0100 | Guest|94 | (~Guest|94@62.151.227.157) |
2023-11-16 23:45:52 +0100 | Guest|94 | (~Guest|94@62.151.227.157) (Client Quit) |
2023-11-16 23:47:10 +0100 | imdoor | (~imdoor@balticom-142-78-50.balticom.lv) (Quit: imdoor) |
2023-11-16 23:47:39 +0100 | imdoor | (~imdoor@balticom-142-78-50.balticom.lv) |
2023-11-16 23:47:45 +0100 | imdoor | (~imdoor@balticom-142-78-50.balticom.lv) (Remote host closed the connection) |
2023-11-16 23:48:05 +0100 | wroathe | (~wroathe@50.205.197.50) |
2023-11-16 23:48:06 +0100 | wroathe | (~wroathe@50.205.197.50) (Changing host) |
2023-11-16 23:48:06 +0100 | wroathe | (~wroathe@user/wroathe) |
2023-11-16 23:49:09 +0100 | wroathe | (~wroathe@user/wroathe) (Client Quit) |
2023-11-16 23:49:14 +0100 | caryhartline | (~caryhartl@168.182.58.169) (Quit: caryhartline) |
2023-11-16 23:50:27 +0100 | michalz | (~michalz@185.246.207.193) (Remote host closed the connection) |
2023-11-16 23:52:39 +0100 | L29Ah | (~L29Ah@wikipedia/L29Ah) |
2023-11-16 23:56:16 +0100 | gmg | (~user@user/gehmehgeh) (Quit: Leaving) |
2023-11-16 23:56:53 +0100 | Square2 | (~Square4@user/square) |
2023-11-16 23:57:45 +0100 | mastarija | (~mastarija@42-10.dsl.iskon.hr) (Quit: Client closed) |
2023-11-16 23:59:45 +0100 | Square | (~Square@user/square) (Ping timeout: 256 seconds) |