2023/12/04

2023-12-04 00:09:49 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-04 00:12:03 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-04 00:13:19 +0100acidjnk(~acidjnk@p200300d6e72b93610dd19c2ddb792c3e.dip0.t-ipconnect.de) (Ping timeout: 268 seconds)
2023-12-04 00:13:47 +0100jorik808(~jorik808@d51A48920.access.telenet.be) (Ping timeout: 264 seconds)
2023-12-04 00:14:06 +0100jorik808(~jorik808@d51A48920.access.telenet.be)
2023-12-04 00:15:55 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-04 00:16:09 +0100Alleria(~JohnGalt@user/alleria)
2023-12-04 00:16:27 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-04 00:17:21 +0100Alleria(~JohnGalt@user/alleria) (Client Quit)
2023-12-04 00:18:26 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection)
2023-12-04 00:18:27 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 256 seconds)
2023-12-04 00:19:06 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643)
2023-12-04 00:19:21 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com)
2023-12-04 00:19:21 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
2023-12-04 00:19:22 +0100wroathe(~wroathe@user/wroathe)
2023-12-04 00:20:33 +0100 <iqubic> What is a FixState in this context?
2023-12-04 00:26:46 +0100 <ski> see <https://gist.githubusercontent.com/JustinChristensen/2111f13e812112b5ac973e292606d17f/raw/03b2086e…> : `data FixState = Start | Backslash deriving (Show,Eq,Enum)'
2023-12-04 00:27:54 +0100idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1)
2023-12-04 00:31:30 +0100 <ski> something about keeping track of whether you're currently in an escape sequence or not
2023-12-04 00:32:36 +0100 <iqubic> Should I try learning what the heck continuations are and how shift, rest, and callCC work in Haskell, or is that not worth it?
2023-12-04 00:33:26 +0100 <ski> s/escape/backslash/
2023-12-04 00:33:50 +0100 <ski> iqubic : it's fun .. but also takes some time to get into
2023-12-04 00:34:15 +0100mechap(~mechap@user/mechap) (Quit: WeeChat 4.1.1)
2023-12-04 00:34:16 +0100 <iqubic> do you have any good guides I can look at?
2023-12-04 00:35:30 +0100 <ski> <https://hackage.haskell.org/package/managed-1.0.10/docs/Control-Monad-Managed.html> might show you one neat thing you can do with it
2023-12-04 00:37:06 +0100 <ski> guides .. hmm .. not really
2023-12-04 00:38:19 +0100 <ski> i mean, i could point you to two research papers by Andrzej Filinski and Olivier Danvy, about the Continuation-Style Passing transform, that helped me understand this, when i started reading about it .. but i'm not sure if you're wanting resources about it, at that level
2023-12-04 00:38:55 +0100iqubic(~avi@2601:602:9502:c70:717f:d982:562d:94a3) (Ping timeout: 260 seconds)
2023-12-04 00:40:45 +0100oo_miguel(~Thunderbi@78-11-179-96.static.ip.netia.com.pl) (Quit: oo_miguel)
2023-12-04 00:41:32 +0100iqubic(~avi@2607:fb91:1518:c0e2:d265:9ef3:5320:9df0)
2023-12-04 00:42:54 +0100 <ski> one way to explain continuations is "`goto' on steroids", or "`goto' with parameters". one can do really mind-warping things with continuations
2023-12-04 00:43:01 +0100 <[Leary]> iqubic: Perhaps start with this lexi-lambda talk, 'Delimited Continuations, Demystified': https://www.youtube.com/watch?v=DRFsodbxHQo
2023-12-04 00:43:30 +0100 <iqubic> ski: I'm using my phones as a wireless hotspot because my home wifi is down right now.
2023-12-04 00:43:37 +0100 <iqubic> I'm back now.
2023-12-04 00:44:15 +0100 <ski> one nice tutorial text is "Web Programming" by Eli Barzilay at <https://tmp.barzilay.org/cont.txt>, applying continuations to making web pages where you may fill in some forms (or just click on buttons), to load new pages with more forms, &c.
2023-12-04 00:45:18 +0100 <iqubic> I see.
2023-12-04 00:45:21 +0100 <iqubic> That's cool.
2023-12-04 00:46:24 +0100 <ski> continuations can be used as a low-level basis, explaining how you compile functions to something more primitive
2023-12-04 00:46:27 +0100mobivme(~mobivme@112.201.111.217) (Read error: Connection reset by peer)
2023-12-04 00:47:10 +0100 <ski> continuations can also be used as a programming idiom (continuation-passing style). the `Cont'/`ContT' (and `Codensity') monad capturess this
2023-12-04 00:48:41 +0100 <iqubic> What is codensity?
2023-12-04 00:48:42 +0100 <ski> just as a language may have primitive state side-effects (and exceptions, &c.), it may also have ditto for continuations. commonly called "first-class continuations". this amounts to, in the language, getting a hold of the implicit low-level continuations that the language is (or may be) compiled into. e.g. Scheme and SML/NJ. also some other systems (Ruby ?) has continuation support
2023-12-04 00:49:12 +0100 <ski> newtype Cont o a = MkCont ((a -> o) -> o)
2023-12-04 00:49:20 +0100 <ski> newtype ContT o m a = MkContT ((a -> m o) -> m o)
2023-12-04 00:49:28 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-04 00:49:37 +0100 <iqubic> I know what those are.
2023-12-04 00:49:38 +0100 <ski> newtype Codensity m a = MkCodensity (forall o. (a -> m o) -> m o)
2023-12-04 00:50:01 +0100 <ski> it hides the "answer"/"result" type, making it polymorphic
2023-12-04 00:50:12 +0100 <iqubic> Why would you want that?
2023-12-04 00:50:30 +0100 <ski> that means that you can't "play tricks" with it (stuff that makes continuation "fun"/"hard")
2023-12-04 00:50:47 +0100 <iqubic> I see. Makes sense.
2023-12-04 00:50:49 +0100 <ski> (well, you can still play tricks with the `m' part of the result type, just not the `o' part)
2023-12-04 00:52:00 +0100 <ski> by Yoneda's lemma, any type `a' is equivalent to `forall o. (a -> o) -> o' (and more generally, for any functor `f', `f a' is equivalent to `forall o. (a -> o) -> f o' .. which is called `Yoneda f a')
2023-12-04 00:52:14 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-04 00:52:37 +0100 <ski> since, the only thing you can do with a value of type `forall o. (a -> o) -> o' is specialize `o' to `a', and pass in `id' of type `a -> a', getting an `a' out
2023-12-04 00:53:03 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-04 00:53:14 +0100 <ski> and, in the other direction, given an `x' of type `a', only way you can get an `forall o. (a -> o) -> o' is `\k -> k x'
2023-12-04 00:53:17 +0100 <iqubic> I don't know much about Yoneda's Lemma. Is it useful to know of that isomorpism?
2023-12-04 00:53:32 +0100 <ski> it's sometimes useful to know about, when refactoring types, yes
2023-12-04 00:53:43 +0100 <ski> (this is related to "Church" representation of data types)
2023-12-04 00:54:13 +0100 <ski> (it's e.g. used for one encoding of existentials)
2023-12-04 00:54:22 +0100 <duncan> oh god.. Church-encoding.. my rival
2023-12-04 00:54:35 +0100 <iqubic> does Coyoneda exist?
2023-12-04 00:55:22 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-04 00:55:25 +0100 <ski> (or i should probably say "Boehm-Berarducci Encoding". see Oleg at <https://okmij.org/ftp/tagless-final/course/Boehm-Berarducci.html>)
2023-12-04 00:55:28 +0100 <ski> yes
2023-12-04 00:55:51 +0100 <iqubic> Coyoneda :: (b -> a) -> f b -> Coyoneda f a
2023-12-04 00:56:17 +0100 <iqubic> Where does the a go and where does the b come from? The hell?!?!
2023-12-04 00:57:09 +0100 <iqubic> This is the definition that Edward Kmett gives in his Kan-Extensions package.
2023-12-04 00:57:15 +0100 <ski> `a' is also equivalent to `exists s. (s,s -> a)' (and more generally, `f a' to `exists s. (f s,s -> a)', for `f' a `Functor')
2023-12-04 00:57:42 +0100 <ski> and that `exists s. (f s,s -> a)' is called `Coyoneda f a'
2023-12-04 00:57:56 +0100 <ski> (so-called (my words) "State encoding"9
2023-12-04 00:57:57 +0100 <ski> )
2023-12-04 00:58:11 +0100 <iqubic> That seems very simple.
2023-12-04 00:58:49 +0100 <ski> @quote GuySteele
2023-12-04 00:58:49 +0100 <lambdabot> GuySteele says: Some people prefer not to commingle the functional, lambda-calculus part of a language with the parts that do side effects. It seems they believe in the separation of Church and
2023-12-04 00:58:49 +0100 <lambdabot> state.
2023-12-04 00:58:54 +0100 <ski> @quote Haskell.separates
2023-12-04 00:58:54 +0100 <lambdabot> shapr says: Haskell separates Church and state
2023-12-04 00:58:58 +0100 <ski> @quote are.dual
2023-12-04 00:58:58 +0100 <lambdabot> ski says: I'd rather say that in Haskell, Church and State are dual
2023-12-04 00:59:22 +0100 <iqubic> That's such a good joke...
2023-12-04 00:59:32 +0100 <iqubic> @quote zzz
2023-12-04 00:59:32 +0100 <lambdabot> erg0t says: <erg0t> sebazzz, me plagias mi vida
2023-12-04 00:59:52 +0100 <iqubic> @quote getSum sleep
2023-12-04 00:59:52 +0100 <lambdabot> No quotes for this person. Just what do you think you're doing Dave?
2023-12-04 01:00:15 +0100 <iqubic> I love the Church and state joke.
2023-12-04 01:00:25 +0100 <ski> (note that the `s' in `exists s. ..s..' there can commonly be thought of as a "state type". e.g. as in OOP. existentials is one way to encode closures, and OOP objects. one can also do ADTs (abstract data types) with existentials, but that's a quite distinct use of them)
2023-12-04 01:00:30 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-04 01:01:09 +0100 <iqubic> Do we even actually care about Yoneda and Coyoneda?
2023-12-04 01:01:23 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-04 01:01:25 +0100 <EvanR> we like to combine the church and the curry
2023-12-04 01:01:55 +0100 <ski> practically, they can be used to delay `fmap'ping over a structure, collecgting the functions to map over, so that when you finally extract, you do all the `fmap's in one pass, instead of multiple traversals
2023-12-04 01:02:08 +0100 <ski> iqubic ^
2023-12-04 01:02:40 +0100 <iqubic> Right. That's cool.
2023-12-04 01:03:02 +0100 <iqubic> fmap f . fmap g = fmap (f . g)
2023-12-04 01:03:09 +0100 <ski> right
2023-12-04 01:03:19 +0100 <iqubic> that's just a functor law.
2023-12-04 01:03:29 +0100 <ski> and `Codensity' does something similar, for left-associated uses of `(>>=)'
2023-12-04 01:03:54 +0100 <ski> this is similar to "difference lists", btw
2023-12-04 01:04:17 +0100 <ski> (or keeping an extra accumulator parameter, to avoid having to add stuff to the end of a list, repeatedly)
2023-12-04 01:04:28 +0100 <iqubic> runCodensity :: forall b. (a -> m b) -> m b
2023-12-04 01:05:01 +0100 <iqubic> That's the sole constructor for a Codensity m a
2023-12-04 01:05:21 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5)
2023-12-04 01:05:28 +0100 <ski> iqubic : consider a recursive definition like `data List a = Nil | Cons a (List a)'. we could "algebraically" write this as `List a = 1 + a * List a'
2023-12-04 01:06:02 +0100 <iqubic> I agree. That's why we call it an ADT.
2023-12-04 01:06:10 +0100 <ski> yea, basically
2023-12-04 01:06:22 +0100 <geekosaur> @quote getSum.*sleep
2023-12-04 01:06:22 +0100 <lambdabot> jle` says: let sleep = pure "zzz" in getSum sleep
2023-12-04 01:06:28 +0100 <iqubic> The A stands for Algebraic.
2023-12-04 01:07:12 +0100 <ski> now lets say we only really consider the *finite* length lists here. looking at `List a = 1 + a * List a', this is an equation in `List a', that has multiple solutions, though. one is the finite-length lists (this is the least solution). another is the possibly-finite streams (including infinite ones) (this is the greatest solution)
2023-12-04 01:07:38 +0100 <iqubic> Yeah, that makes sense.
2023-12-04 01:08:08 +0100 <ski> in order to be clear about which one we want, and to avoid having to write a recursive equation, we have notation where the least solution is written `mu r. 1 + a * r', and the greatest solution is written `nu r. 1 + a * r'
2023-12-04 01:08:41 +0100 <ski> so, for the least, we get `List a = mu r. 1 + a * r', and for the greatest, we get `List a = nu r. 1 + a * r'
2023-12-04 01:08:45 +0100 <EvanR> runCodensity :: Codensity m a -> (forall b. (a -> m b) -> m b)
2023-12-04 01:08:48 +0100 <iqubic> Oh, that's a clever way to disambiguate the solutions.
2023-12-04 01:09:00 +0100 <ski> think of `mu r. ..r..' and `nu r. ..r..' as being similar to `fix (\r -> ..r..)
2023-12-04 01:09:16 +0100 <iqubic> I already kinda assumed that.
2023-12-04 01:09:34 +0100 <ski> in (although, denotationally speaking, in Haskell, `fix' computes the least fixed point)
2023-12-04 01:10:21 +0100 <ski> iqubic : anyway, there are now useful ways in which we can refactor recursive types, expressed as `mu' (least) or `nu' (greatest) fixed points
2023-12-04 01:10:35 +0100 <iqubic> There are?
2023-12-04 01:10:47 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-04 01:10:59 +0100 <ski> specifically, `mu r. ..r..' is equivalent to `forall r. (..r.. -> r) -> r', and `nu s. ..s..' is equivalent to `exists s. (s,s -> ..s..)'
2023-12-04 01:11:32 +0100 <ski> let's take `mu r. 1 + a * r', aka `List a', from above. this would then be equivalent to `forall r. (1 + a * r -> r) -> r'
2023-12-04 01:11:34 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-04 01:12:11 +0100 <iqubic> Hmm... That makes sense.
2023-12-04 01:12:17 +0100 <ski> but `X + Y -> Z' is equivalent to `(X -> Z) * (Y -> Z)' (`o^(m+n) = o^m * o^n')
2023-12-04 01:12:35 +0100 <ski> so, that gets us to `forall r. (1 -> r) * (a * r -> r) -> r'
2023-12-04 01:12:57 +0100lg1889(~lg188@82.18.98.230)
2023-12-04 01:13:02 +0100lg188(~lg188@82.18.98.230) (Read error: Connection reset by peer)
2023-12-04 01:13:03 +0100lg1889lg188
2023-12-04 01:13:04 +0100 <iqubic> I see how that works.
2023-12-04 01:13:23 +0100 <ski> now we can use currying. `1 -> Z' is equivalent to `Z' (`o^1 = o'), and `X * Y -> Z' is equivalent to `X -> Y -> Z' (`o^(m*n) = (o^n)^m')
2023-12-04 01:13:50 +0100 <iqubic> I follow you there.
2023-12-04 01:13:56 +0100 <ski> that gets us to `forall r. r * (a -> r -> r) -> r'. and if we uncurry the outer function type, we get `forall r. r -> (a -> r -> r) -> r'
2023-12-04 01:14:00 +0100 <ski> now, look at
2023-12-04 01:14:20 +0100 <ski> foldr :: (a -> r -> r) -> r -> [a] -> r
2023-12-04 01:14:43 +0100 <iqubic> Those two are very similar.
2023-12-04 01:14:46 +0100 <ski> flip foldr :: r -> (a -> r -> r) -> [a] -> r
2023-12-04 01:15:19 +0100 <ski> flip . flip foldr :: r -> [a] -> (a -> r -> r) -> r
2023-12-04 01:15:32 +0100 <ski> flip (flip . flip foldr) :: [a] -> r -> (a -> r -> r) -> r
2023-12-04 01:15:35 +0100 <ski> which is really
2023-12-04 01:15:42 +0100 <ski> flip (flip . flip foldr) :: forall a. forall r. [a] -> r -> (a -> r -> r) -> r
2023-12-04 01:15:46 +0100 <ski> which can be rewritten as
2023-12-04 01:15:56 +0100 <ski> flip (flip . flip foldr) :: forall a. [a] -> (forall r. r -> (a -> r -> r) -> r)
2023-12-04 01:16:11 +0100 <iqubic> Oh... That's really cool.
2023-12-04 01:16:31 +0100 <ski> (since `... -> forall a. ..a..' is equivalent to `forall a. (... -> ..a..)' .. and `(exists a. ..a..) -> ...' is equivalent to `forall a. (..a.. -> ...)')
2023-12-04 01:16:35 +0100 <iqubic> I'm shocked that the algebra woks like that.
2023-12-04 01:17:07 +0100 <ski> so, `foldr' basically converts from `List a' to the form `forall r. r -> (a -> r -> r) -> r)'
2023-12-04 01:17:08 +0100picnoir(~picnoir@about/aquilenet/vodoo/NinjaTrappeur) (Ping timeout: 268 seconds)
2023-12-04 01:17:28 +0100 <ski> @type GHC.Base.build
2023-12-04 01:17:28 +0100 <lambdabot> (forall b. (a -> b -> b) -> b -> b) -> [a]
2023-12-04 01:17:37 +0100 <ski> is a function that does the opposite
2023-12-04 01:17:40 +0100 <ski> defined as
2023-12-04 01:17:47 +0100 <ski> build f = f (:) []
2023-12-04 01:18:15 +0100 <iqubic> Oh, that's really cool
2023-12-04 01:19:25 +0100 <ski> and there's specialization rules in GHC, amounting to `build' being inverse of `foldr' (and vice versa). namely `foldr cons nil (build f) = f cons nil' -- this is used for a type of "list fusion optimization" where we skip constructing intermediate lists, if we're going to `foldr' on them. we pass the `cons' (callback) and `nil' (starting point) directly to the "builder" `f' function
2023-12-04 01:19:37 +0100 <iqubic> foldr and build are just converting between the two types. I think [a] and forall r. r -> (a -> r -> r) -> r) are isomorphic
2023-12-04 01:19:43 +0100 <ski> yes
2023-12-04 01:19:47 +0100johnw(~johnw@69.62.242.138) (Quit: ZNC - http://znc.in)
2023-12-04 01:20:19 +0100clwif^(~cd@c-98-242-74-66.hsd1.ga.comcast.net)
2023-12-04 01:20:59 +0100 <ski> so, many of the list-producing functions are "good producers" meaning they produce their output lists by calling `build', and many of the list-consuming functions are "good consumers" meaning they consume their input lists by calling `foldr' on them
2023-12-04 01:21:19 +0100 <ski> (of course, many functions are both producers and consumers of lists, and so would use both `build' and `foldr')
2023-12-04 01:21:19 +0100 <iqubic> That's really cool to know. And I know that there are many functions like this.
2023-12-04 01:21:26 +0100 <iqubic> @type maybe
2023-12-04 01:21:27 +0100 <lambdabot> b -> (a -> b) -> Maybe a -> b
2023-12-04 01:21:40 +0100 <ski> @type either
2023-12-04 01:21:41 +0100 <lambdabot> (a -> c) -> (b -> c) -> Either a b -> c
2023-12-04 01:21:52 +0100 <iqubic> Yeah. Those work in the same way.
2023-12-04 01:22:19 +0100 <iqubic> Those are the cosumers for Maybe a and Either a b
2023-12-04 01:22:29 +0100travgm(~travgm@2600:100e:a121:d6af:56b:4880:133:700e)
2023-12-04 01:22:54 +0100 <ski> they are the folds/catamorphisms, for `Maybe' and `Either', just as `foldr' is the one for `[]', yes
2023-12-04 01:23:26 +0100 <iqubic> Right. Catamorpism was the word I was thinking of.
2023-12-04 01:23:46 +0100wroathe(~wroathe@user/wroathe) (Quit: leaving)
2023-12-04 01:23:56 +0100 <ski> (they also happen to be the "case" functions for `Maybe' and `Either'. `foldr' is not the "case" function for `[]', because `[]' is recursive. its case would have type `(a -> [a] -> r) -> r -> [a] -> r', with `[a]' rather than `r' as argument type in the callback)
2023-12-04 01:24:13 +0100 <iqubic> @type unfoldr
2023-12-04 01:24:14 +0100 <ski> catamorphisms "tear down structure". anamorphisms "build up structure"
2023-12-04 01:24:14 +0100 <lambdabot> (b -> Maybe (a, b)) -> b -> [a]
2023-12-04 01:24:39 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe) (Remote host closed the connection)
2023-12-04 01:24:43 +0100 <ski> yes, if we think of `[a]' as the greatest fixed point, then that `unfoldr' is its unfold/anamorphism
2023-12-04 01:24:45 +0100 <iqubic> I assume that unfoldr uses build somehow?
2023-12-04 01:25:21 +0100mobivme(~mobivme@112.201.111.217)
2023-12-04 01:25:23 +0100 <ski> note that `(s -> Maybe (a,s)) -> s -> [a]' may be more suggestive, thinking of `s' as a "state" or "seed" (think like random-generator seed, e.g.) type
2023-12-04 01:25:30 +0100 <ski> hm, dunno
2023-12-04 01:25:46 +0100misterfish(~misterfis@87.215.131.102) (Ping timeout: 245 seconds)
2023-12-04 01:26:07 +0100 <ski> anyway, say you take now `data Stream a = Cons {head :: a,tail :: Stream a}', abstractly `Steram a = a * Stream a'. here we definitely want the greatest fixed point interpretation (since there are no finite streams here, and so there would be zero finite values)
2023-12-04 01:26:21 +0100 <ski> so, `Stream a = nu s. a * s'
2023-12-04 01:26:36 +0100travgm(~travgm@2600:100e:a121:d6af:56b:4880:133:700e) (Ping timeout: 245 seconds)
2023-12-04 01:26:36 +0100chomwitt(~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1) (Ping timeout: 245 seconds)
2023-12-04 01:27:06 +0100 <iqubic> This uses nu instead of mu, because there are no least fixed points.
2023-12-04 01:27:16 +0100 <ski> if we expand this, using the equivalence above, we get `exists s. s * (s -> a * s)' .. the first `s' part is the "object instance state". the second part is a "method" taking the instance state, and produces an output of type `a', and a new instance state
2023-12-04 01:27:43 +0100 <ski> well, the least fixed point exists, but is empty, not interesting
2023-12-04 01:27:49 +0100 <ski> (is basically `Void')
2023-12-04 01:28:11 +0100 <iqubic> Yes, that's kinda what I meant, but you phrased it much better.
2023-12-04 01:29:11 +0100 <iqubic> How does using `exsist s. s * (s -> a * s)` change things? We have `exists' now, instead of `forall'
2023-12-04 01:30:08 +0100 <ski> now, imagine we want to represent a type of queues, of elements of type `a'. a `Queue a' has some private internal state (of unknown/forgotten/hidden/abstract/opaque/skolem type) `s', and some methods. namely one for enequeueing an `a' onto the queue, and one for dequeueing an `a' from the queue (if it's non-empty, otherwise we get a failure indication)
2023-12-04 01:31:04 +0100 <ski> this suggests `Queue a' should be `exists q. q * (a * q -> q) * (q -> Maybe (q * a))' (enqueue to the left, dequeue from the right)
2023-12-04 01:31:44 +0100 <iqubic> Sure. That's a reasonable guess to make.
2023-12-04 01:31:48 +0100 <ski> iqubic : yes. a value of type `forall a. ..a..' is a polymorphic value, works for *all* possible specific choices of type to use for `a', that the user/caller may pick
2023-12-04 01:32:12 +0100 <iqubic> I know that.
2023-12-04 01:32:24 +0100 <ski> while the producer/implementor must make sure that the code works for all possible `a', doesn't attempt to look into values of type `a', doesn't assume anything about the type
2023-12-04 01:32:25 +0100 <iqubic> But thanks for clarifying
2023-12-04 01:33:01 +0100 <iqubic> So, we're trying to model these queues.
2023-12-04 01:33:31 +0100 <ski> while, for a value of type `exists a. ..a..', this is an "abstract" value, we know there is *some* type `a', but we don't know which. the user/caller/consumer now must be prepared to handle all possible types, for `a', can't make assumptions about `a', does *not* get to pick `a'. instead, the producer/implementor/callee gets to pick `a'
2023-12-04 01:34:19 +0100 <ski> so, in `[exists a. ..a..]', the different elements in the list may have picked different `a's, so you can't assume them to be compatible. only within a single `exists a. ..a..' can you asssume the `a's are the same
2023-12-04 01:34:47 +0100 <ski> and, in `String -> Int -> IO (exists a. ..a..)', the choice of which `a' to use may depend on the arguments, and also in this case on the I/O interaction
2023-12-04 01:34:51 +0100 <iqubic> Oh! That's a really good way to explain the difference.
2023-12-04 01:35:30 +0100 <ski> basically, `exists' and `forall' are "opposite", wrt requirements and capabilities, as it pertains to user/caller/consumer vs. implementor/callee/producer
2023-12-04 01:35:40 +0100picnoir(~picnoir@about/aquilenet/vodoo/NinjaTrappeur)
2023-12-04 01:35:55 +0100 <iqubic> I get that now.
2023-12-04 01:36:07 +0100 <ski> for `exists', callee picks, and caller must handle any choice. for `forall', callee must handle any choice, and caller picks
2023-12-04 01:36:15 +0100 <ski> ok
2023-12-04 01:36:23 +0100 <ski> so, let's imagine
2023-12-04 01:36:37 +0100 <ski> data Queue a = MkQueue (exists q. q * (a * q -> q) * (q -> Maybe (q * a)))
2023-12-04 01:36:42 +0100 <ski> this means that
2023-12-04 01:36:54 +0100 <ski> MkQueue :: (exists q. q * (a * q -> q) * (q -> Maybe (q * a))) -> Queue a
2023-12-04 01:37:23 +0100 <ski> but, according to the equivalence between `(exists a. ..a..) -> ...' and `forall a. (..a.. -> ...)', this ought to be the same as
2023-12-04 01:37:26 +0100 <iqubic> Sure. I'd buy that.
2023-12-04 01:37:42 +0100 <ski> MkQueue :: forall q. q * (a * q -> q) * (q -> Maybe (q * a)) -> Queue a
2023-12-04 01:37:48 +0100 <ski> which we now can uncurry as
2023-12-04 01:38:01 +0100 <ski> MkQueue :: forall q. q -> (a -> q -> q) -> (q -> Maybe (q * a)) -> Queue a
2023-12-04 01:38:10 +0100[itchyjunk][itchTheIndiffer
2023-12-04 01:38:56 +0100 <ski> which we now can express in actuall Haskell (using the `ExistentialQuantification' extension (imho a misnomer, something like `ExistentialConstructors' would be a better name. i'd prefer to have `ExistentialQuantification' available for a real `exists' keyword))
2023-12-04 01:39:21 +0100 <ski> data Queue a = forall q. MkQueue q (a -> q -> q) (q -> Maybe (q,a))
2023-12-04 01:39:29 +0100 <ski> or, with record syntax, for field names
2023-12-04 01:39:49 +0100 <ski> data Queue a = forall q. MkQueue {queueState :: q,enqueue :: a -> q -> q,dequeu :: q -> Maybe (q,a)}
2023-12-04 01:40:00 +0100 <ski> we could alternatively use `GADTs' syntax
2023-12-04 01:40:08 +0100 <ski> data Queue a
2023-12-04 01:40:10 +0100 <ski> where
2023-12-04 01:40:22 +0100 <iqubic> I'm familiar with how `GADTs' work.
2023-12-04 01:40:22 +0100 <ski> MkQueue :: q -> (a -> q -> q) -> (q -> Maybe (q,a)) -> Queue a
2023-12-04 01:41:05 +0100 <iqubic> That's a catamorpism for `Queue a'
2023-12-04 01:41:11 +0100 <ski> (anyway, this ought to explain why the `ExistentialQuantification' syntax uses the `forall' keyword .. the data constructor *is* polymorphic in the existentially quantified type variable (which does not occur in the result type, only possibly in argument types))
2023-12-04 01:41:39 +0100 <iqubic> I actually think I already knew that.
2023-12-04 01:41:57 +0100 <ski> now, `Queue a' encapsulates one internal state of a queue, together with methods for manipulating it
2023-12-04 01:42:34 +0100 <iqubic> That makes sense.
2023-12-04 01:42:44 +0100 <ski> in practice, you'd then define wrapper methods, which extract the state, and the method implementation in question, apply it to the state (and any extra parameters), and then *rewrap* the new state with the method implementations again, producing a new `Queue a' as result
2023-12-04 01:43:19 +0100 <ski> and, you'd define a "class constructor", which is just a function that returns a `Queue a'
2023-12-04 01:43:24 +0100 <iqubic> That's just the smart thing to do.
2023-12-04 01:43:26 +0100 <ski> emptyQ :: Queue a
2023-12-04 01:43:48 +0100 <ski> emptyQ = MkQueue [] enqueue dequeue
2023-12-04 01:43:50 +0100 <ski> where
2023-12-04 01:43:54 +0100 <ski> enqueue ... = ...
2023-12-04 01:43:58 +0100 <ski> dequeue ... = ...
2023-12-04 01:44:02 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-04 01:44:24 +0100 <ski> so that's your "class"/"class constructor". it specifies the initial state, and provides implementations for the methods
2023-12-04 01:44:37 +0100 <iqubic> @type uncons
2023-12-04 01:44:38 +0100 <lambdabot> [a] -> Maybe (a, [a])
2023-12-04 01:44:58 +0100 <ski> well, the above implementation uses `[a]' for `q' .. this is inefficient, namely to add to one end of a list, and remove from the other
2023-12-04 01:45:10 +0100 <iqubic> I agree.
2023-12-04 01:45:10 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-04 01:45:19 +0100 <iqubic> Using a linked list is slow.
2023-12-04 01:45:31 +0100 <ski> better is to use `([a],[a])' for the state type `q', basically a queue with state `(front,revBack)' represents the items in the list `front ++ reverse revBack'
2023-12-04 01:45:42 +0100 <ski> this is the "folklore FP" implementation of queues
2023-12-04 01:46:54 +0100 <iqubic> I think I actually wrote an implementation of a Queue using that representation for the Queue
2023-12-04 01:47:18 +0100 <ski> (once in a while, when `revBack' becomes empty, you reverse `front' and move it over to `revBack', setting the new `front' to `[]'. but that `O(n)' cost is only incurred now and them, making the amorticized cost still `O(1)' .. assuming you just keep around the newest version of the queue, not older versions. there are ways to make it efficient, even if you keep around the older ones. see "Purely Functional
2023-12-04 01:47:24 +0100 <ski> Data Structures" by Chris Okasaki)
2023-12-04 01:47:30 +0100johnw(~johnw@69.62.242.138)
2023-12-04 01:48:06 +0100 <ski> anyway, taking a step back to `exists q. q * (a * q -> q) * (q -> Maybe (q * a))', we can use the equivalent with the `nu' form here actually, rewriting as
2023-12-04 01:48:22 +0100 <ski> exists q. q * (a * q -> q) * (q -> Maybe (q * a))
2023-12-04 01:48:34 +0100 <ski> = exists q. q * (a -> q -> q) * (q -> Maybe (q * a))
2023-12-04 01:48:41 +0100 <ski> = exists q. q * (q -> a -> q) * (q -> Maybe (q * a))
2023-12-04 01:48:55 +0100 <ski> = exists q. q * (q -> (a -> q) * Maybe (q * a))
2023-12-04 01:49:08 +0100 <ski> = nu q. (a -> q) * Maybe (q * a)
2023-12-04 01:49:12 +0100 <ski> which now suggests
2023-12-04 01:49:48 +0100 <ski> data Queue a = MkQueue {enqueue :: a -> Queue a,dequeue :: Maybe (Queue a,a)}
2023-12-04 01:49:57 +0100 <iqubic> I used my own Queue implementation for Advent of Code one year, before I found that Containers has Data.Seq, which has a much better API and implenentation than what I made myself.
2023-12-04 01:49:58 +0100 <ski> (taking the greatest fixed point interpretation of this)
2023-12-04 01:50:08 +0100 <ski> now the instance state is hidden, inside closures
2023-12-04 01:50:18 +0100 <iqubic> Right.
2023-12-04 01:52:00 +0100 <ski> there is a similar equivalence between `a -> b' and `exists env. env * (env * a #-> b)', expressing how functions can be represented as a closure, a pair of a "(user) data"/"context"/"environment"/"config" part, and a (low-level) function (think C function pointer, or address of a subroutine in assembler) taking that, and the function argument, as input
2023-12-04 01:52:13 +0100 <iqubic> Data.Seq is actually a dequeue, as you can add and remove from both ends.
2023-12-04 01:52:47 +0100 <iqubic> I didn't know about that last equivalence!
2023-12-04 01:53:01 +0100 <ski> (`#->' there is known as "strict implication", in logic, btw. `a #-> b' is equivalent to `[] (a -> b)', where `[]' is read "necessary", and in this case means that it's not "cotingent", doesn't depend on run-time input, is defined statically at the top-level)
2023-12-04 01:53:45 +0100 <ski> in C, the `qsort' (suggesting, but not mandating, "quick sort") function, is specified as
2023-12-04 01:54:01 +0100 <ski> void qsort(void *base,size_t nmemb,size_t size,int (*compar)(const void *,const void *));
2023-12-04 01:54:21 +0100 <iqubic> Got it. I was thinking you had randomly decided to pull in Linear Types for some reason. Good to know that's not thecate.
2023-12-04 01:54:23 +0100 <ski> which, if we imagine an extension of C with parametric polymorphism (and parameterized data types), would really be
2023-12-04 01:54:29 +0100 <iqubic> *the case
2023-12-04 01:54:54 +0100 <ski> forall<T> void qsort<T>(T *base,size_t nmemb,typesize_t<T> size,int (*compar)(const T *,const T *));
2023-12-04 01:55:16 +0100 <ski> but better would have been to make the interface pass along a "data pointer", to be passed to the callback, as
2023-12-04 01:55:34 +0100 <ski> forall<T,U> void qsort<T>(T *base,size_t nmemb,typesize_t<T> size,U *env,int (*compar)(U *,const T *,const T *));
2023-12-04 01:55:37 +0100 <ski> or just
2023-12-04 01:55:59 +0100 <ski> void qsort(void *base,size_t nmemb,size_t size,void *env,int (*compar)(void *,const void *,const void *));
2023-12-04 01:56:02 +0100 <ski> in actual C
2023-12-04 01:56:35 +0100 <ski> because then the callback would be able to depend on run-time data, without needing to use global state (which is undesirable in the presence of multi-threading, also reentrancy)
2023-12-04 01:56:49 +0100 <iqubic> That does seem lake a better type signature.
2023-12-04 01:57:32 +0100 <ski> GTK does callbacks in this style
2023-12-04 01:57:40 +0100 <ski> and it's basically emulating closures
2023-12-04 01:57:44 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe)
2023-12-04 01:58:28 +0100 <ski> if you wanted to store a closure, more long-term, you'd use something like `struct { void *data; void (*foo)(void *data,size_t n,double (*parr)[n]); }' or somesuch
2023-12-04 01:58:40 +0100 <ski> (or, if you add multiple function pointers in there, you get "OO objects")
2023-12-04 01:58:53 +0100 <iqubic> I don't know how GTK works, as I've never used it.
2023-12-04 01:59:07 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-04 01:59:09 +0100 <ski> if you check <https://www.glfw.org/docs/latest/group__input.html#ga1caf18159767e761185e49a3be019f8d> (in GLFW), this says
2023-12-04 01:59:33 +0100 <ski> GLFWkeyfun glfwSetKeyCallback(GLFWwindow *window,GLFWkeyfun callback);
2023-12-04 01:59:40 +0100 <iqubic> C isn't Object Oriented is it?
2023-12-04 01:59:56 +0100 <ski> where `GLFWkeyfun' is defined at <https://www.glfw.org/docs/latest/group__input.html#ga5bd751b27b90f865d2ea613533f0453c> as
2023-12-04 02:00:12 +0100 <ski> typedef void (*GLFWkeyfun)(GLFWwindow *window,int key,int scancode,int action,int mods)
2023-12-04 02:00:26 +0100 <ski> .. so it looks like these callbacks are missing the "user data" to simulate closures :(
2023-12-04 02:00:38 +0100 <ski> iqubic : no, but this is one way to simulate OO objects
2023-12-04 02:00:54 +0100 <ski> (not including implementation inheritance, that requires a bit more stuff)
2023-12-04 02:00:57 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com)
2023-12-04 02:00:57 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
2023-12-04 02:00:57 +0100wroathe(~wroathe@user/wroathe)
2023-12-04 02:01:21 +0100 <ski> however, checking <https://www.glfw.org/docs/latest/group__window.html#gae77a4add0d2023ca21ff1443ced01653>, we see
2023-12-04 02:01:37 +0100 <ski> void *glfwGetWindowUserPointer(GLFWwindow *window);
2023-12-04 02:01:37 +0100 <ski> and
2023-12-04 02:02:01 +0100 <ski> void glfwSetWindowUserPointer(GLFWwindow *window,void *pointer);
2023-12-04 02:02:10 +0100 <ski> so there the user data is !
2023-12-04 02:02:39 +0100 <ski> i suspect they realized the usefulness of this later, and decided to add it like this, rather than change the existing interface for creating a window
2023-12-04 02:03:06 +0100 <ski> (someone pointed this about GLFW out, the other day, which is why i recalled it now)
2023-12-04 02:03:35 +0100 <ski> (yea, no linear types, here)
2023-12-04 02:04:09 +0100 <ski> anyway, i wanted to say one more thing about the queues above
2023-12-04 02:04:10 +0100 <wroathe> Hey guys, me again... how would I go about determining what in this loop is allocating memory, and how many times it's being constructed? https://gist.github.com/JustinChristensen/2111f13e812112b5ac973e292606d17f#file-fixfile-hs-L65-L84 I'm running a memory benchmark that shows that for a 6.8M file that has ~7M characters a single call to fixFile allocates 4.5GB worth of heap objects and GCs 1079 times.
2023-12-04 02:04:12 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 252 seconds)
2023-12-04 02:04:16 +0100 <wroathe> I'd like to determine how I could run a more detailed benchmark to show exactly where those allocations are occurring...
2023-12-04 02:04:44 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-04 02:05:31 +0100 <wroathe> My two theories are constructing boxed Word8 values, and constructing boxed FixedState values in this loop. My goal is to get this loop to near-native performance where the automaton keeps the state value in a single word of memory
2023-12-04 02:05:34 +0100 <ski> consider again `exists q. q * (a * q -> q) * (q -> 1 + a * q)' -- but this time, think of it differently. think of the first `q' part not as "current state" but as "another operation", namely one for giving an empty queue. while the other two are still "enqueue" and "dequeue"
2023-12-04 02:06:30 +0100 <ski> data QueueOps a = forall q. MkQueueOps {empty :: q,enqueue :: a -> q -> q,dequeue :: q -> Maybe (q,a)}
2023-12-04 02:07:17 +0100 <ski> iqubic : the difference now is that, instead of unwrapping, applying method, then rewrapping state, repeatedly, we now just unwrap/open the container of operations *once* at the start, then pass around "naked queue states" to the operations
2023-12-04 02:08:41 +0100 <ski> and this makes a real difference, since now you can have "binary operations", like e.g. taking two heaps and merging them together into one. or taking two priority queues and merging them. with the "OO view" of existentials, you have just a single object state, so your "binary method" can't "look inside" both queue inputs, just one. the other might use a different internal state type
2023-12-04 02:09:00 +0100 <ski> but with this version, the "ADT view" (Abstract Data Type), you *can* have "binary operations"
2023-12-04 02:09:06 +0100[_](~itchyjunk@user/itchyjunk/x-7353470)
2023-12-04 02:10:32 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-04 02:11:40 +0100 <ski> wroathe : hm, you removed the strict patterns on `state', looks like
2023-12-04 02:12:21 +0100 <ski> did you try [Leary]'s other suggestion ? (Church encoding)
2023-12-04 02:12:22 +0100 <wroathe> ski: I did. That didn't help at all, and if it did I couldn't have explained why
2023-12-04 02:12:26 +0100[itchTheIndiffer(~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 245 seconds)
2023-12-04 02:12:39 +0100 <wroathe> ski: I'm not going to do a lot of rewriting until I get past the "evidence" phase
2023-12-04 02:13:00 +0100 <wroathe> Still trying to figure out exactly what gets allocated where. Even ticky-ticky isn't very explanatory
2023-12-04 02:13:05 +0100 <ski> yea, your're only passing `Start' or `Backslash' as argument in the `state' position, so i wouldn't except being strict in the argument doing much
2023-12-04 02:13:05 +0100 <iqubic> ski: brb, switching machines
2023-12-04 02:13:35 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-04 02:13:43 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-04 02:13:48 +0100 <wroathe> ski: I was actually just looking at MutVar#. I'm wondering how I can make that enumeration an unlifted type, and then read/write it from a mutable location
2023-12-04 02:14:03 +0100iqubic-(~avi@2601:602:9502:c70:774c:879b:1855:10ba)
2023-12-04 02:14:13 +0100 <iqubic-> back
2023-12-04 02:14:49 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 276 seconds)
2023-12-04 02:15:05 +0100ski's not quite sure what `fixFile' is supposed to do
2023-12-04 02:16:00 +0100 <ski> iqubic : i'll wait for you to read the last above, and perhaps comment/ask about it
2023-12-04 02:16:02 +0100 <wroathe> ski: It's just a simple state machine. I'm iterating through the characters of a file, and I need to keep track of whether I've seen a Backslash or not. If I see a Backslash, and then I find a character that isn't a Backslash, I'm inserting a matching \ before continuing with output
2023-12-04 02:16:27 +0100 <wroathe> ski: The point of the program is that I've got a TSV that has a bunch of \ in unquoted fields, and this function "fixes" that by properly escaping them
2023-12-04 02:16:38 +0100 <wroathe> As an exercise I'm trying to see if I can get it to sed-like performance
2023-12-04 02:17:03 +0100 <ski> oh, i guess you double the backslashes .. unless it was already doubled ?
2023-12-04 02:17:05 +0100 <wroathe> (If I can't there will be no point in maintaining this in Haskell code when I've got a perfectly good shell script that runs sed just fine)
2023-12-04 02:17:09 +0100skimissed the doubling, initially
2023-12-04 02:17:13 +0100 <wroathe> ski: Correct
2023-12-04 02:17:26 +0100iqubic(~avi@2607:fb91:1518:c0e2:d265:9ef3:5320:9df0) (Ping timeout: 245 seconds)
2023-12-04 02:17:47 +0100 <wroathe> Thanks to earlier suggestions in here and a bit of digging in the Base code I was able to minimize the amount of I/O and maximize the amount of buffering this does
2023-12-04 02:18:10 +0100 <wroathe> But something within this loop is doing a bunch of allocating throwaway objects, and I'd like to make it stop doing that
2023-12-04 02:18:18 +0100 <ski> i was wondering how efficient it would be to use a buffer size of `1'
2023-12-04 02:18:54 +0100 <wroathe> ski: Well that's just intended to be a memory location to hold a single character being examined in the loop. The actual buffering is done on the Handle
2023-12-04 02:19:38 +0100 <wroathe> If you look at the top I defined this thing I'm calling a "Fat FD" that allows me to create a separate instance of BufferedIO where I set my buffer size to 8M. I learned yesterday that for regular FD GHC hardcodes that to just 8192 bytes!
2023-12-04 02:20:09 +0100 <ski> mhm
2023-12-04 02:20:10 +0100 <wroathe> So if I've got an 800M TSV that would end up being like almost 100k write calls
2023-12-04 02:20:49 +0100 <ski> i see
2023-12-04 02:21:07 +0100 <wroathe> read/write, actually. On either end.
2023-12-04 02:21:39 +0100 <wroathe> Pretty happy with how that turned out. It works nicely. Now to make Haskell stop doing Haskell things in the loop itself.
2023-12-04 02:21:42 +0100skiwould proably look at core of the code, trying to see where it could allocate
2023-12-04 02:22:20 +0100 <ski> (`-ddump-simpl', or perhaps some other version of it)
2023-12-04 02:22:43 +0100 <wroathe> Let me see if that makes more sense to me than the stg or cmm did
2023-12-04 02:22:47 +0100 <wroathe> I haven't tried simpl yet
2023-12-04 02:24:41 +0100 <wroathe> ski: What does an allocation "look like" in simpl?
2023-12-04 02:25:10 +0100 <wroathe> For example, I see this: case ghc-prim:GHC.Prim.word8ToWord# ipv3_a3KB of { __DEFAULT -> src<bench/memory/Main.hs:69:47-51> Main.Start; 92## -> src<bench/memory/Main.hs:69:32-40> Main.Backslash })
2023-12-04 02:26:13 +0100 <ski> that's checking `c == bs'
2023-12-04 02:26:53 +0100smalltalkman(uid545680@id-545680.hampstead.irccloud.com) (Quit: Connection closed for inactivity)
2023-12-04 02:27:32 +0100 <wroathe> Right, but I mean the terms "Main.Backslash" and "Main.Start" there. Do those constitute an allocation?
2023-12-04 02:27:33 +0100 <ski> `let' would allocate. and lambdas, often, i guess. and i suppose calling data constructors
2023-12-04 02:29:08 +0100 <ski> hm, i suspect so
2023-12-04 02:29:32 +0100 <wroathe> My theory right now is that GHC isn't recognizing what this pattern is, and is just allocating a new value of type FixState on every loop iteration
2023-12-04 02:29:55 +0100 <wroathe> So I think what I need to do here is figure out what the syntax for making it an unlifted type is, and use something like MutVar#
2023-12-04 02:30:28 +0100 <iqubic-> ski: I assume using this would be better than trying roll my own Queue code: https://hackage.haskell.org/package/containers-0.7/docs/Data-Sequence.html#t:Seq
2023-12-04 02:31:56 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-04 02:32:05 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe) (Remote host closed the connection)
2023-12-04 02:32:06 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-04 02:32:21 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe)
2023-12-04 02:32:21 +0100 <iqubic-> It's O(1) for popping from each end and O(1) for pushing to either end
2023-12-04 02:33:42 +0100 <iqubic-> Oh... except that this doesn't work with infinite Seqs
2023-12-04 02:34:19 +0100 <iqubic-> (1 :<| undefined) `index` 0 = undefined
2023-12-04 02:34:27 +0100Square(~Square@user/square) (Ping timeout: 252 seconds)
2023-12-04 02:34:45 +0100 <iqubic-> It's strict in the spine of the sequence. But it's still really good for what it does.
2023-12-04 02:36:30 +0100 <ski> iqubic- : probably, yea
2023-12-04 02:36:48 +0100 <ski> .. how would you like infinite queues to work ?
2023-12-04 02:37:15 +0100 <ski> (enqueueing being a black hole, and dequeueing just removing from its infinite end ?)
2023-12-04 02:38:12 +0100 <ski> wroathe : yea. i suspect that using a Church representation, GHC could perhaps use "join points", which would not require additional allocation
2023-12-04 02:38:13 +0100 <iqubic-> Yeah... I don't know when I'd need an infinite Sequence.
2023-12-04 02:38:29 +0100 <ski> (but i haven't tried playing around with that, with `-ddumpl-simpl' or similar)
2023-12-04 02:38:49 +0100 <ski> iqubic- : no, i mean, not when you need it, but how ought it to work, reasonably
2023-12-04 02:39:20 +0100 <ski> (iqubic- : i also PMed you a question)
2023-12-04 02:39:39 +0100 <wroathe> ski: Hmm, Church scares me... (on a number of levels). I'll try both that and this approach. Ultimately I would prefer to use Lifted types for this that GHC magically optimizes to the code I want
2023-12-04 02:39:58 +0100 <geekosaur> require a Monoid constraint, enqueue eats, dequeue produces mempty 🙂
2023-12-04 02:40:31 +0100skinods to wroathe
2023-12-04 02:41:10 +0100iqubic-(~avi@2601:602:9502:c70:774c:879b:1855:10ba) (Remote host closed the connection)
2023-12-04 02:41:25 +0100 <ski> geekosaur : not necessarily. you could have `listToQueue :: [a] -> Queue a', where if the list is infinite, enqueueing is just a black hole, and dequeueing removes from the infinite list
2023-12-04 02:41:33 +0100 <geekosaur> the Hawking version requires an Arbitrary constraint so dequeue can produce a randomized value
2023-12-04 02:41:45 +0100iqubic(~avi@2601:602:9502:c70:774c:879b:1855:10ba)
2023-12-04 02:42:57 +0100 <ski> hehe :p
2023-12-04 02:45:05 +0100 <ski> listToQueue revBack = loop [] revBack
2023-12-04 02:45:08 +0100 <ski> where
2023-12-04 02:45:36 +0100 <ski> enqueue (loop front revBack) x = loop (x:front) revBack
2023-12-04 02:46:22 +0100 <ski> dequeue (loop front [ ]) = ...
2023-12-04 02:46:49 +0100 <ski> dequeue (loop front (x:revBack)) = Just (loop front revBack,x)
2023-12-04 02:49:41 +0100 <ski> iqubic : anyway, continuations can be useful for efficiency reasons (directly call a callback, instead of making a bundle that'll only be unwrapped by the receiver immediately after the call). can also be useful sometimes for control reasons (early return/exit / short-circuiting), and for more advanced control (e.g. backtracking, ..)
2023-12-04 02:50:12 +0100 <iqubic> Yeah. That's really cool.
2023-12-04 02:51:17 +0100 <ski> e.g. you can use this to turn "internal iteration" (like a `mapM' library operation that applies a callback to each element of some collection (perhaps virtual, generated as we go)), into "external iteration" (the caller gets to decide if and when we advance to the next element)
2023-12-04 02:51:49 +0100szkl(uid110435@id-110435.uxbridge.irccloud.com)
2023-12-04 02:52:50 +0100 <ski> if a language has composable/delimited/sub- continuation side-effects (or, equivalently, (undelimited) continuation side-effects, and at least one mutable cell (state side-effect)), then, given any implementation of a monad, you can turn that into a side-effect, as if that monad was a built-in side-effect in the language (and with composable continuations, this can be relatively efficient, more than
2023-12-04 02:52:56 +0100 <ski> interpreting different data constructors all the time in (especially left-nested) `(>>=)'s). e.g. you could introduce parser side-effects that way
2023-12-04 02:53:19 +0100 <ski> there's two nice papers by Andrzej Filinski about this. the technique (and the papers) is called "monadic reflection"
2023-12-04 02:54:34 +0100 <iqubic> I'll look into that when I get time. I need to get some dinner now.
2023-12-04 02:54:46 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-04 02:54:48 +0100 <ski> if you have `foo :: ... -> Maybe T', you can replace this with `withFoo :: ... -> o -> (T -> o) -> o' (or perhaps, if you had `foo :: ... -> IO (Maybe T)', you'd replace this with `withFoo :: ... -> IO o -> (T -> IO o) -> IO o')
2023-12-04 02:55:06 +0100 <ski> this is passing two continuations, one for the `Nothing' case, and one for the `Just' case, of the `Maybe'
2023-12-04 02:55:16 +0100 <iqubic> I am now a more clever and learned lady!
2023-12-04 02:55:43 +0100Xyloes(~wyx@2400:dd01:103a:1012:5923:33ce:7857:fc04)
2023-12-04 02:55:54 +0100 <ski> `withFoo' will directly call the appropriate continuation (corresponding to a branch of a `case'), rather than constructing a `Maybe T', only to have the caller take it apart immediately and branch into a `case'
2023-12-04 02:56:43 +0100 <ski> effectively, `withFoo' will jump to the appropriate branch immediately, without the control flow having to first pass through the "needle's eye" of the `case', requiring allocating a `Maybe' somewhere
2023-12-04 02:57:39 +0100 <ski> parsing combinator libraries often do something like this, internally
2023-12-04 02:58:11 +0100 <ski> also the `LogicT' type, for fair backtracking, iirc
2023-12-04 02:58:48 +0100 <ski> @hackage logict
2023-12-04 02:58:48 +0100 <lambdabot> https://hackage.haskell.org/package/logict
2023-12-04 03:00:18 +0100 <ski> newtype LogicT m a = LogicT { unLogicT :: forall r. (a -> m r -> m r) -> m r -> m r } -- yep
2023-12-04 03:01:21 +0100 <ski> (note `LogicT Identity a' is the Church representation for `[a]')
2023-12-04 03:02:11 +0100 <ski> oh, i guess, on the topic of `withXXX', i should mention the two encodings of `exists'
2023-12-04 03:02:15 +0100 <ski> if we want
2023-12-04 03:02:42 +0100 <ski> foo :: ... -> exists q. (q,(a,q) -> q,q -> Maybe (q,a))
2023-12-04 03:02:47 +0100 <ski> we can represent this as
2023-12-04 03:02:54 +0100 <ski> foo :: ... -> Queue a
2023-12-04 03:03:15 +0100 <ski> defining `Queue a' as we did above, using `ExistentialQuantification' or `GADTs'
2023-12-04 03:03:40 +0100 <ski> or, we can use the equivalence between `...' and `forall o. (... -> o) -> o', to get from
2023-12-04 03:03:44 +0100 <ski> foo :: ... -> exists q. (q,(a,q) -> q,q -> Maybe (q,a))
2023-12-04 03:03:46 +0100 <ski> to
2023-12-04 03:04:03 +0100 <ski> withFoo :: ... -> forall o. ((exists q. (q,(a,q) -> q,q -> Maybe (q,a))) -> o) -> o
2023-12-04 03:04:07 +0100sawilagar(~sawilagar@user/sawilagar) (Ping timeout: 255 seconds)
2023-12-04 03:04:26 +0100 <ski> which, by `(exists a. ..a..) -> ...' being equivalent to `forall a. (..a.. -> ...)', amounts to
2023-12-04 03:04:46 +0100 <ski> withFoo :: ... -> forall o. (forall q. (q,(a,q) -> q,q -> Maybe (q,a)) -> o) -> o
2023-12-04 03:05:22 +0100 <ski> or, uncurrying (and removing the `forall o.', since `... -> forall a. ..a..' is equivalent to `forall a. (... -> ..a..)', and we can elide top-level `forall's)
2023-12-04 03:05:54 +0100 <ski> withFoo :: ... -> (forall q. q -> (a -> q -> q) -> (q -> Maybe (q,a)) -> o) -> o
2023-12-04 03:06:27 +0100 <ski> so, this is the "CPS" encoding of existentials, by passing an extra callback, that will be polymorphic in the existentially quantified type variable
2023-12-04 03:06:42 +0100 <ski> iqubic : have a nice dinner
2023-12-04 03:08:49 +0100 <iqubic> Thanks for being willing to teach a trans woman like me.
2023-12-04 03:11:56 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com)
2023-12-04 03:15:01 +0100travgm(~travgm@fsf/member/travgm)
2023-12-04 03:16:14 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 252 seconds)
2023-12-04 03:18:46 +0100emmanuelux(~emmanuelu@user/emmanuelux) (Quit: au revoir)
2023-12-04 03:29:56 +0100travgm(~travgm@fsf/member/travgm) (Ping timeout: 245 seconds)
2023-12-04 03:33:31 +0100 <wroathe> ski: So I lost Leary's example, but is the church encoding for FixState in my example basically the same as the "bool" encoding? Is this correct?
2023-12-04 03:33:34 +0100 <wroathe> type FixState a = a -> a -> a
2023-12-04 03:33:36 +0100 <wroathe> start :: FixState a; start a _ = a
2023-12-04 03:33:39 +0100 <wroathe> backslash :: FixState a; backslash _ b = b
2023-12-04 03:34:11 +0100 <ski> well, more like `type FixState = forall a. a -> a -> a' .. but yes, for `start' and `backslash'
2023-12-04 03:34:32 +0100 <wroathe> Ah, I was wondering about forall a. there
2023-12-04 03:34:46 +0100 <wroathe> I still don't get the use of forall beyond making the compiler shut up
2023-12-04 03:34:55 +0100Xyloes(~wyx@2400:dd01:103a:1012:5923:33ce:7857:fc04) (Remote host closed the connection)
2023-12-04 03:35:08 +0100 <wroathe> Is it RankNTypes that enables that for type synonyms?
2023-12-04 03:35:14 +0100 <ski> `forall' means the corresponding value is polymorphic
2023-12-04 03:36:00 +0100 <ski> `length :: forall a. ([a] -> Int)' means that, strictly speaking, `length' is not a function, but a "polymorphic value". namely one that, when specialized, yields a function. (a "polymorphic function", for short)
2023-12-04 03:36:28 +0100 <wroathe> type FixState a = a -> a -> a
2023-12-04 03:36:28 +0100 <wroathe> start :: FixState a; start a _ = a
2023-12-04 03:36:29 +0100 <wroathe> backslash :: FixState a; backslash _ b = b
2023-12-04 03:36:34 +0100 <ski> if you use `forall' around an argument type, then that argument itself (not necessarily the whole function that takes that argument) is polymorphic. this is known as rank-3
2023-12-04 03:36:34 +0100 <wroathe> Whooops, sorry
2023-12-04 03:36:37 +0100 <ski> er, rank-2
2023-12-04 03:36:52 +0100 <wroathe> • Illegal polymorphic type: forall a. a -> a -> a
2023-12-04 03:36:52 +0100 <wroathe> • In the expansion of type synonym ‘FixState’
2023-12-04 03:36:52 +0100 <wroathe> In the type signature:
2023-12-04 03:36:52 +0100 <wroathe> emit :: Handle -> Ptr Word8 -> Word8 -> FixState -> IO FixState
2023-12-04 03:37:29 +0100Xyloes(~wyx@2400:dd01:103a:1012:5923:33ce:7857:fc04)
2023-12-04 03:37:38 +0100 <wroathe> I take it that's not very useful with type synonyms then
2023-12-04 03:37:41 +0100 <ski> *usually*, if you write a type signature with type variables in it, like `zip :: [a] -> [b] -> [(a,b)]', there's "implicit" `forall's *directly* after the `::'
2023-12-04 03:38:03 +0100Sciencentistguy9(~sciencent@hacksoc/ordinary-member)
2023-12-04 03:38:35 +0100 <ski> iow, we really have `zip :: forall a b. [a] -> [b] -> [(a,b)]', but Haskell allows us to be implicit about the `forall's, omit/elide them, so just writing `zip :: [a] -> [b] -> [(a,b)]', and the implementation will (conceptually, at least) insert them back for us
2023-12-04 03:38:57 +0100 <ski> this is merely a convenience thing. some other languages with polymorphism has no such convenience syntax
2023-12-04 03:39:10 +0100 <wroathe> So is the above error saying that we basically do need FixState paramterized by a so that I can quantify it in function signatures?
2023-12-04 03:39:22 +0100travgm(~travgm@2600:100e:a121:d6af:56b:4880:133:700e)
2023-12-04 03:40:12 +0100Sciencentistguy(~sciencent@hacksoc/ordinary-member) (Ping timeout: 268 seconds)
2023-12-04 03:40:12 +0100Sciencentistguy9Sciencentistguy
2023-12-04 03:40:40 +0100 <ski> in any case, `a -> Bool' is *not* short for `forall a. a -> Bool' (since if it were, then `filter :: (a -> Bool) -> [a] -> [a]', could be said to mean the same as `filter :: (forall a. a -> Bool) -> [a] -> [a]', which it most definitely does *not*) .. it's only at the "top-level" of a type *signature*, right after the `::', where implicit `forall's can be added
2023-12-04 03:41:15 +0100 <wroathe> Your brain is too big for me :P
2023-12-04 03:41:45 +0100 <ski> "I take it that's not very useful with type synonyms then" -- with `Rank2Types' or `RankNTypes', they can be
2023-12-04 03:42:28 +0100 <ski> "So is the above error saying that we basically do need FixState paramterized by a so that I can quantify it in function signatures?" -- no, it's asking you to turn on higher-rank (or at least rank-2)
2023-12-04 03:42:32 +0100 <ski> since
2023-12-04 03:42:36 +0100 <ski> emit :: Handle -> Ptr Word8 -> Word8 -> FixState -> IO FixState
2023-12-04 03:42:45 +0100 <ski> by the type synonym, expands to
2023-12-04 03:42:58 +0100 <wroathe> I've got RankNTypes enabled
2023-12-04 03:42:59 +0100 <ski> emit :: Handle -> Ptr Word8 -> Word8 -> (forall a. a -> a -> a) -> IO (forall a. a -> a -> a)
2023-12-04 03:43:09 +0100 <ski> and that's rank-2, the argument is polymorphic
2023-12-04 03:43:22 +0100 <ski> the second problem is that you now also have `forall' nested inside of `IO'
2023-12-04 03:43:23 +0100 <wroathe> It won't let me define type FixState = forall a. a -> a -> a without it
2023-12-04 03:43:57 +0100 <ski> that requires `ImpredicativeTypes' .. which at least used to only be partially implemented. there was some paper with a new approach to it, but i dunno if that's available in GHC yet
2023-12-04 03:44:16 +0100 <ski> one way around that is to wrap the `forall' inside a data type
2023-12-04 03:44:28 +0100 <ski> newtype FixState = FS (forall a. a -> a -> a)
2023-12-04 03:44:37 +0100 <geekosaur> QuickLook has been in ghc since 9.2
2023-12-04 03:44:39 +0100 <ski> then `IO FixState' will be fine
2023-12-04 03:44:59 +0100 <ski> geekosaur : and it works fine, also for `IO (forall a. ..a..)' say ?
2023-12-04 03:45:09 +0100skican't recall the details of the paper
2023-12-04 03:45:13 +0100 <wroathe> ski: https://gist.github.com/JustinChristensen/2111f13e812112b5ac973e292606d17f#file-church-hs
2023-12-04 03:45:17 +0100 <geekosaur> I think so, yes
2023-12-04 03:45:19 +0100 <ski> ok
2023-12-04 03:45:23 +0100 <geekosaur> I don't do impredicativity much
2023-12-04 03:45:28 +0100hgolden_(~hgolden@cpe-172-251-233-141.socal.res.rr.com)
2023-12-04 03:45:30 +0100 <wroathe> This is obviously wrong, but this I think is what you guys are suggesting I do when you say church encoding
2023-12-04 03:45:59 +0100jmdaemon(~jmdaemon@user/jmdaemon)
2023-12-04 03:46:59 +0100hgolden(~hgolden@2603-8000-9d00-3ed1-dd4f-298a-9c49-a0ed.res6.spectrum.com) (Ping timeout: 268 seconds)
2023-12-04 03:50:56 +0100 <ski> hm, yea, i think if you were just returning `IO FixState', that could be useful. but now you're also taking a `FixState' as input, which is making this more questionable. passing `start' or `backslash' as input might allocate closures here, unless these get allocated once, outside
2023-12-04 03:51:04 +0100Unicorn_Princess(~Unicorn_P@user/Unicorn-Princess/x-3540542) (Remote host closed the connection)
2023-12-04 03:51:46 +0100 <ski> (and even then, calling `state' with two `do's may allocate those, i guess unless they get translated into join points ?)
2023-12-04 03:52:37 +0100 <wroathe> So are you saying you're cooling on the idea of the church encoding being a solution for this?
2023-12-04 03:52:48 +0100 <wroathe> I still haven't gotten this to compmile
2023-12-04 03:52:51 +0100 <wroathe> compile*
2023-12-04 03:55:44 +0100smalltalkman(uid545680@id-545680.hampstead.irccloud.com)
2023-12-04 03:59:01 +0100wroathegives up on this idea
2023-12-04 04:09:30 +0100travgm(~travgm@2600:100e:a121:d6af:56b:4880:133:700e) (Ping timeout: 268 seconds)
2023-12-04 04:34:34 +0100ddellacosta(~ddellacos@ool-44c73d16.dyn.optonline.net) (Ping timeout: 276 seconds)
2023-12-04 04:44:21 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
2023-12-04 04:44:21 +0100finn_elija(~finn_elij@user/finn-elija/x-0085643)
2023-12-04 04:44:21 +0100finn_elijaFinnElija
2023-12-04 04:44:33 +0100codolio(~dolio@130.44.134.54)
2023-12-04 04:45:19 +0100dolio(~dolio@130.44.134.54) (Ping timeout: 260 seconds)
2023-12-04 04:45:27 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-04 04:48:59 +0100hapisnake(~hapisnake@120.138.12.144)
2023-12-04 04:49:31 +0100td_(~td@83.135.9.0) (Ping timeout: 245 seconds)
2023-12-04 04:51:37 +0100td_(~td@i53870905.versanet.de)
2023-12-04 04:55:24 +0100dolio(~dolio@130.44.134.54)
2023-12-04 04:55:34 +0100codolio(~dolio@130.44.134.54) (Ping timeout: 256 seconds)
2023-12-04 04:55:59 +0100ddellacosta(~ddellacos@ool-44c73d16.dyn.optonline.net)
2023-12-04 04:59:59 +0100szkl(uid110435@id-110435.uxbridge.irccloud.com) (Quit: Connection closed for inactivity)
2023-12-04 05:01:04 +0100takuan(~takuan@178-116-218-225.access.telenet.be)
2023-12-04 05:05:29 +0100hays(rootvegeta@fsf/member/hays) (Remote host closed the connection)
2023-12-04 05:05:51 +0100hamess(~hamess@user/hamess) (Ping timeout: 260 seconds)
2023-12-04 05:10:14 +0100hapisnake(~hapisnake@120.138.12.144) (Ping timeout: 250 seconds)
2023-12-04 05:26:02 +0100hays(rootvegeta@fsf/member/hays)
2023-12-04 05:27:08 +0100hays(rootvegeta@fsf/member/hays) (Client Quit)
2023-12-04 05:29:00 +0100hays(rootvegeta@fsf/member/hays)
2023-12-04 05:41:00 +0100ddellacosta(~ddellacos@ool-44c73d16.dyn.optonline.net) (Quit: WeeChat 4.1.1)
2023-12-04 05:47:09 +0100aforemny_(~aforemny@2001:9e8:6cd2:2300:81b8:672c:d485:69b9)
2023-12-04 05:47:15 +0100aforemny(~aforemny@i59F516CC.versanet.de) (Ping timeout: 256 seconds)
2023-12-04 05:48:41 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 245 seconds)
2023-12-04 06:02:13 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com)
2023-12-04 06:12:12 +0100trev(~trev@user/trev)
2023-12-04 06:16:55 +0100lg188(~lg188@82.18.98.230) (Quit: Ping timeout (120 seconds))
2023-12-04 06:17:16 +0100lg188(~lg188@82.18.98.230)
2023-12-04 06:17:35 +0100 <glguy> int-e: you get to leverage so laziness for part 2?
2023-12-04 06:17:54 +0100 <int-e> I didn't
2023-12-04 06:19:15 +0100 <glguy> oh, maybe just recursively built up a list?
2023-12-04 06:20:40 +0100glguytries to reframe this as a scanr
2023-12-04 06:22:18 +0100 <probie> I used a boring `foldr` for part 2
2023-12-04 06:23:58 +0100 <probie> glguy: c3VtICQgZm9sZHIgKFx4IHhzIC0+IDEgKyBzdW0gKHRha2UgKHgtMSkgeHMpOiB4cykgW10gKG1hcCBjb3VudFdpbm5lcnMgZ2FtZXMp is how I did it (base64 "encrypted" to avoid spoilers)
2023-12-04 06:38:15 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 260 seconds)
2023-12-04 06:39:21 +0100azimut(~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection)
2023-12-04 06:39:47 +0100azimut(~azimut@gateway/tor-sasl/azimut)
2023-12-04 06:41:54 +0100 <EvanR> I want my client to decode64 when clicking on base64 encoded text
2023-12-04 06:46:01 +0100robobub(uid248673@id-248673.uxbridge.irccloud.com)
2023-12-04 06:49:22 +0100azimut(~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection)
2023-12-04 06:49:46 +0100azimut(~azimut@gateway/tor-sasl/azimut)
2023-12-04 06:56:35 +0100danza(~francesco@rm-19-56-167.service.infuturo.it)
2023-12-04 06:58:34 +0100wroathe(~wroathe@user/wroathe) (Ping timeout: 255 seconds)
2023-12-04 07:10:49 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 255 seconds)
2023-12-04 07:11:25 +0100euleritian(~euleritia@dynamic-002-247-251-082.2.247.pool.telefonica.de)
2023-12-04 07:16:20 +0100zetef(~quassel@95.77.17.251)
2023-12-04 07:22:13 +0100chomwitt(~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1)
2023-12-04 07:22:37 +0100hapisnake(~hapisnake@103.28.246.140)
2023-12-04 07:22:59 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Remote host closed the connection)
2023-12-04 07:23:52 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-04 07:33:56 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com)
2023-12-04 07:33:57 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
2023-12-04 07:33:57 +0100wroathe(~wroathe@user/wroathe)
2023-12-04 07:34:43 +0100hapisnake(~hapisnake@103.28.246.140) (Quit: Client closed)
2023-12-04 07:45:02 +0100wroathe(~wroathe@user/wroathe) (Ping timeout: 255 seconds)
2023-12-04 07:45:44 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-04 07:46:21 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com)
2023-12-04 07:48:32 +0100rosco(~rosco@175.136.158.171)
2023-12-04 07:50:13 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 256 seconds)
2023-12-04 07:50:46 +0100danza(~francesco@rm-19-56-167.service.infuturo.it) (Ping timeout: 255 seconds)
2023-12-04 07:50:55 +0100clwif^(~cd@c-98-242-74-66.hsd1.ga.comcast.net) (Remote host closed the connection)
2023-12-04 07:55:16 +0100euleritian(~euleritia@dynamic-002-247-251-082.2.247.pool.telefonica.de) (Read error: Connection reset by peer)
2023-12-04 07:55:33 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-04 07:56:41 +0100 <EvanR> the more I think about part 2 the less I understand it
2023-12-04 07:56:54 +0100 <EvanR> luckily I got my stars already
2023-12-04 07:59:51 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 256 seconds)
2023-12-04 08:00:11 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-04 08:02:01 +0100zetef(~quassel@95.77.17.251) (Ping timeout: 245 seconds)
2023-12-04 08:05:59 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 260 seconds)
2023-12-04 08:08:12 +0100Sgeo_(~Sgeo@user/sgeo)
2023-12-04 08:11:35 +0100Sgeo(~Sgeo@user/sgeo) (Ping timeout: 260 seconds)
2023-12-04 08:11:36 +0100zetef(~quassel@95.77.17.251)
2023-12-04 08:16:36 +0100acidjnk(~acidjnk@p200300d6e72b9356246dd2d07051f792.dip0.t-ipconnect.de)
2023-12-04 08:16:36 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
2023-12-04 08:16:43 +0100euleritian(~euleritia@dynamic-002-247-251-082.2.247.pool.telefonica.de)
2023-12-04 08:17:05 +0100euleritian(~euleritia@dynamic-002-247-251-082.2.247.pool.telefonica.de) (Read error: Connection reset by peer)
2023-12-04 08:17:21 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-04 08:25:38 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl)
2023-12-04 08:30:03 +0100sord937(~sord937@gateway/tor-sasl/sord937)
2023-12-04 08:37:38 +0100sord937(~sord937@gateway/tor-sasl/sord937) (Remote host closed the connection)
2023-12-04 08:37:59 +0100sord937(~sord937@gateway/tor-sasl/sord937)
2023-12-04 08:48:51 +0100lortabac(~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4)
2023-12-04 08:53:16 +0100iqubic(~avi@2601:602:9502:c70:774c:879b:1855:10ba) (Ping timeout: 245 seconds)
2023-12-04 08:54:06 +0100zetef(~quassel@95.77.17.251) (Ping timeout: 245 seconds)
2023-12-04 08:55:57 +0100danse-nr3(~danse@na-19-84-78.service.infuturo.it)
2023-12-04 08:56:59 +0100danse-nr3(~danse@na-19-84-78.service.infuturo.it) (Remote host closed the connection)
2023-12-04 08:57:21 +0100danse-nr3(~danse@na-19-84-78.service.infuturo.it)
2023-12-04 09:01:43 +0100azimut(~azimut@gateway/tor-sasl/azimut) (Ping timeout: 240 seconds)
2023-12-04 09:02:46 +0100CiaoSen(~Jura@2a05:5800:2d9:1600:ca4b:d6ff:fec1:99da)
2023-12-04 09:02:59 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 264 seconds)
2023-12-04 09:04:15 +0100 <EvanR> ah ha!
2023-12-04 09:04:56 +0100fendor(~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c)
2023-12-04 09:07:06 +0100zetef(~quassel@95.77.17.251)
2023-12-04 09:12:35 +0100_d0t(~{-d0t-}@user/-d0t-/x-7915216) (Ping timeout: 268 seconds)
2023-12-04 09:15:47 +0100_d0t(~{-d0t-}@user/-d0t-/x-7915216)
2023-12-04 09:21:30 +0100tzh(~tzh@c-71-193-181-0.hsd1.or.comcast.net) (Quit: zzz)
2023-12-04 09:24:03 +0100waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
2023-12-04 09:24:49 +0100coot(~coot@89.69.206.216)
2023-12-04 09:28:41 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl)
2023-12-04 09:37:04 +0100lg188(~lg188@82.18.98.230) (Quit: Ping timeout (120 seconds))
2023-12-04 09:37:27 +0100lg188(~lg188@82.18.98.230)
2023-12-04 09:37:38 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net)
2023-12-04 09:37:56 +0100idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
2023-12-04 09:42:08 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection)
2023-12-04 09:42:40 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 276 seconds)
2023-12-04 09:42:48 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643)
2023-12-04 09:46:58 +0100coot(~coot@89.69.206.216) (Quit: coot)
2023-12-04 09:48:16 +0100gmg(~user@user/gehmehgeh)
2023-12-04 09:50:28 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
2023-12-04 09:51:30 +0100euleritian(~euleritia@dynamic-002-247-251-082.2.247.pool.telefonica.de)
2023-12-04 09:56:45 +0100Sgeo_(~Sgeo@user/sgeo) (Read error: Connection reset by peer)
2023-12-04 09:58:55 +0100TMA(tma@twin.jikos.cz) (Ping timeout: 276 seconds)
2023-12-04 10:00:04 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-04 10:03:37 +0100steew(~steew@user/steew) (Ping timeout: 255 seconds)
2023-12-04 10:03:45 +0100 <danse-nr3> morning. Enjoying reading abuseofnotation.github.io/category-theory-illustrated, although it may look like kindergarden study material to many
2023-12-04 10:04:47 +0100Incredia(~Incredia@176.254.244.83) (Ping timeout: 264 seconds)
2023-12-04 10:06:40 +0100Square2(~Square4@user/square)
2023-12-04 10:08:23 +0100zetef(~quassel@95.77.17.251) (Ping timeout: 264 seconds)
2023-12-04 10:14:15 +0100cfricke(~cfricke@user/cfricke)
2023-12-04 10:17:20 +0100YoungFrog(~youngfrog@2a02:a03f:ca07:f900:3d37:6f51:8df5:683d) (Ping timeout: 268 seconds)
2023-12-04 10:19:56 +0100zetef(~quassel@95.77.17.251)
2023-12-04 10:21:15 +0100infinity0(~infinity0@pwned.gg) (Remote host closed the connection)
2023-12-04 10:23:22 +0100infinity0(~infinity0@pwned.gg)
2023-12-04 10:23:43 +0100Incredia(~Incredia@176.254.244.83)
2023-12-04 10:23:54 +0100Square2(~Square4@user/square) (Quit: Leaving)
2023-12-04 10:24:23 +0100Square2(~Square4@user/square)
2023-12-04 10:24:59 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655)
2023-12-04 10:27:33 +0100econo_(uid147250@id-147250.tinside.irccloud.com) (Quit: Connection closed for inactivity)
2023-12-04 10:29:36 +0100coot(~coot@89-69-206-216.dynamic.chello.pl)
2023-12-04 10:30:21 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe) (Remote host closed the connection)
2023-12-04 10:33:46 +0100alp_(~alp@2001:861:e3d6:8f80:59a0:3738:2d56:41bc)
2023-12-04 10:34:28 +0100waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 256 seconds)
2023-12-04 10:34:47 +0100shriekingnoise(~shrieking@186.137.175.87) (Ping timeout: 264 seconds)
2023-12-04 10:51:23 +0100chele(~chele@user/chele)
2023-12-04 11:01:20 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe)
2023-12-04 11:02:04 +0100iqubic(~avi@2601:602:9502:c70:7ce7:f8c:f1d2:dccf)
2023-12-04 11:02:46 +0100__monty__(~toonn@user/toonn)
2023-12-04 11:03:41 +0100zetef(~quassel@95.77.17.251) (Ping timeout: 245 seconds)
2023-12-04 11:05:12 +0100danse-nr3(~danse@na-19-84-78.service.infuturo.it) (Remote host closed the connection)
2023-12-04 11:09:28 +0100danse-nr3(~danse@na-19-84-78.service.infuturo.it)
2023-12-04 11:09:45 +0100kuribas(~user@ip-188-118-57-242.reverse.destiny.be)
2023-12-04 11:11:04 +0100tomboy64(~tomboy64@user/tomboy64) (Ping timeout: 276 seconds)
2023-12-04 11:14:08 +0100Lord_of_Life(~Lord@user/lord-of-life/x-2819915) (Ping timeout: 256 seconds)
2023-12-04 11:14:12 +0100zetef(~quassel@95.77.17.251)
2023-12-04 11:14:41 +0100Lord_of_Life(~Lord@user/lord-of-life/x-2819915)
2023-12-04 11:15:01 +0100malte(~malte@mal.tc)
2023-12-04 11:18:40 +0100guy80(~guy@250.79-105-213.static.virginmediabusiness.co.uk)
2023-12-04 11:19:27 +0100guy80telem
2023-12-04 11:19:42 +0100 <telem> hi, im reading about solidity
2023-12-04 11:19:51 +0100 <telem> it uses top level variables
2023-12-04 11:19:56 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 245 seconds)
2023-12-04 11:20:05 +0100 <telem> i want to understand how this fits into the haskell story
2023-12-04 11:20:19 +0100 <danse-nr3> haskell also has top level vals
2023-12-04 11:20:27 +0100 <telem> but they are immutable
2023-12-04 11:20:51 +0100 <telem> like, not variable
2023-12-04 11:21:05 +0100 <telem> we have top level immutable values
2023-12-04 11:21:35 +0100 <telem> is it something to do with the evaluation order?
2023-12-04 11:21:43 +0100 <telem> like, in do syntax you can overwrite them
2023-12-04 11:21:53 +0100 <telem> its something to do with it not being imperative?
2023-12-04 11:22:03 +0100 <danse-nr3> that is shadowing more than overwriting
2023-12-04 11:22:24 +0100 <telem> sure, but it would throw a syntax error at top level right?
2023-12-04 11:22:31 +0100 <telem> about conflicting function definitions...
2023-12-04 11:22:40 +0100 <telem> or it would just strat trying to pattern match them or something
2023-12-04 11:22:43 +0100 <telem> ahhh, maybe thats it
2023-12-04 11:22:55 +0100 <telem> so all the declerations are taken to be simultaniously true
2023-12-04 11:23:09 +0100tomboy64(~tomboy64@user/tomboy64)
2023-12-04 11:23:09 +0100 <telem> that kind of makes sense about the top down imperative evaluation order
2023-12-04 11:23:16 +0100 <telem> kind of adds a sort of temporality
2023-12-04 11:23:23 +0100 <telem> temporal scoping*
2023-12-04 11:24:12 +0100 <telem> i guess thats why you can overwrite a top level value in a restrected scope
2023-12-04 11:24:30 +0100 <telem> im always amazed how much scoping considerations affect the language
2023-12-04 11:24:41 +0100 <telem> i think its what makes it so different to imperative languages
2023-12-04 11:24:54 +0100 <telem> i think i understand how top level variables fit into this now
2023-12-04 11:25:09 +0100 <telem> so i answerd my own question! but i didnt think i could do that when i asked it!
2023-12-04 11:25:12 +0100 <telem> derp
2023-12-04 11:25:20 +0100 <danse-nr3> you are welcome
2023-12-04 11:25:30 +0100 <telem> yeah, thanks for the input
2023-12-04 11:25:37 +0100 <telem> i was kind of hoping there could be some interesting offshoot
2023-12-04 11:25:59 +0100 <telem> but then i just trying to think about carried scopes in imperative program specifications in some DSL
2023-12-04 11:26:27 +0100 <telem> i think that would make a really cool haskell style language
2023-12-04 11:26:54 +0100 <telem> i guess kind of making the list of active variables in a do-like block
2023-12-04 11:27:02 +0100 <telem> making it explicit
2023-12-04 11:27:44 +0100 <telem> i was doing something like that, where i had programs in datatypes so you could modify them
2023-12-04 11:28:25 +0100 <telem> but then there was a kind of horrible formalism of how you would have to write the corresponding program in pure haskell so that its implementation would map over nicely to how it would be written in the DSL
2023-12-04 11:29:34 +0100 <telem> you end up implementing a sort of graph with explicit shape decorations that the program sits ontop of, which essentially mimics how top level functions fit together to form a program graph
2023-12-04 11:29:53 +0100 <telem> and then get frustrated at the idea of having to somehow compile pure code to it
2023-12-04 11:30:25 +0100ridcully_(~ridcully@p57b52ac5.dip0.t-ipconnect.de)
2023-12-04 11:30:43 +0100 <telem> but then, if you can either do that, or are happy writing it by hand, then in these imperative subsequent code lines, then you can repeatedly modify the program with lenses into it and stuff
2023-12-04 11:31:15 +0100 <telem> modify_program all_if_statements_are_true
2023-12-04 11:32:11 +0100 <telem> im not sure if anything would be lost with these semantics
2023-12-04 11:32:16 +0100ridcully(~ridcully@p508acfd3.dip0.t-ipconnect.de) (Ping timeout: 255 seconds)
2023-12-04 11:32:32 +0100 <telem> other than pattern matching using multiple lines of function decleartion
2023-12-04 11:33:27 +0100 <telem> i think also, re with me cos this is kind of mind-bending. so, something like, to level value declerations *replacing* pattern matching
2023-12-04 11:33:46 +0100 <telem> like, where do you specify the value name. some languages have it in the type sig
2023-12-04 11:33:55 +0100 <telem> f :: (x :: String) -> Bool
2023-12-04 11:34:07 +0100 <telem> while in the imperative style its
2023-12-04 11:34:10 +0100 <telem> x :: String
2023-12-04 11:34:16 +0100 <telem> f :: x -> Bool
2023-12-04 11:34:24 +0100 <telem> or something like that
2023-12-04 11:34:48 +0100 <telem> obviously that conflicts with polymorphic syntax
2023-12-04 11:35:29 +0100 <telem> seems to force pattern matching into the type signature, not sure to what effect!
2023-12-04 11:36:26 +0100 <telem> i guess if the imperative ordering risked shadowing or overwriting the value, then a distinguishing annotation to a required type signature could kind of handle both value overwrites, and pattern matching which does not overwrite, other than matching a seperate case
2023-12-04 11:36:58 +0100 <telem> and then how you would treat unreachable patterns
2023-12-04 11:37:20 +0100 <telem> i think we already *have* the imperative ordering for patterns which makes me suspicious!
2023-12-04 11:37:31 +0100 <telem> i hate it when it makes *too much* sense!
2023-12-04 11:37:48 +0100 <telem> makes me think im onto something, which makes me afraid!
2023-12-04 11:38:17 +0100 <telem> so im glad that was useful!?
2023-12-04 11:38:40 +0100 <telem> and then like, i guess i dont have to wait for a response then... ciao?
2023-12-04 11:38:51 +0100telem(~guy@250.79-105-213.static.virginmediabusiness.co.uk) (Quit: Connection closed)
2023-12-04 11:40:23 +0100euleritian(~euleritia@dynamic-002-247-251-082.2.247.pool.telefonica.de) (Read error: Connection reset by peer)
2023-12-04 11:40:43 +0100euleritian(~euleritia@77.22.252.56)
2023-12-04 11:46:57 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-04 11:48:49 +0100remedan(~remedan@ip-94-112-0-18.bb.vodafone.cz) (Quit: Bye!)
2023-12-04 11:52:02 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 252 seconds)
2023-12-04 11:56:43 +0100mobivme(~mobivme@112.201.111.217) (Ping timeout: 256 seconds)
2023-12-04 11:59:55 +0100oo_miguel(~Thunderbi@78-11-179-96.static.ip.netia.com.pl)
2023-12-04 12:00:02 +0100mobivme(~mobivme@112.201.111.217)
2023-12-04 12:01:07 +0100danse-nr3(~danse@na-19-84-78.service.infuturo.it) (Ping timeout: 256 seconds)
2023-12-04 12:02:17 +0100`2jt(~jtomas@90.162.208.36)
2023-12-04 12:04:20 +0100remedan(~remedan@ip-94-112-0-18.bb.vodafone.cz)
2023-12-04 12:06:47 +0100zetef(~quassel@95.77.17.251) (Ping timeout: 256 seconds)
2023-12-04 12:16:15 +0100misterfish(~misterfis@87.215.131.102)
2023-12-04 12:16:22 +0100zetef(~quassel@95.77.17.251)
2023-12-04 12:27:29 +0100bitmapper(uid464869@id-464869.lymington.irccloud.com)
2023-12-04 12:30:25 +0100YoungFrog(~youngfrog@2a02:a03f:ca07:f900:1f5c:a3c6:297:feeb)
2023-12-04 12:34:49 +0100lortabac(~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4) (Ping timeout: 255 seconds)
2023-12-04 12:35:12 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net)
2023-12-04 12:39:49 +0100lottaquestions(~nick@2607:fa49:503d:b200:791c:1e35:f3fd:c3f3) (Remote host closed the connection)
2023-12-04 12:40:15 +0100lottaquestions(~nick@2607:fa49:503d:b200:2d55:64ae:c120:e947)
2023-12-04 12:45:34 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5)
2023-12-04 12:46:27 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655)
2023-12-04 12:51:14 +0100shriekingnoise(~shrieking@186.137.175.87)
2023-12-04 12:51:23 +0100danse-nr3(~danse@na-19-84-78.service.infuturo.it)
2023-12-04 12:55:53 +0100danse-nr3(~danse@na-19-84-78.service.infuturo.it) (Read error: Connection reset by peer)
2023-12-04 12:56:11 +0100danse-nr3(~danse@151.47.50.89)
2023-12-04 12:57:01 +0100__monty__(~toonn@user/toonn) (Ping timeout: 245 seconds)
2023-12-04 12:58:42 +0100__monty__(~toonn@user/toonn)
2023-12-04 13:00:04 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-04 13:03:08 +0100ritog(~ritog@45.112.243.193)
2023-12-04 13:03:38 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-04 13:04:00 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-04 13:05:07 +0100_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl)
2023-12-04 13:05:19 +0100Sciencentistguy7(~sciencent@hacksoc/ordinary-member)
2023-12-04 13:06:55 +0100lortabac(~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4)
2023-12-04 13:08:28 +0100Sciencentistguy(~sciencent@hacksoc/ordinary-member) (Ping timeout: 268 seconds)
2023-12-04 13:08:28 +0100Sciencentistguy7Sciencentistguy
2023-12-04 13:10:50 +0100zetef(~quassel@95.77.17.251) (Ping timeout: 260 seconds)
2023-12-04 13:11:43 +0100jjhoo(~jahakala@user/jjhoo) (Ping timeout: 255 seconds)
2023-12-04 13:14:32 +0100ritog(~ritog@45.112.243.193) (Quit: Leaving)
2023-12-04 13:15:52 +0100Tisoxin(~Ikosit@user/ikosit)
2023-12-04 13:18:41 +0100jjhoo(~jahakala@user/jjhoo)
2023-12-04 13:20:17 +0100 <Tisoxin> Hi! Is there a lens combinator (in the lens package) that allows me to do
2023-12-04 13:20:17 +0100 <Tisoxin> > [1, 2, 3] & ix 1 `cbr` \x -> Just (x+1)
2023-12-04 13:20:17 +0100 <Tisoxin> ⇒ Just [1, 3, 3]
2023-12-04 13:20:17 +0100 <Tisoxin> > [1, 2, 3] & ix 1 `cbr` \x -> Nothing
2023-12-04 13:20:17 +0100 <Tisoxin> ⇒ Nothing
2023-12-04 13:20:18 +0100 <Tisoxin> cbr is the lens combinator I'm searching
2023-12-04 13:20:18 +0100 <lambdabot> error:
2023-12-04 13:20:18 +0100 <lambdabot> • Variable not in scope:
2023-12-04 13:20:19 +0100 <lambdabot> cbr :: (m0 -> f0 m0) -> (a1 -> Maybe a1) -> t
2023-12-04 13:20:19 +0100 <lambdabot> error:
2023-12-04 13:20:19 +0100 <lambdabot> • Variable not in scope:
2023-12-04 13:20:20 +0100 <lambdabot> cbr :: (m0 -> f0 m0) -> (p0 -> Maybe a0) -> t
2023-12-04 13:21:11 +0100 <ncf> id?
2023-12-04 13:21:49 +0100 <ncf> > [1,2,3] & ix 1 `id` (\x -> Just (x+1))
2023-12-04 13:21:51 +0100 <lambdabot> Just [1,3,3]
2023-12-04 13:21:52 +0100 <ncf> > [1,2,3] & ix 1 `id` (\x -> Nothing)
2023-12-04 13:21:53 +0100 <lambdabot> Nothing
2023-12-04 13:22:36 +0100 <ncf> or if you want to pretend that lens doesn't use the van laarhoven encoding, (%%~) https://hackage.haskell.org/package/lens-5.2.3/docs/Control-Lens-Lens.html#v:-37--37--126-
2023-12-04 13:22:58 +0100 <ncf> (i think that's a good idea, actually!)
2023-12-04 13:23:23 +0100 <Tisoxin> ok thanks, I guess I should really once again take a look at how exactly lenses work
2023-12-04 13:23:29 +0100waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
2023-12-04 13:23:55 +0100 <Tisoxin> I also just now found traverseOf which should do the right thing as well™
2023-12-04 13:24:44 +0100 <Tisoxin> Thanks ncf!
2023-12-04 13:24:56 +0100 <ncf> what you're asking for is basically the "universal use case" for traversals; so much so that they're encoded that way: in the lens library, a Traversal s t a b is a polymorphic function (forall f. Applicative f => (a -> f b) -> s -> f t)
2023-12-04 13:26:06 +0100 <ncf> for an analogy, if you consider that the universal use case for natural numbers is to be able to recurse on them, i.e. given a function and an initial value, apply the function n times to the initial value, then you end up with the "Church encoding" for natural numbers, (forall a. (a -> a) -> a -> a)
2023-12-04 13:27:34 +0100 <Tisoxin> very interesting, I didn't now that this is how one can construct the church encoding of a type but it's very intuitive
2023-12-04 13:29:12 +0100 <dminuoso_> Tisoxin: I think what you're really after is just `at`
2023-12-04 13:29:34 +0100 <dminuoso_> Which captures writing/updating/deleting indexed elements via a lens.
2023-12-04 13:31:02 +0100 <Tisoxin> I don't think so. `at` only works for Maps and not for lists afaik
2023-12-04 13:32:11 +0100CiaoSen(~Jura@2a05:5800:2d9:1600:ca4b:d6ff:fec1:99da) (Ping timeout: 260 seconds)
2023-12-04 13:33:56 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 13:34:01 +0100 <dminuoso_> Ah. Mmm.
2023-12-04 13:34:20 +0100 <dminuoso_> Oh, I did read your initial question wrong too, you dont mean to delete with Nothing.
2023-12-04 13:36:47 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 13:37:01 +0100danse-nr3(~danse@151.47.50.89) (Ping timeout: 245 seconds)
2023-12-04 13:37:38 +0100 <dminuoso_> Tisoxin: To continue on ncf's points, a Lens then is just a (forall f. Functor f => (a -> f b) -> s -> f t) - and the rationale here is that instead of focusing on "multiple" points (where you have to combine the effects via Applicative), it focus only on a single thing.
2023-12-04 13:37:49 +0100 <dminuoso_> Which is why you only have Functor (since no combination of effects occur)
2023-12-04 13:37:51 +0100 <dminuoso_> > (1, 2) & _1 `id` (\x -> Just (x + 1))
2023-12-04 13:37:52 +0100 <lambdabot> Just (2,2)
2023-12-04 13:39:06 +0100 <Tisoxin> hm, ok; thanks
2023-12-04 13:39:27 +0100simendsjo(~user@84.209.170.3)
2023-12-04 13:41:09 +0100danse-nr3(~danse@151.47.50.89)
2023-12-04 13:41:13 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 13:43:24 +0100 <dminuoso_> % data Vec3 a b c = Vec3 a b c
2023-12-04 13:43:24 +0100 <yahb2> <no output>
2023-12-04 13:43:36 +0100 <dminuoso_> % traverseV3 f = \(Vec3 a b c) -> Vec3 <$> f a <*> f b <*> f c
2023-12-04 13:43:37 +0100 <yahb2> <no output>
2023-12-04 13:43:40 +0100 <dminuoso_> % l1 f = \(Vec3 a b c) -> (\x -> Vec3 x b c) <$> f a
2023-12-04 13:43:40 +0100 <yahb2> <no output>
2023-12-04 13:43:44 +0100 <dminuoso_> % l1 f = \(Vec3 a b c) -> (\x -> Vec3 x b c) <$> f a
2023-12-04 13:43:44 +0100 <yahb2> <no output>
2023-12-04 13:43:50 +0100 <dminuoso_> err that one should have been named l2.
2023-12-04 13:44:07 +0100 <dminuoso_> Tisoxin: ^- Do you see how Lens is a sort of degenerate traversal that doesnt run over the entire thing?
2023-12-04 13:44:51 +0100 <dminuoso_> % l1 f = \(Vec3 a b c) -> (\x -> Vec3 x b c) <$> f a
2023-12-04 13:44:51 +0100 <yahb2> <no output>
2023-12-04 13:44:54 +0100 <dminuoso_> % l2 f = \(Vec3 a b c) -> (\x -> Vec3 a x c) <$> f b
2023-12-04 13:44:55 +0100 <yahb2> <no output>
2023-12-04 13:51:08 +0100akegalj(~akegalj@78-1-167-210.adsl.net.t-com.hr)
2023-12-04 13:51:17 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 13:51:50 +0100 <Tisoxin> > Tisoxin: ^- Do you see how Lens is a sort of degenerate traversal that doesnt run over the entire thing?
2023-12-04 13:51:50 +0100 <Tisoxin> yes
2023-12-04 13:51:51 +0100 <lambdabot> <hint>:1:10: error: parse error on input ‘^-’
2023-12-04 13:55:29 +0100jespada(~jespada@cpc121308-nmal25-2-0-cust15.19-2.cable.virginm.net) (Read error: Connection reset by peer)
2023-12-04 13:55:32 +0100jespada_(~jespada@cpc121308-nmal25-2-0-cust15.19-2.cable.virginm.net)
2023-12-04 13:55:41 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: Textual IRC Client: www.textualapp.com)
2023-12-04 13:56:46 +0100azimut(~azimut@gateway/tor-sasl/azimut)
2023-12-04 13:57:13 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 13:58:04 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-04 13:59:26 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 14:03:18 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 14:09:40 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470)
2023-12-04 14:11:46 +0100zetef(~quassel@95.77.17.251)
2023-12-04 14:13:03 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 14:13:31 +0100[_](~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 268 seconds)
2023-12-04 14:16:15 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 14:16:29 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 14:17:03 +0100sawilagar(~sawilagar@user/sawilagar)
2023-12-04 14:17:27 +0100sawilagar(~sawilagar@user/sawilagar) (Remote host closed the connection)
2023-12-04 14:17:50 +0100sawilagar(~sawilagar@user/sawilagar)
2023-12-04 14:18:05 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 14:22:57 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 14:23:16 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 14:23:34 +0100rgh(~ritog@45.112.243.193)
2023-12-04 14:25:59 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 14:26:43 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 14:29:43 +0100pastly(~pastly@gateway/tor-sasl/pastly)
2023-12-04 14:35:44 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 14:36:26 +0100rghritog
2023-12-04 14:36:33 +0100ritogrito
2023-12-04 14:37:49 +0100CiaoSen(~Jura@2a05:5800:2d9:1600:ca4b:d6ff:fec1:99da)
2023-12-04 14:38:55 +0100iqubic(~avi@2601:602:9502:c70:7ce7:f8c:f1d2:dccf) (Ping timeout: 260 seconds)
2023-12-04 14:40:46 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 14:40:59 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 14:43:09 +0100 <haskellbridge> 12<B​enno Fünfstück> @djinn (a -> b) -> [a] -> [b]
2023-12-04 14:44:29 +0100 <ncf> can't djinn from the bridge
2023-12-04 14:44:38 +0100gabiruh(~gabiruh@vps19177.publiccloud.com.br) (Ping timeout: 260 seconds)
2023-12-04 14:46:37 +0100danse-nr3(~danse@151.47.50.89) (Read error: Connection reset by peer)
2023-12-04 14:47:26 +0100misterfish(~misterfis@87.215.131.102) (Ping timeout: 260 seconds)
2023-12-04 14:50:18 +0100 <haskellbridge> 12<B​enno Fünfstück> sad :( is there an online versoin of djinn somewhere
2023-12-04 14:51:49 +0100 <xerox> on irc
2023-12-04 14:52:06 +0100gabiruh(~gabiruh@vps19177.publiccloud.com.br)
2023-12-04 14:53:43 +0100phma(phma@2001:5b0:210d:4b88:db07:55ae:ef67:3fd5) (Read error: Connection reset by peer)
2023-12-04 14:54:05 +0100bennofs(~bennofs@141.76.100.206)
2023-12-04 14:54:06 +0100ft(~ft@p508dbe71.dip0.t-ipconnect.de) (Ping timeout: 245 seconds)
2023-12-04 14:54:31 +0100phma(~phma@host-67-44-208-166.hnremote.net)
2023-12-04 14:54:58 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 14:55:32 +0100 <probie> @djinn (a -> b) -> [a] -> [b]
2023-12-04 14:55:33 +0100 <lambdabot> Error: Undefined type []
2023-12-04 14:55:53 +0100ft(~ft@p4fc2a395.dip0.t-ipconnect.de)
2023-12-04 14:58:57 +0100danse-nr3(~danse@151.47.50.89)
2023-12-04 14:59:31 +0100 <ncf> https://www.hedonisticlearning.com/djinn/ ?
2023-12-04 15:01:48 +0100 <danse-nr3> interesting, looks like an alternative to hoogle
2023-12-04 15:02:34 +0100 <danse-nr3> oh, no, > Generate Haskell code from a type
2023-12-04 15:03:14 +0100Xyloes(~wyx@2400:dd01:103a:1012:5923:33ce:7857:fc04) (Quit: Konversation terminated!)
2023-12-04 15:04:37 +0100 <akegalj> I ran into augustss implementation of BASIC http://augustss.blogspot.com/search/label/BASIC but I can't figure out why line "10 GOSUB 1000" works? How can this be valid? Source is here https://hackage.haskell.org/package/BASIC-0.1.5.0/docs/src/Language-BASIC-Parser.html#getBASIC and its pretty short. How can number 10 come before GOSUB. What magic is this?
2023-12-04 15:06:00 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 15:06:29 +0100 <exarkun> akegalj: What would you say type of the numeric literal `10` is?
2023-12-04 15:08:50 +0100 <akegalj> exarkun: I can't even guess. I would guess it is Num a
2023-12-04 15:09:10 +0100 <exarkun> akegalj: What if, instead of `10`, that line had `f`? As in, `f GOSUB 1000`?
2023-12-04 15:09:13 +0100 <exarkun> What's the type of f?
2023-12-04 15:09:23 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 15:10:11 +0100 <akegalj> exarkun: f would be some function in this case as its bound to some type variable. But its not literal
2023-12-04 15:10:47 +0100 <exarkun> "f would be some function" -> indeed. I'm not sure what you mean by "its bound to some type variable".
2023-12-04 15:11:14 +0100danse-nr3(~danse@151.47.50.89) (Ping timeout: 260 seconds)
2023-12-04 15:11:43 +0100 <exarkun> How do you figure f would be a function just by looking at that expression?
2023-12-04 15:11:55 +0100 <akegalj> exarkun: ignore type variable part
2023-12-04 15:12:42 +0100 <akegalj> exarkun: its function becouse it takes two arguments, right ?
2023-12-04 15:12:56 +0100 <exarkun> Yea
2023-12-04 15:13:01 +0100 <akegalj> its applied to them by type aplication " "
2023-12-04 15:13:08 +0100 <exarkun> yep
2023-12-04 15:13:58 +0100 <akegalj> that doesn't make me less confused :D
2023-12-04 15:14:20 +0100 <akegalj> is 10 a function ?
2023-12-04 15:14:42 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 15:16:32 +0100 <exarkun> If `f x y` is function application to two arguments and the type checker accepts `10 x y` then ...?
2023-12-04 15:17:06 +0100 <akegalj> exarkun: which type checker? Haskells ?
2023-12-04 15:17:53 +0100bennofs(~bennofs@141.76.100.206) (Quit: Connection closed)
2023-12-04 15:18:24 +0100 <exarkun> akegalj: yea
2023-12-04 15:18:31 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 15:19:11 +0100danse-nr3(~danse@151.47.50.89)
2023-12-04 15:19:23 +0100 <exarkun> akegalj: We can narrow down the type a bit. It's not just a function, but a function of two arguments, and those arguments have particular types.
2023-12-04 15:20:19 +0100 <exarkun> Like, GOSUB is a constructor for GOTO
2023-12-04 15:21:23 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 260 seconds)
2023-12-04 15:21:25 +0100dcoutts_(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net)
2023-12-04 15:21:47 +0100 <exarkun> And we probably know something about its return type because the way you use this thing is with `runBASIC`' which accepts a value of `BASIC` (an alias for `Expr ()`)
2023-12-04 15:22:10 +0100 <exarkun> So given that, what's a narrower type for `f` in `f GOSUB 1000`?
2023-12-04 15:22:12 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 15:22:25 +0100 <akegalj> exarkun: Its Expr ()
2023-12-04 15:22:44 +0100thegeekinside(~thegeekin@189.141.65.247)
2023-12-04 15:22:59 +0100 <exarkun> `f GOSUB 1000` is, yea. How about `f` by itself?
2023-12-04 15:24:21 +0100Unicorn_Princess(~Unicorn_P@user/Unicorn-Princess/x-3540542)
2023-12-04 15:24:22 +0100 <akegalj> exarkun: I can't tell . Its f :: a -> b -> Expr ()
2023-12-04 15:24:35 +0100 <akegalj> exarkun: where is this Expr defined?
2023-12-04 15:24:59 +0100 <exarkun> Expr is in Types.hs
2023-12-04 15:25:26 +0100 <probie> https://hackage.haskell.org/package/BASIC-0.1.5.0/docs/src/Language-BASIC-Types.html
2023-12-04 15:25:38 +0100 <exarkun> `f :: a -> b -> Expr ()` is right but we can narrow it further. We saw GOSUB as a value for the first parameter, so we know `a` must be the type of GOSUB.
2023-12-04 15:26:38 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 15:27:14 +0100 <probie> exarkun: I think you mean of type `GOTO`. `data GOTO = GOTO | GOSUB deriving (Eq)`
2023-12-04 15:27:53 +0100 <akegalj> exarkun: yes, then is `f :: GOTO -> b -> Expr ()`
2023-12-04 15:28:15 +0100 <exarkun> sorry yea. I mean whatever type `GOSUB` is must be the same as `a`. so, indeed, GOTO.
2023-12-04 15:28:25 +0100 <akegalj> I guess this fits into `Cmd Integer Command [Expr a]` of the Expr type
2023-12-04 15:30:10 +0100040AADFUL(~nand@haasn.dev) (Killed (NickServ (GHOST command used by haasn!sid579015@id-579015.hampstead.irccloud.com)))
2023-12-04 15:30:28 +0100 <exarkun> akegalj: Yea, getting close
2023-12-04 15:30:30 +0100haasn`(~nand@haasn.dev)
2023-12-04 15:30:49 +0100idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1)
2023-12-04 15:30:50 +0100zetef(~quassel@95.77.17.251) (Ping timeout: 256 seconds)
2023-12-04 15:31:03 +0100haasn`(~nand@haasn.dev) (Remote host closed the connection)
2023-12-04 15:32:29 +0100 <byorgey> akegalj: In Haskell, what type is 10?
2023-12-04 15:32:42 +0100 <exarkun> So in, eg, the Func.hs example, we've got this do block full of similar things. Since these things return `Expr ()` and we use them in a `do` block, do we know something else about `Expr`?
2023-12-04 15:33:31 +0100 <danse-nr3> % :t 10 -- this byorgey?
2023-12-04 15:33:31 +0100 <yahb2> 10 -- this byorgey? :: Num a => a
2023-12-04 15:34:26 +0100 <cheater> if i have two types, Foo and Bar that take the same kind of parameters (say 5 int parameters), can i somehow make the constructor a variable when creating the value with the constructor? something like x 1 2 3 4 5
2023-12-04 15:35:06 +0100 <danse-nr3> yeah but maybe wrap the types in a product first
2023-12-04 15:35:14 +0100 <akegalj> exarkun: sorry, where is Func.hs?
2023-12-04 15:35:18 +0100 <exarkun> akegalj: https://hackage.haskell.org/package/BASIC-0.1.5.0/src/examples/Func.hs
2023-12-04 15:35:32 +0100 <exarkun> just an arbitrary but specific example of using the library
2023-12-04 15:36:03 +0100 <cheater> duh, put the constructor in a variable
2023-12-04 15:36:04 +0100 <exarkun> although it doesn't use GOSUB so maybe not the bet choice
2023-12-04 15:36:05 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 15:36:14 +0100billchenchina(~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe)
2023-12-04 15:36:17 +0100billchenchina(~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe) (Remote host closed the connection)
2023-12-04 15:36:36 +0100 <akegalj> exarkun: ... sec ... to check that
2023-12-04 15:36:58 +0100 <exarkun> Maybe https://hackage.haskell.org/package/BASIC-0.1.5.0/src/examples/HiLo.hs is closer to what you were looking at originally?
2023-12-04 15:37:17 +0100 <exarkun> oh yea, I think that's the same example as from the blog post
2023-12-04 15:37:22 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 15:37:57 +0100machinedgod(~machinedg@modemcable243.147-130-66.mc.videotron.ca)
2023-12-04 15:38:11 +0100 <akegalj> exarkun: yes, that's the same example
2023-12-04 15:40:09 +0100 <akegalj> exarkun: I think I am confused with "parsing" part from Language.BASIC.Parser . I ll try to play around and see if I can figure this out. Fortunately example is quite short but I guess my mind can't bend over this one
2023-12-04 15:40:25 +0100 <exarkun> akegalj: I think there's basically one more leap to make
2023-12-04 15:40:55 +0100 <exarkun> I haven't hinted at it much yet because I want to let you figure out the surprise :)
2023-12-04 15:41:02 +0100 <cheater> hm no that didn't work
2023-12-04 15:41:10 +0100 <cheater> the two constructors are from different types
2023-12-04 15:41:50 +0100 <exarkun> akegalj: You're on the right track thinking about `Cmd`. Keep thinking about that `f :: GOTO -> b -> Expr ()` type also.
2023-12-04 15:42:06 +0100 <exarkun> And pay attention to the instances that Parser.hs defines
2023-12-04 15:42:44 +0100 <akegalj> exarkun: thanks for hand holding, will play in repl to figure it out
2023-12-04 15:43:36 +0100 <exarkun> np, have fun
2023-12-04 15:46:09 +0100seeg123456(~seeg12345@64.176.64.83) (Quit: Gateway shutdown)
2023-12-04 15:46:45 +0100 <danse-nr3> maybe now we have more bandwidth cheater ... i was thinking that maybe i was wrong pointing to a product, could be a case for composition
2023-12-04 15:47:11 +0100 <cheater> think about it this way
2023-12-04 15:47:12 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 15:48:06 +0100 <cheater> data Foo = Foo Int deriving Show; data Bar = Bar Int deriving Show; if bool then show (Foo 2) else show (Bar 2)
2023-12-04 15:48:27 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-04 15:48:41 +0100 <cheater> i want this to be something like: let x = if bool then Foo else Bar; show (x 2)
2023-12-04 15:49:03 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 15:49:14 +0100 <danse-nr3> show $ if ?
2023-12-04 15:49:42 +0100 <danse-nr3> hum maybe that does not type check actually
2023-12-04 15:51:32 +0100 <danse-nr3> no it does not
2023-12-04 15:52:11 +0100 <cheater> yeah
2023-12-04 15:52:29 +0100 <danse-nr3> but `show` takes a constraint, i guess we should make an example with something else, as you probably do not want to use a class
2023-12-04 15:53:44 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 268 seconds)
2023-12-04 15:55:53 +0100seeg123456(~seeg12345@64.176.64.83)
2023-12-04 15:56:54 +0100simendsjo(~user@84.209.170.3) (Ping timeout: 252 seconds)
2023-12-04 15:57:52 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 15:58:46 +0100 <akegalj> exarkun: byorgey: aha, the whole trickery is to implement instances of functions over Num typeclasses . When I reread I saw byorgey simple question "what type is 10" :D
2023-12-04 16:00:58 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 16:01:06 +0100 <akegalj> do people tend to write DSLs using these tricks or is this not so common ?
2023-12-04 16:01:13 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 16:02:44 +0100 <exarkun> I think this style is a fun joke that would practically never be used for serious code
2023-12-04 16:04:17 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 16:05:09 +0100euleritian(~euleritia@77.22.252.56) (Ping timeout: 252 seconds)
2023-12-04 16:05:34 +0100euleritian(~euleritia@dynamic-002-247-248-235.2.247.pool.telefonica.de)
2023-12-04 16:05:43 +0100 <kuribas> The problem with overly polymorphic code is that it can often compile, but into something different than intended.
2023-12-04 16:06:07 +0100 <kuribas> Also function monad or Num instance is pretty hard to read.
2023-12-04 16:06:57 +0100 <danse-nr3> i find function applicative legit at least. Num instance... a bit more edgy
2023-12-04 16:07:40 +0100 <kuribas> Meh, 99% of obfuscated code examples are using the function applicative/monad.
2023-12-04 16:08:08 +0100 <kuribas> If you really want this, insert a Reader newtype to make it explicit.
2023-12-04 16:08:26 +0100 <exarkun> Also the Num instance in BASIC is trivially unlawful. It only provides fromInteger. And I'm not sure why the empty Eq and Show instances are there, but they have no implementation at all.
2023-12-04 16:08:51 +0100 <probie> exarkun: Once upon a time, Haskell required both `Eq` and `Show` for `Num`
2023-12-04 16:08:55 +0100 <exarkun> Could you implement the rest of them? I'm not sure. Probably not in a very meaningful or coherent way.
2023-12-04 16:09:01 +0100 <exarkun> probie: Ah
2023-12-04 16:09:54 +0100 <exarkun> akegalj: More concretely, the types say you can do `negate $ 10 GOTO 20` it will just crash at runtime if you try. Also, what could it even mean?
2023-12-04 16:10:15 +0100 <exarkun> I mean .. maybe `negate $ 10 GOTO 20` should be the same as `20 COMEFROM 10`? :) But in general it's nonsense.
2023-12-04 16:10:16 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 16:10:40 +0100 <exarkun> (actually 20 COMEFROM 10 probably equals 10 GOTO 20, maybe I meant 10 COMEFROM 20)
2023-12-04 16:10:43 +0100zetef(~quassel@95.77.17.251)
2023-12-04 16:13:08 +0100 <kuribas> exarkun: intercal?
2023-12-04 16:14:39 +0100 <exarkun> as legit a choice as BASIC!
2023-12-04 16:15:11 +0100 <exarkun> (well maybe not)
2023-12-04 16:15:14 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 16:15:19 +0100 <akegalj> exarkun: yes, I saw they are not lawful. Fun example no matter what
2023-12-04 16:15:25 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 16:20:43 +0100wib_jonas(~wib_jonas@business-37-191-60-209.business.broadband.hu)
2023-12-04 16:22:54 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl)
2023-12-04 16:25:27 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 16:25:56 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 16:35:17 +0100alp_(~alp@2001:861:e3d6:8f80:59a0:3738:2d56:41bc) (Ping timeout: 252 seconds)
2023-12-04 16:37:26 +0100alp_(~alp@2001:861:e3d6:8f80:c0c9:d001:c090:e9f8)
2023-12-04 16:43:58 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 16:44:40 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex) (Quit: = "")
2023-12-04 16:45:05 +0100iqubic(~avi@2601:602:9502:c70:3f43:b574:9cc8:e2f)
2023-12-04 16:48:16 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 16:50:34 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 16:51:10 +0100chomwitt(~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1) (Ping timeout: 246 seconds)
2023-12-04 16:53:16 +0100CiaoSen(~Jura@2a05:5800:2d9:1600:ca4b:d6ff:fec1:99da) (Ping timeout: 245 seconds)
2023-12-04 16:57:26 +0100zetef(~quassel@95.77.17.251) (Ping timeout: 245 seconds)
2023-12-04 16:58:41 +0100danse-nr3(~danse@151.47.50.89) (Ping timeout: 245 seconds)
2023-12-04 16:58:52 +0100danse-nr3(~danse@rm-19-41-115.service.infuturo.it)
2023-12-04 17:02:20 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 17:06:25 +0100machinedgod(~machinedg@modemcable243.147-130-66.mc.videotron.ca) (Remote host closed the connection)
2023-12-04 17:06:31 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 17:06:48 +0100notzmv(~zmv@user/notzmv)
2023-12-04 17:08:11 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 17:08:35 +0100zetef(~quassel@95.77.17.251)
2023-12-04 17:10:07 +0100 <iqubic> ski: I think you can use forall for existential qualification and fake heterogeneous lists.
2023-12-04 17:11:33 +0100 <iqubic> data Showable = forall s. Show s => S s
2023-12-04 17:12:04 +0100 <iqubic> And then you can have [Showable].
2023-12-04 17:12:34 +0100euleritian(~euleritia@dynamic-002-247-248-235.2.247.pool.telefonica.de) (Read error: Connection reset by peer)
2023-12-04 17:12:39 +0100 <iqubic> But the only thing you can do with the elements of that list is call the Show methods on them.
2023-12-04 17:12:51 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-04 17:13:08 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
2023-12-04 17:13:56 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-04 17:16:49 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 17:17:01 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 17:19:31 +0100akegalj(~akegalj@78-1-167-210.adsl.net.t-com.hr) (Ping timeout: 245 seconds)
2023-12-04 17:20:37 +0100 <byorgey> glguy: I did part 2 with a lazy recursively defined list, kind of ad-hoc though. I didn't figure out a way to formulate it as a scanr or anything. https://github.com/byorgey/AoC/blob/master/2023/04/04.hs#L49
2023-12-04 17:21:17 +0100 <glguy> byorgey: I think the benefit of scanr would have been lost by having to post-process the result with map (take 1)
2023-12-04 17:21:59 +0100 <byorgey> maybe so
2023-12-04 17:22:07 +0100 <xerox> nice sprinkling of >>>
2023-12-04 17:22:49 +0100 <byorgey> I always sprinkle >>> when solving programming challenges, but never use it in real projects =)
2023-12-04 17:22:55 +0100lortabac(~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4) (Quit: WeeChat 4.1.1)
2023-12-04 17:23:50 +0100 <danse-nr3> >>> considered harmful?
2023-12-04 17:23:53 +0100szkl(uid110435@id-110435.uxbridge.irccloud.com)
2023-12-04 17:24:11 +0100 <byorgey> not at all, just a style thing
2023-12-04 17:24:44 +0100 <xerox> my heat of the moment one was like this https://github.com/mrtnpaolo/advent-of-code-2023/blob/5e8feb7/execs/Day04.hs#L37-L42
2023-12-04 17:25:47 +0100 <byorgey> ah, nice
2023-12-04 17:26:43 +0100qqq(~qqq@92.43.167.61) (Quit: leaving)
2023-12-04 17:26:49 +0100 <xerox> wished there was an insertwith that also returns the possibly different eventually inserted value
2023-12-04 17:28:16 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 17:28:40 +0100 <byorgey> I feel like there must be a way to do that in one line with lens combinators.
2023-12-04 17:29:44 +0100 <ski> iqubic : yes, `[Showable]' encodes `[exists s. Show s *> s]'
2023-12-04 17:29:54 +0100 <ncf> i used löb https://github.com/ncfavier/aoc/blob/main/src/2023/Day04.hs
2023-12-04 17:29:58 +0100 <ski> "ut the only thing you can do with the elements of that list is call the Show methods on them." -- yes
2023-12-04 17:30:28 +0100 <xerox> löve that
2023-12-04 17:31:21 +0100 <byorgey> ncf: fantastic
2023-12-04 17:32:22 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 17:33:26 +0100 <ski> ncf : each one depends on the following `n' ?
2023-12-04 17:33:41 +0100 <ncf> yes
2023-12-04 17:33:58 +0100 <ski> sounds like a course-of-values recursion could also be used there, then
2023-12-04 17:35:09 +0100 <ncf> yes that's what glguy did
2023-12-04 17:35:15 +0100 <glguy> https://github.com/glguy/advent/blob/main/solutions/src/2023/04.hs#L57-L60
2023-12-04 17:35:23 +0100 <ski> mhm
2023-12-04 17:36:16 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 17:36:28 +0100dhil(~dhil@2001:8e0:2014:3100:5872:f936:bc7a:ceb8)
2023-12-04 17:36:50 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 17:36:59 +0100 <ncf> re lens, probably something with (<%~)
2023-12-04 17:37:51 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 256 seconds)
2023-12-04 17:38:01 +0100danse-nr3(~danse@rm-19-41-115.service.infuturo.it) (Ping timeout: 255 seconds)
2023-12-04 17:39:00 +0100 <cheater> what are those directories called ~/.ghcup/hls/1.2.3.4 ? i mean i know they're related to the hls, but how do i get rid of them? i have two, one's called 2.4.0.0 and the other called 1.9.0.0. i guess i don't need both, so how do i get rid of one? they're 2 gigs a pop
2023-12-04 17:39:47 +0100 <glguy> cheater: if you use "ghcup tui", you can uninstall things with the u key
2023-12-04 17:40:30 +0100 <ncf> insertWith' f k v = at k <%~ \x -> f v <$> x <|> Just v
2023-12-04 17:40:34 +0100 <glguy> While you're there you can uninstall both and upgrade to 2.5.0.0 if you want
2023-12-04 17:40:35 +0100 <cheater> is there any reason at all to have two different versions of hls?
2023-12-04 17:40:58 +0100 <haskellbridge> 14<m​aerwald> Yes
2023-12-04 17:41:18 +0100 <haskellbridge> 14<m​aerwald> Hls 2.5.0.0 doesn't support GHC 9.4.7 anymore
2023-12-04 17:41:45 +0100 <haskellbridge> 14<m​aerwald> If you use vscode, it can downgrade automatically if your project GHC is e.g. 9.4.7
2023-12-04 17:42:17 +0100 <cheater> https://i.imgur.com/S2VPCmH.png
2023-12-04 17:42:19 +0100 <glguy> are a lot of projects that use 9.4.7 not compatible with 9.4.8?
2023-12-04 17:42:28 +0100 <cheater> i honestly don't even use hls at all right now
2023-12-04 17:42:41 +0100 <cheater> i might look into setting it up with vim
2023-12-04 17:43:13 +0100 <glguy> I use it both with vim and vscode - it's pretty useful
2023-12-04 17:43:31 +0100juri_(~juri@faikvm.com) (Ping timeout: 255 seconds)
2023-12-04 17:43:42 +0100 <ncf> insertWith'' f k v = alterF (\x -> let x' = maybe (f v) v x in (x, Just x)) k
2023-12-04 17:44:29 +0100 <ncf> er
2023-12-04 17:44:37 +0100 <ncf> insertWith'' f k v = alterF (\x -> let x' = maybe v (f v) x in (x', Just x')) k
2023-12-04 17:44:48 +0100 <iqubic> I haven't updated to 9.6.2 because jle's advent-of-code-api fails to work with newer versions of transformers. I think it's something to do with liftIO not being re-exported.
2023-12-04 17:45:08 +0100 <iqubic> jle`: you might want to fix this.
2023-12-04 17:45:43 +0100Guest87(~Guest87@2409:11:1420:a600:fc27:c511:dd24:c407)
2023-12-04 17:46:23 +0100Guest87(~Guest87@2409:11:1420:a600:fc27:c511:dd24:c407) (Client Quit)
2023-12-04 17:46:32 +0100 <cheater> what is the haskellbridge bridging towards
2023-12-04 17:46:59 +0100 <yushyin> matrix
2023-12-04 17:47:57 +0100 <yushyin> the room name is haskell-irc, iirc
2023-12-04 17:48:38 +0100 <cheater> OK
2023-12-04 17:49:14 +0100chomwitt(~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1)
2023-12-04 17:49:19 +0100YoungFrog(~youngfrog@2a02:a03f:ca07:f900:1f5c:a3c6:297:feeb) (Ping timeout: 260 seconds)
2023-12-04 17:49:58 +0100 <geekosaur> yes
2023-12-04 17:50:25 +0100juri_(~juri@faikvm.com)
2023-12-04 17:50:57 +0100 <geekosaur> if you /whois haskellbridge it'll give you some more information
2023-12-04 17:51:21 +0100 <yushyin> nice
2023-12-04 17:51:24 +0100 <geekosaur> although there isn't enough room to list all the bridged channels and where they go
2023-12-04 17:53:23 +0100 <geekosaur> hm, didn't include matrix in that, should fix that
2023-12-04 17:53:59 +0100zetef(~quassel@95.77.17.251) (Ping timeout: 264 seconds)
2023-12-04 17:54:03 +0100 <cheater> geekosaur: the /whois doesn't tell me anything
2023-12-04 17:56:23 +0100 <ski> -!- ircname : Haskell matterbridge operated by geekosaur
2023-12-04 17:56:54 +0100 <geekosaur> it tells you the important part which is who to contact for more information
2023-12-04 17:56:57 +0100 <cheater> yeah i saw that
2023-12-04 17:57:03 +0100 <cheater> but i already knew that part
2023-12-04 17:57:07 +0100 <geekosaur> as I said, there isn;'t enough room (IRC limits) to really say more
2023-12-04 17:57:08 +0100 <cheater> since you're the one who told me about it
2023-12-04 17:57:10 +0100 <cheater> lol
2023-12-04 17:57:32 +0100 <cheater> try setting your ircname to "Haskell chat bridge https://tiny.co/blah"
2023-12-04 17:57:54 +0100YoungFrog(~youngfrog@2a02:a03f:ca07:f900:1f5c:a3c6:297:feeb)
2023-12-04 18:00:53 +0100TMA(tma@twin.jikos.cz)
2023-12-04 18:01:11 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 18:01:23 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 18:02:31 +0100 <trev> glguy: can you explain to me (a dummy) how your part 2 works? even printing out the accumulator each fold, i still can't grasp it :|
2023-12-04 18:02:31 +0100wib_jonas(~wib_jonas@business-37-191-60-209.business.broadband.hu) (Quit: Client closed)
2023-12-04 18:03:23 +0100 <glguy> trev: it's building up a list of how many total cards you get by playing one of each card in the list
2023-12-04 18:04:24 +0100 <glguy> so you start with: wins_on_card_1 : wins_on_card_2 : ... : []
2023-12-04 18:04:49 +0100 <glguy> the output in each position is how many cards one of that card turns into
2023-12-04 18:05:06 +0100idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
2023-12-04 18:05:15 +0100euandreh(~Thunderbi@189.6.18.26)
2023-12-04 18:05:17 +0100 <glguy> foldr replaces all of those : constructors in the input with a function
2023-12-04 18:05:43 +0100 <glguy> The function takes two things: the number of wins on the current card and the output list for all cards following it
2023-12-04 18:06:03 +0100 <glguy> It extends that output list by one element, that element is the number of cards this card will turn into
2023-12-04 18:06:07 +0100iqubic(~avi@2601:602:9502:c70:3f43:b574:9cc8:e2f) (Ping timeout: 260 seconds)
2023-12-04 18:07:00 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 18:07:53 +0100 <glguy> f wins_1 (f wins_2 (f wins_3 [])) ==> f wins_1 (f wins_2 [output_3]) ==> f wins_1 [output_2, output_3] ==> [output_1, output_2, output_3]
2023-12-04 18:08:02 +0100 <trev> i guess i don't even understand the first iteration of the fold - the accumulator is [] and then you prepend `1 + sum (take wins xs)` but that should just be 1
2023-12-04 18:08:04 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 18:08:16 +0100`2jt(~jtomas@90.162.208.36) (Ping timeout: 255 seconds)
2023-12-04 18:08:27 +0100 <glguy> The very last card in the list will necessarily have 0 wins on it
2023-12-04 18:08:46 +0100 <glguy> so you'll have: f 0 [] ==> 1 + sum (take 0 []) : [] ==> [1,]
2023-12-04 18:08:51 +0100 <glguy> s/,//
2023-12-04 18:09:19 +0100 <trev> ah so it's going backwards
2023-12-04 18:09:21 +0100 <glguy> so that last card doesn't turn into any more cards, when you play it you only play 1 card
2023-12-04 18:09:37 +0100coot(~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
2023-12-04 18:10:04 +0100AlexZenon(~alzenon@5.139.232.120) (Ping timeout: 256 seconds)
2023-12-04 18:10:21 +0100coot(~coot@89-69-206-216.dynamic.chello.pl)
2023-12-04 18:10:41 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe) (Remote host closed the connection)
2023-12-04 18:10:57 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe)
2023-12-04 18:11:24 +0100 <trev> thanks. genius solution
2023-12-04 18:12:46 +0100phma(~phma@host-67-44-208-166.hnremote.net) (Read error: Connection reset by peer)
2023-12-04 18:12:49 +0100fendor(~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c) (Remote host closed the connection)
2023-12-04 18:13:34 +0100phma(~phma@2001:5b0:2143:bdc8:5f21:c979:aa9:dd43)
2023-12-04 18:13:57 +0100 <trev> i confused myself since i'm doing it in OCaml which doesn't have tail recursion on foldr so i was using foldl and reversing the input -_-
2023-12-04 18:14:02 +0100YoungFrog(~youngfrog@2a02:a03f:ca07:f900:1f5c:a3c6:297:feeb) (Ping timeout: 256 seconds)
2023-12-04 18:14:17 +0100 <glguy> Oh, you could reverse and foldl like this just fine
2023-12-04 18:14:39 +0100 <trev> yeah, it works that way. i forgot about the rev and couldn't conceptualize it in my mind
2023-12-04 18:14:47 +0100 <glguy> ah, I see
2023-12-04 18:15:47 +0100YoungFrog(~youngfrog@2a02:a03f:ca07:f900:1f5c:a3c6:297:feeb)
2023-12-04 18:16:58 +0100 <ski> trev : "OCaml which doesn't have tail recursion on foldr" -- Haskell doesn't, either
2023-12-04 18:17:06 +0100AlexZenon(~alzenon@5.139.232.120)
2023-12-04 18:19:05 +0100iqubic(~avi@2601:602:9502:c70:dd03:78c7:a43f:a269)
2023-12-04 18:19:11 +0100 <trev> ski, oh then i have no idea why it wasn't working with foldr
2023-12-04 18:19:32 +0100 <ski> ?
2023-12-04 18:19:37 +0100coot(~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
2023-12-04 18:20:52 +0100 <trev> ski: it just doesn't work correctly with fold_right in OCaml. No idea why right now
2023-12-04 18:21:29 +0100 <ski> you mean you don't get the right result ?
2023-12-04 18:21:53 +0100 <trev> yep
2023-12-04 18:22:52 +0100Square2(~Square4@user/square) (Ping timeout: 246 seconds)
2023-12-04 18:23:00 +0100 <ski> hm, i don't see why it shouldn't
2023-12-04 18:23:11 +0100 <ski> val fold_right : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b
2023-12-04 18:23:45 +0100 <ski> argument ordering is slightly different, but shouldn't be a problem. it's also not incremental, but that shouldn't be needed here, afaiui
2023-12-04 18:25:15 +0100 <trev> i'll put the two side by side in a paste
2023-12-04 18:26:05 +0100 <trev> https://paste.tomsmeding.com/rqjAOycf
2023-12-04 18:26:36 +0100 <trev> perhaps i've been staring at it too long
2023-12-04 18:26:46 +0100kuribas(~user@ip-188-118-57-242.reverse.destiny.be) (Remote host closed the connection)
2023-12-04 18:27:06 +0100 <idgaen> in ocaml foldr can product stack overflow enough easily. But in haskell there is not this issue (there is no stack, for saying it merely).
2023-12-04 18:27:28 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 18:27:42 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 18:28:26 +0100 <trev> i don't get a stack overflow, just the wrong answer
2023-12-04 18:28:46 +0100 <idgaen> weird
2023-12-04 18:28:57 +0100albet70(~xxx@2400:8902::f03c:92ff:fe60:98d8)
2023-12-04 18:29:26 +0100 <idgaen> possibly an arithmetic overflow then
2023-12-04 18:29:46 +0100 <trev> that is possible cause the output is a huge negative number
2023-12-04 18:30:47 +0100 <glguy> trev: aren't the arguments to fold_right in the wrong order in your paste?
2023-12-04 18:31:44 +0100 <trev> glguy: left and right have swapped args in ocaml
2023-12-04 18:32:16 +0100 <glguy> well your code doesn't match what ski pasted
2023-12-04 18:32:31 +0100 <glguy> if the type signature ski pasted is correct, then your code has the arguments in the wrong order
2023-12-04 18:32:48 +0100 <trev> oh wow you're right
2023-12-04 18:32:53 +0100 <idgaen> I'd rather like the haskell arguments order for fold… each time I tried to play with ocaml I was confused
2023-12-04 18:33:15 +0100 <trev> that is super annoying!
2023-12-04 18:33:28 +0100 <trev> now my |> won't work
2023-12-04 18:33:46 +0100 <glguy> good, because that direction of composition is always so awkward
2023-12-04 18:33:48 +0100 <glguy> :-p
2023-12-04 18:33:53 +0100 <ncf> how does it typecheck if the arguments are swapped?
2023-12-04 18:34:03 +0100 <trev> acc and [] are the same type
2023-12-04 18:34:10 +0100 <trev> int list
2023-12-04 18:34:13 +0100 <ski> idgaen : there is a stack, just not in quite the ordinary sense. also GHC will extend the stack on overflow, now, rather than crashing
2023-12-04 18:34:22 +0100loonycyborg(loonycybor@wesnoth/developer/loonycyborg) (Remote host closed the connection)
2023-12-04 18:34:42 +0100 <glguy> There goes the illusion of types helping with program correctness :-S
2023-12-04 18:34:43 +0100 <idgaen> ski: ok, thanks you for this information.
2023-12-04 18:34:48 +0100 <ncf> oh right, you're building a list
2023-12-04 18:35:02 +0100 <ski> trev : no, `fold_left' is the same as in Haskell
2023-12-04 18:35:08 +0100 <ski> val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
2023-12-04 18:35:31 +0100 <ski> (and yea, i just copied these from `ocaml')
2023-12-04 18:35:52 +0100 <trev> ski i meant in ocaml's fold_left and fold_right swap the two last args
2023-12-04 18:36:04 +0100 <trev> and also the args of the accumulator :\
2023-12-04 18:36:07 +0100 <ski> idgaen : part of the point of the OCaml ordering, is to be able to say `fold_right o fold_right' or `fold_left o fold_left'
2023-12-04 18:36:50 +0100 <ski> .. and SML has yet another ordering
2023-12-04 18:36:56 +0100 <trev> what does the `o` mean ski?
2023-12-04 18:37:12 +0100 <ski> function composition
2023-12-04 18:37:26 +0100 <idgaen> ski: oh! It is for composition of function. I have never noticed
2023-12-04 18:37:29 +0100 <ski> val foldr : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b
2023-12-04 18:37:32 +0100 <ski> val foldl : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b
2023-12-04 18:37:47 +0100 <ski> in SML, they preferred to keep the signatures of both exactly the same
2023-12-04 18:37:55 +0100 <ski> (and uncurried the callback)
2023-12-04 18:39:27 +0100 <ski> @type let foldl :: (s -> a -> s) -> s -> [a] -> s; foldl = Prelude.foldl in foldl . foldl
2023-12-04 18:39:28 +0100 <lambdabot> (s -> a -> s) -> s -> [[a]] -> s
2023-12-04 18:39:30 +0100 <ski> vs.
2023-12-04 18:39:32 +0100 <ski> @type let foldr :: (a -> s -> s) -> s -> [a] -> s; foldr = Prelude.foldr in foldr . flip . foldr
2023-12-04 18:39:33 +0100 <lambdabot> (a -> s -> s) -> s -> [[a]] -> s
2023-12-04 18:39:42 +0100 <ski> that `flip' isn't needed in the OCaml version
2023-12-04 18:39:56 +0100 <EvanR> last night I finally realized this "foldr" solution, and it's very fast and sensible. But now I'm wondering if foldl' would be even faster xD
2023-12-04 18:40:34 +0100 <EvanR> also discussing the detailed solution the day of?
2023-12-04 18:41:11 +0100 <ski> @type map . map
2023-12-04 18:41:16 +0100 <lambdabot> (a -> b) -> [[a]] -> [[b]]
2023-12-04 18:41:18 +0100 <ski> @type zipWith . zipWith
2023-12-04 18:41:19 +0100 <idgaen> I used to use foldl' unless if lazyness or I build a list. In these last case foldr is better, I feel.
2023-12-04 18:41:19 +0100 <lambdabot> (a -> b -> c) -> [[a]] -> [[b]] -> [[c]]
2023-12-04 18:41:38 +0100 <EvanR> you can build a list backwards with foldl' very fast xD
2023-12-04 18:42:00 +0100 <EvanR> i.e. what is required here
2023-12-04 18:42:31 +0100 <idgaen> depends I you want keep the original order.
2023-12-04 18:42:34 +0100 <ski> > foldl' (flip (:)) [] [0 ..] -- very fast infinite list building
2023-12-04 18:42:40 +0100 <lambdabot> mueval-core: Time limit exceeded
2023-12-04 18:43:00 +0100 <EvanR> laziness doesn't help with memory usage in this one
2023-12-04 18:44:17 +0100 <EvanR> if you build list L backwards, it is in the right order still
2023-12-04 18:44:21 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-04 18:44:31 +0100 <EvanR> i.e. start with the last element and prepend second to last element, etc
2023-12-04 18:44:53 +0100econo_(uid147250@id-147250.tinside.irccloud.com)
2023-12-04 18:47:48 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 18:48:17 +0100tzh(~tzh@c-71-193-181-0.hsd1.or.comcast.net)
2023-12-04 18:49:11 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 18:52:34 +0100CrunchyFlakes(~CrunchyFl@ip92348280.dynamic.kabel-deutschland.de) (Ping timeout: 276 seconds)
2023-12-04 18:52:42 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 18:53:42 +0100CrunchyFlakes(~CrunchyFl@ip92348280.dynamic.kabel-deutschland.de)
2023-12-04 18:53:44 +0100 <EvanR> I just tried and it has no effect on runtime, maybe because everything else in the program is much slower, maybe because optimizer thinks they are equivalent
2023-12-04 18:53:53 +0100 <EvanR> or both
2023-12-04 18:54:35 +0100Square(~Square@user/square)
2023-12-04 18:54:37 +0100 <EvanR> but the foldl' version has simpler code, and I'd like to ask for input on beautifying my foldr code, but only if the spoiler period is over
2023-12-04 18:54:48 +0100pavonia(~user@user/siracusa) (Quit: Bye!)
2023-12-04 18:55:25 +0100 <EvanR> or by the time I get back from the DMV I'll have figured it out xD
2023-12-04 18:56:08 +0100 <trev> my bad for bringing up the solution so early. it was eating at me
2023-12-04 18:57:27 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 19:00:01 +0100 <idgaen> trev: I'm happy, I joined too lately for looking at your solution ;)
2023-12-04 19:02:07 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 19:02:08 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
2023-12-04 19:02:08 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 19:02:56 +0100adium(adium@user/adium) (Excess Flood)
2023-12-04 19:03:01 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-04 19:04:59 +0100adium(adium@user/adium)
2023-12-04 19:09:32 +0100akegalj(~akegalj@141-136-219-144.dsl.iskon.hr)
2023-12-04 19:10:42 +0100AlexNoo_(~AlexNoo@5.139.232.120)
2023-12-04 19:12:26 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 19:13:14 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 19:13:58 +0100AlexNoo(~AlexNoo@5.139.232.120) (Ping timeout: 255 seconds)
2023-12-04 19:22:22 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
2023-12-04 19:22:31 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-04 19:23:10 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 19:23:25 +0100edr(~edr@user/edr)
2023-12-04 19:27:39 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-04 19:28:44 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com)
2023-12-04 19:36:14 +0100bwe(~bwe@2a01:4f8:1c1c:4878::2) (Quit: Lost terminal)
2023-12-04 19:42:26 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 245 seconds)
2023-12-04 19:43:05 +0100euleritian(~euleritia@dynamic-002-247-248-235.2.247.pool.telefonica.de)
2023-12-04 19:43:34 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 256 seconds)
2023-12-04 19:50:10 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-04 19:50:19 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 19:51:22 +0100gentauro(~gentauro@user/gentauro) (Read error: Connection reset by peer)
2023-12-04 19:52:58 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 19:54:55 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 255 seconds)
2023-12-04 19:56:40 +0100gentauro(~gentauro@user/gentauro)
2023-12-04 19:56:42 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 19:57:41 +0100akegalj(~akegalj@141-136-219-144.dsl.iskon.hr) (Ping timeout: 252 seconds)
2023-12-04 19:59:14 +0100AlexNoo_AlexNoo
2023-12-04 20:00:40 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 20:01:06 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 20:02:11 +0100 <EvanR> also if you're ok with foldr it seems this becomes one of the situations you can count on one hand where foldl not-prime would at least not be wrong
2023-12-04 20:07:49 +0100rosco(~rosco@175.136.158.171) (Quit: Lost terminal)
2023-12-04 20:11:04 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 20:11:06 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 20:14:45 +0100chele(~chele@user/chele) (Remote host closed the connection)
2023-12-04 20:16:15 +0100 <monochrom> Usually, if you use foldl to build a list and then reverse it, you can use foldr to build a diff list instead.
2023-12-04 20:16:52 +0100 <EvanR> no need to reverse in this case
2023-12-04 20:17:33 +0100euandreh(~Thunderbi@189.6.18.26) (Remote host closed the connection)
2023-12-04 20:17:37 +0100 <glguy> EvanR: if you're worried about spoilers just put the code in a pastebin instead of directly into channel
2023-12-04 20:17:45 +0100 <EvanR> oh
2023-12-04 20:18:12 +0100 <EvanR> also I tried a 3rd way and the runtime is still not affected
2023-12-04 20:18:16 +0100 <monochrom> Yeah if you say "this paste contains spoilers" then people can choose to not click.
2023-12-04 20:19:17 +0100euandreh(~Thunderbi@189.6.18.26)
2023-12-04 20:19:44 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe) (Remote host closed the connection)
2023-12-04 20:20:45 +0100AlexNoo_(~AlexNoo@5.139.232.120)
2023-12-04 20:20:59 +0100acidjnk_new(~acidjnk@p200300d6e72b930718d4047c6b088385.dip0.t-ipconnect.de)
2023-12-04 20:21:17 +0100Incredia_(~Incredia@176.254.244.83)
2023-12-04 20:21:41 +0100alp_(~alp@2001:861:e3d6:8f80:c0c9:d001:c090:e9f8) (Ping timeout: 240 seconds)
2023-12-04 20:22:11 +0100drewjose6(~drewjose@129.154.40.88)
2023-12-04 20:22:33 +0100g__(g@libera/staff/glguy)
2023-12-04 20:22:34 +0100WzC(~Frank@77-162-168-71.fixed.kpn.net)
2023-12-04 20:22:52 +0100mniip_(mniip@libera/staff/mniip)
2023-12-04 20:22:56 +0100g(g@libera/staff/glguy) (Killed (cadmium.libera.chat (Nickname regained by services)))
2023-12-04 20:22:56 +0100g__g
2023-12-04 20:22:57 +0100caasih_(sid13241@id-13241.ilkley.irccloud.com)
2023-12-04 20:22:57 +0100yandere_(sid467876@id-467876.ilkley.irccloud.com)
2023-12-04 20:22:57 +0100lally_(sid388228@id-388228.uxbridge.irccloud.com)
2023-12-04 20:22:58 +0100totbwf_(sid402332@id-402332.uxbridge.irccloud.com)
2023-12-04 20:23:00 +0100_0xa_(~user@2001:19f0:5001:2ba8:5400:1ff:feda:88fc)
2023-12-04 20:23:01 +0100meooow_(~meooow@2400:6180:100:d0::ad9:e001)
2023-12-04 20:23:02 +0100dsal_(sid13060@id-13060.lymington.irccloud.com)
2023-12-04 20:23:04 +0100Taneb0(~Taneb@runciman.hacksoc.org)
2023-12-04 20:23:04 +0100jackdk_(sid373013@cssa/jackdk)
2023-12-04 20:23:05 +0100hovsater_(sid499516@id-499516.lymington.irccloud.com)
2023-12-04 20:23:07 +0100smalltalkman_(uid545680@id-545680.hampstead.irccloud.com)
2023-12-04 20:23:08 +0100Fangs_(sid141280@id-141280.hampstead.irccloud.com)
2023-12-04 20:23:10 +0100nurupo_(~nurupo.ga@user/nurupo)
2023-12-04 20:23:13 +0100delyan__(sid523379@id-523379.hampstead.irccloud.com)
2023-12-04 20:23:14 +0100dysfigured(~dfg@dfg.rocks)
2023-12-04 20:23:14 +0100kaskal-(~kaskal@2001:4bb8:2d2:5771:29a:c01c:fefc:78b5)
2023-12-04 20:23:19 +0100sa_(sid1055@id-1055.tinside.irccloud.com)
2023-12-04 20:23:20 +0100jmtd(jon@dow.land)
2023-12-04 20:23:23 +0100bw____(sid2730@id-2730.ilkley.irccloud.com)
2023-12-04 20:23:24 +0100urdh_(~urdh@user/urdh)
2023-12-04 20:23:38 +0100innegatives_(sid621315@id-621315.tinside.irccloud.com)
2023-12-04 20:24:57 +0100np(~nerdypepp@user/nerdypepper)
2023-12-04 20:25:26 +0100abrar_(~abrar@pool-108-52-90-30.phlapa.fios.verizon.net)
2023-12-04 20:25:33 +0100farn_(~farn@2a03:4000:7:3cd:d4ab:85ff:feeb:f505)
2023-12-04 20:25:33 +0100aosync_(~alews@141.94.77.100)
2023-12-04 20:25:36 +0100ezzieygu1wuf(~Unknown@user/ezzieyguywuf)
2023-12-04 20:25:37 +0100shane_(~shane@ana.rch.ist)
2023-12-04 20:25:40 +0100Taneb(~Taneb@runciman.hacksoc.org) (Ping timeout: 252 seconds)
2023-12-04 20:25:41 +0100yandere(sid467876@id-467876.ilkley.irccloud.com) (Ping timeout: 252 seconds)
2023-12-04 20:25:41 +0100Jon(jon@dow.land) (Ping timeout: 252 seconds)
2023-12-04 20:25:41 +0100smalltalkman(uid545680@id-545680.hampstead.irccloud.com) (Ping timeout: 252 seconds)
2023-12-04 20:25:41 +0100jackdk(sid373013@cssa/jackdk) (Ping timeout: 252 seconds)
2023-12-04 20:25:41 +0100totbwf(sid402332@id-402332.uxbridge.irccloud.com) (Ping timeout: 252 seconds)
2023-12-04 20:25:41 +0100hovsater(sid499516@id-499516.lymington.irccloud.com) (Ping timeout: 252 seconds)
2023-12-04 20:25:41 +0100bw___(sid2730@id-2730.ilkley.irccloud.com) (Ping timeout: 252 seconds)
2023-12-04 20:25:41 +0100meooow(~meooow@2400:6180:100:d0::ad9:e001) (Ping timeout: 252 seconds)
2023-12-04 20:25:41 +0100lally(sid388228@id-388228.uxbridge.irccloud.com) (Ping timeout: 252 seconds)
2023-12-04 20:25:41 +0100Incredia(~Incredia@176.254.244.83) (Ping timeout: 252 seconds)
2023-12-04 20:25:41 +0100abrar(~abrar@pool-108-52-90-30.phlapa.fios.verizon.net) (Ping timeout: 252 seconds)
2023-12-04 20:25:41 +0100nerdypepper(~nerdypepp@user/nerdypepper) (Ping timeout: 252 seconds)
2023-12-04 20:25:41 +0100farn(~farn@2a03:4000:7:3cd:d4ab:85ff:feeb:f505) (Ping timeout: 252 seconds)
2023-12-04 20:25:41 +0100_0xa(~user@user/0xa/x-3134607) (Ping timeout: 252 seconds)
2023-12-04 20:25:41 +0100delyan_(sid523379@id-523379.hampstead.irccloud.com) (Ping timeout: 252 seconds)
2023-12-04 20:25:42 +0100krj(~krjst@2604:a880:800:c1::16b:8001) (Ping timeout: 252 seconds)
2023-12-04 20:25:42 +0100aosync(~alews@user/aws) (Ping timeout: 252 seconds)
2023-12-04 20:25:42 +0100kaskal(~kaskal@89.144.222.250) (Ping timeout: 252 seconds)
2023-12-04 20:25:42 +0100caasih(sid13241@id-13241.ilkley.irccloud.com) (Ping timeout: 252 seconds)
2023-12-04 20:25:42 +0100hughjfchen(~hughjfche@vmi556545.contaboserver.net) (Ping timeout: 252 seconds)
2023-12-04 20:25:42 +0100edr(~edr@user/edr) (Ping timeout: 252 seconds)
2023-12-04 20:25:42 +0100AlexNoo(~AlexNoo@5.139.232.120) (Ping timeout: 252 seconds)
2023-12-04 20:25:42 +0100infinity0(~infinity0@pwned.gg) (Ping timeout: 252 seconds)
2023-12-04 20:25:42 +0100acidjnk(~acidjnk@p200300d6e72b9356246dd2d07051f792.dip0.t-ipconnect.de) (Ping timeout: 252 seconds)
2023-12-04 20:25:42 +0100Lycurgus(~georg@user/Lycurgus) (Ping timeout: 252 seconds)
2023-12-04 20:25:42 +0100urdh(~urdh@user/urdh) (Ping timeout: 252 seconds)
2023-12-04 20:25:42 +0100cln_(cln@wtf.cx) (Ping timeout: 252 seconds)
2023-12-04 20:25:43 +0100Fangs(sid141280@id-141280.hampstead.irccloud.com) (Ping timeout: 252 seconds)
2023-12-04 20:25:43 +0100dsal(sid13060@id-13060.lymington.irccloud.com) (Ping timeout: 252 seconds)
2023-12-04 20:25:43 +0100ezzieyguywuf(~Unknown@user/ezzieyguywuf) (Ping timeout: 252 seconds)
2023-12-04 20:25:43 +0100titibandit(~titibandi@user/titibandit) (Ping timeout: 252 seconds)
2023-12-04 20:25:43 +0100nurupo(~nurupo.ga@user/nurupo) (Ping timeout: 252 seconds)
2023-12-04 20:25:43 +0100ski(~ski@remote11.chalmers.se) (Ping timeout: 252 seconds)
2023-12-04 20:25:43 +0100shane(~shane@ana.rch.ist) (Ping timeout: 252 seconds)
2023-12-04 20:25:43 +0100yushyin(XznNkBgf65@karif.server-speed.net) (Ping timeout: 252 seconds)
2023-12-04 20:25:43 +0100haveo(~weechat@pacamara.iuwt.fr) (Ping timeout: 252 seconds)
2023-12-04 20:25:43 +0100innegatives(sid621315@id-621315.tinside.irccloud.com) (Ping timeout: 252 seconds)
2023-12-04 20:25:44 +0100drewjose(~drewjose@129.154.40.88) (Ping timeout: 252 seconds)
2023-12-04 20:25:44 +0100sa(sid1055@id-1055.tinside.irccloud.com) (Ping timeout: 252 seconds)
2023-12-04 20:25:44 +0100Noinia(~Frank@77-162-168-71.fixed.kpn.net) (Ping timeout: 252 seconds)
2023-12-04 20:25:44 +0100dfg(~dfg@user/dfg) (Ping timeout: 252 seconds)
2023-12-04 20:25:44 +0100dhil(~dhil@2001:8e0:2014:3100:5872:f936:bc7a:ceb8) (Ping timeout: 252 seconds)
2023-12-04 20:25:44 +0100lally_lally
2023-12-04 20:25:44 +0100jackdk_jackdk
2023-12-04 20:25:45 +0100smalltalkman_smalltalkman
2023-12-04 20:25:45 +0100caasih_caasih
2023-12-04 20:25:45 +0100hovsater_hovsater
2023-12-04 20:25:45 +0100Fangs_Fangs
2023-12-04 20:25:45 +0100totbwf_totbwf
2023-12-04 20:25:45 +0100yandere_yandere
2023-12-04 20:25:45 +0100delyan__delyan_
2023-12-04 20:25:45 +0100urdh_urdh
2023-12-04 20:25:45 +0100drewjose6drewjose
2023-12-04 20:25:45 +0100dsal_dsal
2023-12-04 20:25:46 +0100hughjfch1(~hughjfche@vmi556545.contaboserver.net)
2023-12-04 20:25:49 +0100sa_sa
2023-12-04 20:25:50 +0100ski(~ski@remote11.chalmers.se)
2023-12-04 20:25:58 +0100Lycurgus(~georg@li1192-118.members.linode.com)
2023-12-04 20:25:58 +0100Lycurgus(~georg@li1192-118.members.linode.com) (Changing host)
2023-12-04 20:25:58 +0100Lycurgus(~georg@user/Lycurgus)
2023-12-04 20:25:59 +0100haveo(~weechat@pacamara.iuwt.fr)
2023-12-04 20:26:01 +0100cln_(cln@wtf.cx)
2023-12-04 20:26:10 +0100titibandit(~titibandi@user/titibandit)
2023-12-04 20:26:18 +0100krasjet(~krjst@2604:a880:800:c1::16b:8001)
2023-12-04 20:26:32 +0100mniip(mniip@libera/staff/mniip) (Read error: Connection reset by peer)
2023-12-04 20:27:00 +0100dhil(~dhil@2001:8e0:2014:3100:5872:f936:bc7a:ceb8)
2023-12-04 20:27:16 +0100nurupo_nurupo
2023-12-04 20:27:32 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 20:28:32 +0100infinity0(~infinity0@pwned.gg)
2023-12-04 20:29:11 +0100mc47(~mc47@xmonad/TheMC47)
2023-12-04 20:30:41 +0100cfricke(~cfricke@user/cfricke) (Quit: WeeChat 4.0.5)
2023-12-04 20:31:20 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 20:32:09 +0100coot(~coot@89-69-206-216.dynamic.chello.pl)
2023-12-04 20:32:34 +0100rito(~ritog@45.112.243.193) (Quit: Leaving)
2023-12-04 20:32:52 +0100ritog(~ritog@45.112.243.193)
2023-12-04 20:34:43 +0100rito(~ritog@45.112.243.193)
2023-12-04 20:35:15 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c)
2023-12-04 20:35:34 +0100ritog(~ritog@45.112.243.193) (Client Quit)
2023-12-04 20:35:34 +0100rito(~ritog@45.112.243.193) (Remote host closed the connection)
2023-12-04 20:35:36 +0100JeremyB99(~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer)
2023-12-04 20:37:13 +0100coot(~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
2023-12-04 20:37:27 +0100coot(~coot@89-69-206-216.dynamic.chello.pl)
2023-12-04 20:37:33 +0100yushyin(sJ30bcriGA@mail.karif.server-speed.net)
2023-12-04 20:39:46 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl)
2023-12-04 20:40:28 +0100oo_miguel(~Thunderbi@78-11-179-96.static.ip.netia.com.pl) (Ping timeout: 276 seconds)
2023-12-04 20:41:03 +0100bwe(~bwe@2a01:4f8:1c1c:4878::2)
2023-12-04 20:42:12 +0100bwe_(~bwe@2a01:4f8:1c1c:4878::2)
2023-12-04 20:42:59 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-04 20:45:30 +0100JeremyB99(~JeremyB99@208.64.173.6)
2023-12-04 20:47:01 +0100bwe_(~bwe@2a01:4f8:1c1c:4878::2) (Client Quit)
2023-12-04 20:47:06 +0100alp_(~alp@2001:861:e3d6:8f80:9ca3:38ae:c1a8:63c1)
2023-12-04 20:47:15 +0100bwe(~bwe@2a01:4f8:1c1c:4878::2) (Remote host closed the connection)
2023-12-04 20:47:32 +0100bwe(~bwe@2a01:4f8:1c1c:4878::2)
2023-12-04 20:47:59 +0100bwe(~bwe@2a01:4f8:1c1c:4878::2) (Client Quit)
2023-12-04 20:49:06 +0100bwe(~bwe@2a01:4f8:1c1c:4878::2)
2023-12-04 20:49:31 +0100bwe(~bwe@2a01:4f8:1c1c:4878::2) (Client Quit)
2023-12-04 20:50:40 +0100bwe(~bwe@2a01:4f8:1c1c:4878::2)
2023-12-04 20:52:26 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-04 20:53:37 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d)
2023-12-04 20:56:05 +0100dcoutts_(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 252 seconds)
2023-12-04 20:56:46 +0100Feuermagier_(~Feuermagi@user/feuermagier)
2023-12-04 20:56:47 +0100FeuermagierGuest6842
2023-12-04 20:56:47 +0100Guest6842(~Feuermagi@user/feuermagier) (Killed (tungsten.libera.chat (Nickname regained by services)))
2023-12-04 20:56:47 +0100Feuermagier_Feuermagier
2023-12-04 20:57:42 +0100alexherbo2(~alexherbo@2a02-8440-3341-75a8-58d4-3b45-b569-2dca.rev.sfr.net)
2023-12-04 21:01:16 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) (Remote host closed the connection)
2023-12-04 21:01:29 +0100bwe(~bwe@2a01:4f8:1c1c:4878::2) (Quit: Lost terminal)
2023-12-04 21:01:43 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d)
2023-12-04 21:02:04 +0100bwe(~bwe@2a01:4f8:1c1c:4878::2)
2023-12-04 21:03:51 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com)
2023-12-04 21:03:51 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
2023-12-04 21:03:51 +0100wroathe(~wroathe@user/wroathe)
2023-12-04 21:07:54 +0100AlexNoo_AlexNoo
2023-12-04 21:11:51 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) (Remote host closed the connection)
2023-12-04 21:12:32 +0100coot(~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
2023-12-04 21:12:46 +0100coot(~coot@89-69-206-216.dynamic.chello.pl)
2023-12-04 21:16:14 +0100bwe(~bwe@2a01:4f8:1c1c:4878::2) (Quit: Lost terminal)
2023-12-04 21:17:54 +0100bwe(~bwe@2a01:4f8:1c1c:4878::2)
2023-12-04 21:18:29 +0100bwe(~bwe@2a01:4f8:1c1c:4878::2) (Remote host closed the connection)
2023-12-04 21:18:48 +0100bwe(~bwe@2a01:4f8:1c1c:4878::2)
2023-12-04 21:19:36 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d)
2023-12-04 21:21:59 +0100Taneb0Taneb
2023-12-04 21:25:52 +0100kassouni(~textual@2601:646:401:6c30:5dd8:64ca:fd4d:e39b)
2023-12-04 21:26:00 +0100trev(~trev@user/trev) (Quit: trev)
2023-12-04 21:27:40 +0100wroathe(~wroathe@user/wroathe) (Ping timeout: 246 seconds)
2023-12-04 21:29:48 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) (Remote host closed the connection)
2023-12-04 21:32:52 +0100coot(~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
2023-12-04 21:33:07 +0100coot(~coot@89-69-206-216.dynamic.chello.pl)
2023-12-04 21:37:29 +0100opus(~nil@user/opus) (Quit: bye)
2023-12-04 21:37:29 +0100pedant(~who@user/pedant) (Quit: bye)
2023-12-04 21:37:30 +0100anderson(~anderson@user/anderson) (Quit: bye)
2023-12-04 21:41:16 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d)
2023-12-04 21:45:23 +0100 <zero> there has to be a more elegant way of writing `req_msg <$> (decodeStrict =<< req)`
2023-12-04 21:45:55 +0100 <Rembane> zero: req_msg . decodeStrict =<< req -- IIRC
2023-12-04 21:46:14 +0100 <dminuoso_> That doesnt look right.
2023-12-04 21:46:17 +0100 <shapr> @pl req_msg <$> (decodeStrict =<< req)
2023-12-04 21:46:17 +0100 <lambdabot> req_msg <$> (decodeStrict =<< req)
2023-12-04 21:46:22 +0100 <shapr> oh well, worth trying
2023-12-04 21:46:26 +0100 <dminuoso_> zero: You can drop the parenthesis.
2023-12-04 21:46:33 +0100 <Rembane> dminuoso_: I had to write it to realize it. :/
2023-12-04 21:46:45 +0100 <dminuoso_> zero: Even ignoring precedence! No matter how you associate that <$>, it will be the same.
2023-12-04 21:46:52 +0100 <dminuoso_> By law.
2023-12-04 21:46:56 +0100 <Rembane> zero: Just out of curiousity, what's the type of decodeStrict?
2023-12-04 21:47:30 +0100cimento(CO2@gateway/vpn/protonvpn/cimento)
2023-12-04 21:47:31 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) (Remote host closed the connection)
2023-12-04 21:47:40 +0100 <zero> i thought so too. but i get an error
2023-12-04 21:47:47 +0100 <Rembane> What's the error?
2023-12-04 21:47:57 +0100 <zero> decodeStrict :: forall a. FromJSON a => ByteString -> Maybe a
2023-12-04 21:48:39 +0100 <zero> Couldn't match type ‘Text’ with ‘Maybe Text’Expected: ByteString -> Maybe Text Actual: ByteString -> Text
2023-12-04 21:48:45 +0100 <zero> without the parenthesis
2023-12-04 21:50:02 +0100 <zero> Couldn't match type ‘Maybe a0’ with ‘Req’Expected: ByteString -> Req Actual: ByteString -> Maybe a0In the second argument of ‘(.)’, namely ‘decodeStrict’In the first argument of ‘(=<<)’, namely ‘req_msg . decodeStrict’
2023-12-04 21:50:06 +0100 <zero> with the .
2023-12-04 21:50:42 +0100 <Rembane> I was super wrong about the dot, I'm sorry.
2023-12-04 21:50:54 +0100 <zero> Rembane: i did the same mistake
2023-12-04 21:51:22 +0100zetef(~quassel@95.77.17.251)
2023-12-04 21:51:23 +0100 <Rembane> zero: It looks nice, but doesn't work. :)
2023-12-04 21:51:52 +0100 <zero> my brain tells me to write it another way
2023-12-04 21:54:11 +0100 <Rembane> zero: You could use do-notation if that makes your brain happier.
2023-12-04 21:54:50 +0100 <dminuoso_> zero: Depending on surrounding code, <&> could help
2023-12-04 21:54:53 +0100alp_(~alp@2001:861:e3d6:8f80:9ca3:38ae:c1a8:63c1) (Remote host closed the connection)
2023-12-04 21:55:10 +0100alp_(~alp@2001:861:e3d6:8f80:fcbc:9c69:6404:51f0)
2023-12-04 21:55:59 +0100 <dminuoso_> zero: Or making a decodeReq :: (Req -> a) -> Inp -> Decode a type of function
2023-12-04 21:56:05 +0100 <dminuoso_> Such that you can write `decodeReq req_msg =<< req`
2023-12-04 21:58:09 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-04 21:59:06 +0100dcoutts_(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net)
2023-12-04 22:02:11 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-04 22:02:30 +0100 <Hecate> win la
2023-12-04 22:02:32 +0100 <Hecate> (woops)
2023-12-04 22:02:37 +0100zetef(~quassel@95.77.17.251) (Ping timeout: 255 seconds)
2023-12-04 22:03:02 +0100zetef(~quassel@5.2.182.98)
2023-12-04 22:03:08 +0100not_reserved(~not_reser@185.195.59.27)
2023-12-04 22:04:14 +0100dhil(~dhil@2001:8e0:2014:3100:5872:f936:bc7a:ceb8) (Ping timeout: 260 seconds)
2023-12-04 22:11:16 +0100_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Remote host closed the connection)
2023-12-04 22:17:24 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-04 22:17:46 +0100sord937(~sord937@gateway/tor-sasl/sord937) (Quit: sord937)
2023-12-04 22:21:13 +0100alp_(~alp@2001:861:e3d6:8f80:fcbc:9c69:6404:51f0) (Ping timeout: 246 seconds)
2023-12-04 22:21:23 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d)
2023-12-04 22:23:20 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-04 22:24:50 +0100akegalj(~akegalj@141-136-219-144.dsl.iskon.hr)
2023-12-04 22:25:38 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) (Ping timeout: 252 seconds)
2023-12-04 22:26:12 +0100kassouni(~textual@2601:646:401:6c30:5dd8:64ca:fd4d:e39b) (Ping timeout: 256 seconds)
2023-12-04 22:27:46 +0100akegalj(~akegalj@141-136-219-144.dsl.iskon.hr) (Client Quit)
2023-12-04 22:28:01 +0100coot(~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
2023-12-04 22:30:32 +0100takuan(~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection)
2023-12-04 22:38:07 +0100mobivme(~mobivme@112.201.111.217) (Excess Flood)
2023-12-04 22:40:33 +0100mobivme(~mobivme@112.201.111.217)
2023-12-04 22:45:16 +0100zzz(~z@user/zero)
2023-12-04 22:48:41 +0100zero(~z@user/zero) (Ping timeout: 245 seconds)
2023-12-04 22:48:41 +0100zzzzero
2023-12-04 22:51:04 +0100alp_(~alp@2001:861:e3d6:8f80:2823:fd6b:81cc:5297)
2023-12-04 22:51:28 +0100Square2(~Square4@user/square)
2023-12-04 22:53:20 +0100 <darkling> ROFL @ Venn diagrams.
2023-12-04 22:53:30 +0100 <darkling> Err. -ECHANNEL.
2023-12-04 22:54:21 +0100Square(~Square@user/square) (Ping timeout: 252 seconds)
2023-12-04 22:55:27 +0100misterfish(~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 260 seconds)
2023-12-04 23:00:57 +0100fendor(~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c)
2023-12-04 23:09:26 +0100dcoutts_(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Remote host closed the connection)
2023-12-04 23:09:39 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d)
2023-12-04 23:09:44 +0100dcoutts_(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net)
2023-12-04 23:11:49 +0100mc47(~mc47@xmonad/TheMC47) (Remote host closed the connection)
2023-12-04 23:11:57 +0100 <monochrom> I love Venn diagrams!
2023-12-04 23:14:02 +0100robobub(uid248673@id-248673.uxbridge.irccloud.com) (Quit: Connection closed for inactivity)
2023-12-04 23:14:47 +0100 <glguy> If I do part 2 as a list of partial sums I get: asPart2' = head . foldr (\wins xs -> 1 + (2 * head xs - xs !! wins) : xs) [0]
2023-12-04 23:18:25 +0100chomwitt(~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1) (Ping timeout: 256 seconds)
2023-12-04 23:19:33 +0100euandreh(~Thunderbi@189.6.18.26) (Ping timeout: 256 seconds)
2023-12-04 23:26:10 +0100euandreh(~Thunderbi@189.6.18.26)
2023-12-04 23:27:52 +0100 <glguy> I should put that in my c++ solution where the indexing can be efficient
2023-12-04 23:28:08 +0100 <monochrom> :)
2023-12-04 23:29:15 +0100 <int-e> Hmm... 1 + (head xs - xs !! wins) + head xs ...okay, yeah, that looks correct :P
2023-12-04 23:30:39 +0100euandreh(~Thunderbi@189.6.18.26) (Ping timeout: 252 seconds)
2023-12-04 23:32:24 +0100fendor(~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c) (Remote host closed the connection)
2023-12-04 23:32:28 +0100skiEuler's some diagrams
2023-12-04 23:33:42 +0100euandreh(~Thunderbi@189.6.18.26)
2023-12-04 23:41:05 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-04 23:43:14 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-04 23:44:31 +0100 <iqubic> I love Euler Diagrams.
2023-12-04 23:51:42 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-04 23:55:25 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-04 23:56:46 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 276 seconds)
2023-12-04 23:59:58 +0100szkl(uid110435@id-110435.uxbridge.irccloud.com) (Quit: Connection closed for inactivity)