Home liberachat/#haskell: Logs Calendar

Logs on 2023-12-09 (liberachat/#haskell)

00:03:16 <monochrom> I was reading Bauer's "what's algebraic about algebraic effects?". I love this fun sentence: "The next time the subject of tensor products comes up, you may impress your mathematician friends by mentioning that you know how to tensor software with hardware." >:D
00:03:51 pavonia joins (~user@user/siracusa)
00:06:18 <ski> link ?
00:07:39 <geekosaur> https://arxiv.org/abs/1807.05923 I think?
00:07:45 <geekosaur> well, via that
00:07:51 <monochrom> Yeah that.
00:08:06 peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com)
00:08:32 <ski> ty
00:10:22 <monochrom> (The sentence means the tensor product between effectful programs and external environment/state-space.)
00:14:04 × azimut quits (~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection)
00:14:23 azimut joins (~azimut@gateway/tor-sasl/azimut)
00:16:36 × peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 245 seconds)
00:24:39 × waleee quits (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 252 seconds)
00:29:24 × idgaen quits (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1)
00:47:15 × sawilagar quits (~sawilagar@user/sawilagar) (Ping timeout: 260 seconds)
00:52:49 peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com)
00:57:31 × juri_ quits (~juri@faikvm.com) (Ping timeout: 255 seconds)
00:58:31 lane joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
00:59:07 juri_ joins (~juri@79.140.117.90)
01:04:28 <dsal> I'm having trouble with an impredicative type. I want to write ` :: [Coercible a b => a] -> [b]` but obvious things aren't working. I should be able to do this, right?
01:04:31 × lane quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Ping timeout: 268 seconds)
01:05:15 <dsal> Maybe that's too magical. Makes usage super easy…
01:05:39 <ski> did you mean `[forall a. Coercible a b => a] -> [b]' ? or maybe `[exists a. Coercible a b *> a] -> [b]' ?
01:06:25 ski suspects the latter
01:06:36 <dsal> Ohh. I forgot to scope the forall. I'm not familiar with exists.
01:06:55 <ski> pseudo-Haskell (not (yet ?) supported by any extension)
01:07:40 <ski> with the latter, each element of the list could have a different type `a', as long as they're all coercible to `b'
01:07:52 <dsal> Ah. Yeah, that sounds right.
01:08:04 <ski> with the former, each element of the list has to be polymorphic, has to have *all* types `a' that are coercible to `b'
01:08:32 <ski> you want the former, or the latter ?
01:08:33 <dsal> I just want to pass a bag of newtype values I have lying around that all have the same representation and let the callee do the conversion.
01:08:47 <ski> do all of them have the same type ?
01:08:51 <dsal> No.
01:10:08 × jargon quits (~jargon@32.sub-174-238-226.myvzw.com) (Remote host closed the connection)
01:11:06 <ski> there are two ways of encoding `exists a. Cxt a *> Foo a'. first one is to define a datatype `data SomeFoo = forall a. Cxt a => WrapFoo (Foo a)' (using `ExistentialQuantification' (imho a misnomer, `ExistentialConstructors' would be better)), alternatively using `data SomeFoo where WrapFoo :: Cxt a => Foo a -> SomeFoo' (using `GADTs')
01:11:18 <ski> in either case, you get
01:11:27 <ski> WrapFoo :: Cxt a => Foo a -> SomeFoo
01:11:32 lane joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
01:11:37 <ski> which really means here
01:11:41 <ski> WrapFoo :: forall a. Cxt a => Foo a -> SomeFoo
01:11:46 <ski> which is logically equivalent to
01:11:57 <ski> WrapFoo :: (exists a. Cxt a *> Foo a) -> SomeFoo
01:12:11 <ski> therefore a `SomeFoo' value expresses `exists a. Cxt a *> Foo a'
01:12:28 × peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 255 seconds)
01:12:30 <ski> the second way of encoding is to replace
01:12:43 <ski> makeSomeFoo :: ... -> exists a. Cxt a *> Foo a
01:12:44 <ski> with
01:13:04 <ski> withSomeFoo :: ... -> (forall a. Cxt a => Foo a -> o) -> o
01:13:17 <ski> (requires `Rank2Types')
01:13:24 × [itchyjunk] quits (~itchyjunk@user/itchyjunk/x-7353470) (Remote host closed the connection)
01:13:30 [_] joins (~itchyjunk@user/itchyjunk/x-7353470)
01:13:49 <ski> this second encoding, the CPS/Church encoding, is useful when you want to return an existential, but unpack it immediately after the call on the other side
01:13:55 <dsal> For my use case, I'm basically passing a list of differently wrapped types that all unwrap to the same thing, but I don't want to make it harder for the caller. If I have to do anything other than [v1, v2, v3] (for three types coercible to underlying value), then I might as well just have the caller coerce.
01:14:13 <ski> while the `data' type encoding, is useful when you want to store the existential in some data structure (like your list)
01:16:04 <ski> dsal : right, okay
01:16:39 <ski> for the `data' encoding, you need the data constructor. for the CPS encoding, you need to use a `withXXX' version (or introduce a lambda)
01:17:02 <dsal> Now my call looks like [coerce @_ T v1, coerce v2, coerce v3] Which… is OK, I guess. I'm only trying to add sugar.
01:17:48 <ski> fair
01:19:09 <ski> (perhaps "raw" existentials could be added at some point. but i'm not too sure how little extra annotations (say type ascriptions, possibly) could be needed)
01:19:39 × lane quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Ping timeout: 252 seconds)
01:20:39 <monochrom> But hey if you have turned out impredicativity anyway you may as well simulate raw existentials by CPSing to raw universals >:)
01:20:53 emmanuelux joins (~emmanuelu@user/emmanuelux)
01:21:20 <monochrom> [forall o. (forall a. Cxt a => Foo a -> o) -> o]
01:22:04 <ski> yep ("introduce a lambda")
01:22:40 × emmanuelux_ quits (~emmanuelu@user/emmanuelux) (Ping timeout: 276 seconds)
01:23:03 <monochrom> "So you want a list of objects. Let me introduce you to System F..." >:)
01:26:41 notzmv joins (~zmv@user/notzmv)
01:33:36 × Tuplanolla quits (~Tuplanoll@91-159-68-236.elisa-laajakaista.fi) (Quit: Leaving.)
01:42:46 lane joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
01:44:22 <dsal> Yeah, I thought about doing that, but anything other than passing the raw value might as well be `coerce`. This isn't a common use case.
01:44:28 <dsal> (probably, I don't know, I'm just trying this out)
01:46:10 <monochrom> In practice, [coerce x, coerce y, ...] is probably the simplest.
01:47:01 <ski> if it's a list literal, i guess one could use TH ..
01:47:17 <ski> (.. probably not worth it)
01:47:59 × myme quits (~myme@2a01:799:d60:e400:674:e335:7501:d41d) (Ping timeout: 268 seconds)
01:48:37 myme joins (~myme@2a01:799:d60:e400:f494:822d:598a:260f)
01:52:34 × lane quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Ping timeout: 276 seconds)
01:56:28 lane joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
01:57:35 × machinedgod quits (~machinedg@93-136-199-108.adsl.net.t-com.hr) (Ping timeout: 264 seconds)
01:58:53 machinedgod joins (~machinedg@93-136-130-2.adsl.net.t-com.hr)
02:00:32 <iqubic> What are we talling about here?
02:01:33 × mosul quits (~mosul@user/mosul) (Ping timeout: 268 seconds)
02:01:40 jargon joins (~jargon@32.sub-174-238-226.myvzw.com)
02:01:52 × Unicorn_Princess quits (~Unicorn_P@user/Unicorn-Princess/x-3540542) (Ping timeout: 255 seconds)
02:02:22 Unicorn_Princess joins (~Unicorn_P@user/Unicorn-Princess/x-3540542)
02:02:25 × lane quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Ping timeout: 255 seconds)
02:02:57 mosul joins (~mosul@user/mosul)
02:10:11 × machinedgod quits (~machinedg@93-136-130-2.adsl.net.t-com.hr) (Ping timeout: 264 seconds)
02:15:07 lane joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
02:23:27 × lane quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Ping timeout: 252 seconds)
02:24:07 lane joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
02:26:07 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Ping timeout: 240 seconds)
02:27:03 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
02:27:44 xff0x_ joins (~xff0x@2405:6580:b080:900:9024:2952:42f7:bdd9)
02:30:46 × xff0x quits (~xff0x@ai096045.d.east.v6connect.net) (Ping timeout: 255 seconds)
02:33:01 × lane quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Ping timeout: 256 seconds)
02:44:49 lane joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
02:47:00 maars joins (uid160334@id-160334.uxbridge.irccloud.com)
02:48:49 <edwardk> iqubic: haskell, nominally. i mean i sometimes like to talk about ai or fish these days, but haskell is what it says on the tin
02:49:01 <iqubic> I see.
02:49:11 × lane quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Ping timeout: 264 seconds)
02:55:41 × Unicorn_Princess quits (~Unicorn_P@user/Unicorn-Princess/x-3540542) (Remote host closed the connection)
02:57:23 not_reserved joins (~not_reser@194.124.76.8)
02:57:57 tommy__ joins (~tommy@2601:681:5a00:a260:f35c:8e59:cc90:e32a)
03:00:49 × xff0x_ quits (~xff0x@2405:6580:b080:900:9024:2952:42f7:bdd9) (Ping timeout: 276 seconds)
03:01:13 xff0x joins (~xff0x@ai085147.d.east.v6connect.net)
03:04:27 × tommy__ quits (~tommy@2601:681:5a00:a260:f35c:8e59:cc90:e32a) (Ping timeout: 268 seconds)
03:08:52 <dsal> I saw a whale this morning.
03:10:23 <dsal> iqubic: I'm doing a thing at work where I have a large number of newtype wrappers around a fundamental type and I want to do some stuff where I shed the type distinction and do stuff with the fundamental. I'd like to be able to do that with a list of stuff I know can be coerced to that type without having to do the coercion in the caller (just to make it easier to use), but it's probably not that important.
03:10:39 <iqubic> I see...
03:12:22 mikess joins (~sam@user/mikess)
03:16:29 × enviosity quits (~enviosity@176.254.244.83) (Ping timeout: 240 seconds)
03:17:41 × analoq quits (~yashi@user/dies) (Ping timeout: 240 seconds)
03:19:32 analoq joins (~yashi@user/dies)
03:25:52 × edr quits (~edr@user/edr) (Quit: Leaving)
03:29:49 × pretty_dumm_guy quits (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5)
03:31:12 <edwardk> dsal: but a whale is a mammal. it doesn't count ;)
03:43:11 × td_ quits (~td@i5387090D.versanet.de) (Ping timeout: 252 seconds)
03:45:12 td_ joins (~td@i5387091B.versanet.de)
03:46:34 nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net)
03:54:26 <dsal> edwardk: heh, [category theory joke] but it was the first one of the season, so I was excited about it.
03:54:48 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
03:54:49 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
04:14:05 <iqubic> edwardk: do you think that the semigroupoids library is still needed now that Foldable1 is in Base?
04:17:28 <edwardk> i still use a few things from it now and again
04:17:31 × phma quits (~phma@host-67-44-208-50.hnremote.net) (Read error: Connection reset by peer)
04:17:56 phma joins (phma@2001:5b0:211f:f418:cffc:74b5:153b:99d9)
04:19:04 <edwardk> Extend, Bind, Conclude, Decide, Devise, Apply, Alt don't have base equivalents
04:19:05 <iqubic> Like what?
04:19:51 <iqubic> What is Decide? Is that like, some covariant Applicative Functor?
04:19:56 <edwardk> let alone the Bitraversable1, etc. kind of things.
04:20:09 <iqubic> *contravariant
04:20:22 <edwardk> https://hackage.haskell.org/package/semigroupoids-6.0.0.1/docs/Data-Functor-Contravariant-Decide.html
04:21:59 <iqubic> What the heck does that do?
04:22:38 <edwardk> 'if you can handle b, and you can handle c, and you can convert an a into b or c you can handle a."
04:23:18 <iqubic> I see...
04:24:12 <edwardk> this is the version without a unit, unlike Decidable in contravariant
04:24:24 <iqubic> So `f' has to use the parameter in a negative position.
04:24:33 <edwardk> yep
04:24:57 <edwardk> easiest instance is Op r
04:25:02 <edwardk> with no constraints on r
04:25:11 <iqubic> I see.
04:25:42 <ski> write end of concurrent channels ?
04:26:23 <iqubic> Would `Newtype Predicate a = Predicate { runPredicate :: a -> Bool }' also work?
04:26:33 <ski> yes
04:26:37 <edwardk> iqubic: yep. aka Op Bool
04:26:58 <edwardk> https://www.schoolofhaskell.com/user/edwardk/editorial/procrustean-mathematics talks about why i care about these sort of crippled not-quite-what-everyone-uses classes
04:28:08 <iqubic> I see that Divisible from Contravariant has a "conquer :: f a" function. What's that for?
04:28:20 <ski> (iow `CoyonedaOp Chan')
04:28:33 × jargon quits (~jargon@32.sub-174-238-226.myvzw.com) (Remote host closed the connection)
04:28:44 <edwardk> its a 'unit' for divide
04:29:00 <edwardk> plays the same role as pure
04:29:02 <ski> `(a -> Void) -> f a'
04:29:04 <edwardk> which seems odd given that signature
04:29:28 <edwardk> you use the mapping to () actually
04:29:36 <iqubic> What would "conquer" look like for Op r?
04:30:04 <edwardk> there it requires r have an instance. i'll let you guess what it might be that is associative and has a unit
04:30:42 <iqubic> newtype Op r a = Op { getOp :: a -> r }
04:30:45 <edwardk> for predicates conquer is the predicate that returns true
04:30:50 <edwardk> in all cases
04:31:16 <edwardk> so that if you divide and conquer one case you are left with the predicate for the other case (because divide uses && on the Bool result)
04:32:40 <iqubic> let me guess, you need "instance Monoid r => Op r where..." so that you can return 'mempty' in "conquer"?
04:33:09 <edwardk> pure :: (() -> a) -> f a ~ a -> f a, conquer :: (a -> ()) -> f a ~ f a, lose :: (a -> Void) -> f a, empty :: (Void -> a) -> f a ~ f a
04:33:17 <edwardk> yep
04:33:29 <iqubic> https://hackage.haskell.org/package/contravariant-1.5.5/docs/src/Data.Functor.Contravariant.Divisible.html#line-191
04:33:38 <iqubic> Looks like I'm write!
04:33:42 <iqubic> *right
04:34:16 <edwardk> anyways those 4 units above are the key to understanding Applicative, Divisible, Decidable, and Alternative in many ways and why those 4 classes are so tightly intertwined
04:35:06 <edwardk> the same story that says monads are monoids in the category of endofunctors can be used to argue about Applicative, which is also a monoid object in the category of endofunctors, just w.r.t a different choice of tensor
04:35:27 <edwardk> the tensor chosen there is something called Day convolution
04:35:33 <iqubic> What the hell is "lose :: (a -> Void) -> f a"
04:35:40 <edwardk> but Day convolution is _usually_ done about contravariant functors.
04:35:46 <iqubic> Why is Void there?
04:35:48 <edwardk> Contravariant 'empty'
04:35:55 <ski> iqubic : instead of `Either b c'
04:35:56 <edwardk> :t empty
04:35:58 <lambdabot> Alternative f => f a
04:36:39 <edwardk> notice how all 4 of those take in an arrow that is either to or from an initial or terminal object
04:36:57 <edwardk> and then the forms we usually deal with are ones that have been simplified using that fact
04:36:58 <iqubic> I do notice that.
04:37:15 <edwardk> hence why i wrote the unsimplified versions next to the ones we know
04:38:10 <iqubic> Void is the intial object, right? And () is the terminal object?
04:38:17 <ski> yea
04:38:37 <ski> (ignoring bottoms)
04:39:02 <edwardk> for a fun exercise play around with Day :: (a -> (b, c)) -> f b -> g c -> Day f g a but we could also write Day :: (a -> Either b c) -> f b -> g c -> Day f g a, or Day :: ((b, c) -> a) -> f b -> g c -> Day f g a or Day :: (Either b c -> a) -> f b -> g c -> Day f g a
04:39:27 <edwardk> then for a fun exercise you can realize that for one of those there exists a function that takes Applicative f => Day f f a -> f a
04:39:38 <edwardk> and another Divisible f => Day f f a -> f a
04:39:49 <edwardk> and another Decidable f => ... and another Alternative f =>
04:40:16 <edwardk> now Decidable and Alternative aren't purely about the monoidal structure, there's some half-defined interaction with Divisible or Applicative
04:40:21 × [_] quits (~itchyjunk@user/itchyjunk/x-7353470) (Remote host closed the connection)
04:40:29 [_] joins (~itchyjunk@user/itchyjunk/x-7353470)
04:40:43 <edwardk> :t liftA2
04:40:44 <lambdabot> Applicative f => (a -> b -> c) -> f a -> f b -> f c
04:40:54 <edwardk> :t liftA2 . curry
04:40:55 <lambdabot> Applicative f => ((a, b) -> c) -> f a -> f b -> f c
04:41:09 <edwardk> looks a lot like the third 'Day' type i wrote above
04:42:03 aforemny_ joins (~aforemny@i59F516ED.versanet.de)
04:42:11 <edwardk> and you can write combinators to take each Day and provide associativity, and the mixture of arrows to/from the initial/terminal objects act as appropriate units for Day
04:42:52 × aforemny quits (~aforemny@i59F516CC.versanet.de) (Ping timeout: 246 seconds)
04:42:53 <edwardk> i gave a talk at some point, let me find it
04:43:17 <edwardk> https://www.youtube.com/watch?v=cB8DapKQz-I here you go. Discrimination is Wrong.
04:46:32 <iqubic> That's really, really cool!
04:47:35 <edwardk> https://www.youtube.com/watch?v=cB8DapKQz-I&t=376s is the relevant section of the talk starting from the 'monads are monoids in the category of endofunctors' bit
04:48:49 × nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 255 seconds)
04:50:53 × iqubic quits (~avi@2601:602:9502:c70:dd03:78c7:a43f:a269) (Remote host closed the connection)
04:58:23 <ski> ooh, I-Vars
05:01:20 <edwardk> https://hackage.haskell.org/package/discrimination-0.5/docs/Data-Discrimination-Grouping.html has my favorit Divisible/Decidable instances in haskell
05:02:03 <edwardk> at the end of that talk i call for help. well help didn't wind up coming forth and i had to solve the problem myself, which led to https://hackage.haskell.org/package/promises and that implementation of Grouping
05:02:11 <ski> @hackage ivar-simple
05:02:12 <lambdabot> https://hackage.haskell.org/package/ivar-simple
05:02:17 <ski> @hackage data-ivar
05:02:18 <lambdabot> https://hackage.haskell.org/package/data-ivar
05:02:23 <edwardk> i mention it because it has a fancier version of ivars than those ;)
05:02:47 <ski> yea, it looks a bit more elaborate, `ST'-style
05:03:19 <edwardk> it comes down to the observation that we have lazy and strict futures, but only strict promises
05:03:23 <edwardk> what would a lazy promise be?
05:04:01 <edwardk> a strict future rushes off and does something when you create it, and you block waiting for it. this is basically the birth of async/await style
05:04:10 <edwardk> a lazy future... well, we're haskellers. thunks
05:04:25 <edwardk> doesn't do squat until you start camping out waiting for it, then it does its work
05:04:50 <ski> "If you observe the demanded answer of this promise then either by the end of the current lazy computation we'll provide a \"real\" answer, or you'll get an error." -- meaning we'll block until the end of the `runLazy'/`runLazy_' ?
05:04:57 <edwardk> a promise is different than a future, despite being an implementation technique for the latter. given a 'future' i have a computation that will run and the last thing it gives will be the answer
05:05:27 <edwardk> but a promise is just something that someone will fulfill later and then you can unblock
05:05:34 <edwardk> it gets written to, ivar style
05:05:41 trev joins (~trev@user/trev)
05:05:51 <edwardk> but uh.. how do i tell the entire universe to stop and to run only when i need something?
05:05:59 <edwardk> i can't do that with an IO-based IVar
05:06:08 <edwardk> but i can make something that kind of works like a demand-driven ST
05:06:08 <ski> yea, a promise is more like a logic/dataflow variable
05:06:35 × sabino quits (~sabino@user/sabino) (Ping timeout: 264 seconds)
05:06:45 <edwardk> where the computation that will produce the result of the IVar is known, it will write to the promise eventually, or reach the end in which case the promise goes unfulfilled (in my case often filling in with a default value)
05:07:02 <edwardk> and we can drive the ST-like computation forward right up until the promise is fulfilled and then put it back to bed
05:07:09 <edwardk> so 'lazy' promises can exist!
05:07:33 <edwardk> and they are needed in order to get the correct asymptotics for productive stable unordered discrimination in that talk
05:07:57 <edwardk> otherwise they take sorting from n log n to... something that is basically n^2, not to something effectively linear
05:08:15 sabino joins (~sabino@user/sabino)
05:08:16 <edwardk> er not sorting, producing equivalence classes in the order encountered
05:08:25 <ski> mhm .. don't quite get how this works, yet .. watching the talk might help
05:08:30 <ski> the `b' in `runLazy'/`runLazy_' is ignored, i suppose
05:08:42 <edwardk> but if each equivalence class produced had to sift through the inputs independently you'd spend O(n^2) time
05:08:46 <edwardk> yeah
05:09:07 <edwardk> you communicate with the outside world through promises and demands
05:09:33 <edwardk> runLazy_ $ \p -> do q <- promise_; p != "yay! " ++ demand q; q != "it works." =====> "yay! it works."
05:09:52 <ski> (first, i was thinking it was something like `newCyclicIdent :: (Ident a -> a) -> IO a', with `readIdent :: Ident a -> IO a',`instance Eq (Ident a)')
05:09:58 <edwardk> p is going to be the answer. and we can fulfill p partially, and leave in the middle of it a demand for yet another promise
05:10:28 <edwardk> then since this is 'ST-like' you can have STVars, etc.
05:10:49 <ski> what about nested ?
05:10:51 <edwardk> so it turns out the way to use the promises API is typically by making STvariables or arrays and the like and stuffing promises in them
05:10:55 <edwardk> they work fine
05:11:19 <edwardk> each promises is tied to the logical lazy st-like computation that will fulfill it
05:11:28 <edwardk> it may also choose to fulfill a bunch of other promises along the way
05:11:49 <edwardk> but when you demand a solution to one promise, you don't care if that program runs around like a doordasher fulfilling other people's orders too
05:12:09 <ski> hm, but the `s' in `Lazy' doesn't interact with the one in `ST', i suppose
05:12:40 <edwardk> well, it plays the exact same role
05:12:48 ski nods
05:13:06 <edwardk> it ensures it is only ever able to be fulfilled by the correct logical thread of execution
05:13:17 <ski> and if you fulfill a promise more than once ?
05:13:20 <edwardk> so i can suspend that thread until something needs a promise fulfilled
05:13:51 <edwardk> not here. this isn't lindsey kuper's version of ivars
05:14:06 <edwardk> in hers you can fulfill them multiple times so long as you always agree
05:14:32 <edwardk> but the problem there is safety and sanity require you to know how to compare the values you put in them for equality
05:14:45 <edwardk> and i can't do that all the time. the promise may be that i'll tell you a function or something
05:14:52 <ski> @hackage lvish
05:14:52 <lambdabot> https://hackage.haskell.org/package/lvish
05:14:53 <ski> yea
05:15:09 <ski> right
05:15:53 <ski> (you'd need unification .. Mercury throws a run-time exception, if you try to unify functions or predicates, iirc)
05:16:24 <edwardk> and in my case you'd have some pretty weird semantics. the first thing that fulfils is when i 'go back to sleep'. so if you ran to that point to answer a demand you'd ge the first result, but if someone fulfille it multiple times before you demanded a result of a particular promise somewhere you could get the second result!
05:17:09 <ski> (lambdaProlog does higher-order unification (incomplete) .. and its lambdas are weaker, no recursion at all, computation is done through predicates, not functions (which are more like quoted functions in MetaML/MetaOCaml))
05:17:48 <ski> so, do you detect that ?
05:18:00 <edwardk> e.g. runLazy $ \p -> q <- promise_; r <- promise; p != (demand q, demand r); r != "hello"; r != "goodbye"; q != "testing" -- would produce ("testing","hello") -- if the second r != wasn't there.
05:18:14 <edwardk> and if you demanded the first half of the pair before the second
05:18:20 × mikess quits (~sam@user/mikess) (Quit: leaving)
05:18:39 <edwardk> but if yuou demanded the second half of the pair before the first... you'd get ("testing","goodbye") ?!
05:19:00 <edwardk> well, i throw at yu if you try to fulfill a promise twice.
05:19:00 <ski> kinda like weird `unsafeInterleaveST' behaviour, i guess
05:19:06 <ski> ok
05:19:48 <edwardk> it dies because you go to put into an Mvar that has no other referent, so you get BlockedIndefinitelyOnMVar out of ghc
05:20:47 <ski> (hm, isn't there an monad for doing concurrent pipelines in the PCPH ? for some reason i'm reminded of that)
05:20:49 <edwardk> anyways you can view the Lazy s monad as a sort of super-powered but safe interleaveST
05:21:07 <edwardk> remember, i'm deliberately not progressing the pipeline until its demanded
05:21:12 <edwardk> otherwise its just a boring normal promise
05:21:15 <edwardk> like everyone else uses
05:21:20 <ski> "pipeline" here being ?
05:21:26 <edwardk> the computation
05:21:31 <edwardk> whatever you wrote in the Lazy monad
05:21:37 <ski> the sequence of `Lazy s' actions ?
05:21:39 <ski> ok
05:22:00 <edwardk> until you introspect the result of it, nothing happens. it gets triggered to advance when you implicitly demand the answer by looking at it
05:22:06 <edwardk> and then it runs through the chain until it is fulfilled
05:22:34 <ski> but it runs forwards, right ?
05:22:35 <edwardk> but along the way it may have set up other promises and used demands on those (as yet unfulfilled) promises as part of how it fulfilled the original promise, ike i did above
05:22:41 <edwardk> yes, until it files p != ...
05:22:43 <edwardk> er finds
05:22:52 <ski> (not like `ST.Lazy' .. or is there a version of it like that ?)
05:22:55 <edwardk> and then that becomes the answer. and then it stops
05:23:06 <edwardk> Lazy here is like ST.ReallyReallyLazy ;)
05:23:42 <edwardk> one way to think about it is ST is still kinda future'y
05:23:52 <edwardk> its only way to commmunicate with the outside world is through its result
05:23:55 <ski> i think someone had some example with `foo = do xs <- foo; ...; return (x:xs)', which "executed backwards" in lazy `ST'
05:24:01 <edwardk> but when you demand the result the whole action has to kinda happen
05:24:11 <edwardk> here i can kinda stop and take a nap
05:24:39 <ski> (there was a paste on <lpaste.net>, i believe)
05:24:53 <edwardk> you get similar results in lazy state
05:24:57 <edwardk> head recursion
05:25:06 <edwardk> and guards that don't stop you from launching missiles, etc.
05:25:43 <edwardk> foo = do foo; modify (1:) -- when exec'd produces an infinite stream of 1:'s in lazy state
05:25:56 <ski> right
05:26:03 <edwardk> but you'll note that this computation runs _forwards_
05:26:08 <edwardk> but then stops and takes a nap
05:26:20 <ski> yes, that's what i was wondering about
05:27:24 <monochrom> Yes I posted ST.Lazy and State.Lazy examples like that on lpaste. Then lpaste died. :)
05:27:40 <ski> right, i thought it might've been you
05:28:13 <edwardk> the lazy state monad example is a general argument for why 'cont is the mother of all monads' doesn't hold in a lazy language
05:28:54 <edwardk> theres no cps'd lazy state
05:29:26 <ski> (e.g. my `links' file tells me "unsafeInterleavIO passing style" by monochrom in 2012-11-0[78] at <http://lpaste.net/77374>)
05:34:48 <edwardk> in any event the result of that promises lib is something that comes across like a form of laziness where you can tell other computations what their answers are in the process of finishing your own. whereas normal laziness forces you to er.. force the thunk and let it go work out its own answer, and it can't help you out until its done.
05:36:01 <edwardk> there should be a more elegant way to write it where its one thread of execution per runLazy call that blocks rather than this weird coroutine that kind of swaps over to whatever thread demands results from it, but that was the first version i came up with
05:37:10 <edwardk> it gets used in Grouping, because newtype Group a = Group { getGroup :: forall m b. PrimMonad m => (b -> m (b -> m ())) -> m (a -> b -> m ()) } lets the consumer pick the PrimMonad instance. and Lazy s is an instance of PrimMonad
05:37:11 <ski> mhm
05:37:19 <ski> when would that make a difference ?
05:37:37 <edwardk> might be faster, fewer constructors being allocated, etc.
05:37:40 <edwardk> more waiting on mvars
05:38:11 <ski> mhm
05:38:13 <edwardk> but then i'd have to explicitly fulfil all the defaulted versions at the end.
05:38:18 <edwardk> so maybe not a win
05:38:26 <edwardk> its on my list of 'ways to make discrimination faster'
05:38:28 <ski> and you have some consumer of `Group a' which picks `Lazy s' ?
05:38:35 <edwardk> yeah, several.
05:39:06 <edwardk> https://hackage.haskell.org/package/discrimination-0.5/docs/src/Data.Discrimination.Grouping.html#runGroup
05:39:08 <edwardk> is the big one
05:39:19 <edwardk> it gives what looks like the API of 'Sorting' from Grouping
05:39:40 <edwardk> but also the nub replacement.
05:39:42 <edwardk> https://hackage.haskell.org/package/discrimination-0.5/docs/src/Data.Discrimination.Grouping.html#nubWith
05:45:10 <ski> `MutVar's in `Lazy s' ?
05:48:55 <ski> hm, i think i kinda follow what `runGroup' is doing
05:56:39 <edwardk> its basically making a directory of equivalence classes it has seen so far and when new items come in they are being deposited into the right list one at a time
05:57:25 <edwardk> the individual instances are responsible for using each of those computations in the right way
05:57:42 <ski> it looks similar to `set-cdr!'ing the tail, doing TCMC
05:57:54 <ski> (except, lazy)
05:58:02 <edwardk> notice how nubWith looks like that given a lobotomy. the only thing that matters is the first thing in each equivalence class, which is emitted directly, then the action that is give back drops all the rest on the floor
06:00:05 <edwardk> but if you mapped head over the result of runGroup and fed it pairs of (a,a) values, it'd have the same demand profile, and that would be a valid (if inefficient) way to implement nub with the correct asymptotics
06:01:08 <edwardk> i just love how non-obvious of a contravariant functor Grouping is
06:01:17 <ski> hm, there's only one `:' in `nubWith', though, while there's two in `runGroup' ?
06:01:33 <edwardk> keep in mind the associativity
06:01:41 <edwardk> one is building a list of lists
06:01:43 <edwardk> one is building a list
06:01:59 iqubic joins (~avi@2601:602:9502:c70:5de0:aac0:2bec:3df)
06:01:59 <edwardk> one of those promises is for the member of the inner list it just made
06:02:09 <edwardk> the other is for the outer list to put more equivalance classes in place
06:02:17 <ski> yea, well, three actually. but i was only considering the ones for the inner lists
06:02:25 <iqubic> What are we talking about here now?
06:02:40 <ski> iqubic : last two links above
06:02:50 <ski> oh, sorry, you just joined
06:03:20 <iqubic> Yeah, my laptop died, so I had to wait for it to charge up enough to let me use it.
06:03:22 <ski> <https://hackage.haskell.org/package/discrimination-0.5/docs/Data-Discrimination-Grouping.html>,<https://hackage.haskell.org/package/discrimination-0.5/docs/src/Data.Discrimination.Grouping.html#runGroup>,<https://hackage.haskell.org/package/discrimination-0.5/docs/src/Data.Discrimination.Grouping.html#nubWith>
06:03:22 <edwardk> we're talking about my lazy promises library and the discrimination code linked above that uses it. https://hackage.haskell.org/package/discrimination-0.5/docs/src/Data.Discrimination.Grouping.html#runGroup https://hackage.haskell.org/package/promises-0.3/docs/Data-Promise.html
06:03:48 <edwardk> Grouping there is an instance of Divisible and Decidable and all that jazz we were talking about earlier
06:04:03 <edwardk> and is the most complicated contravariant functor i've ever used in haskell in earnest
06:04:12 <edwardk> newtype Group a = Group { getGroup :: forall m b. PrimMonad m => (b -> m (b -> m ())) -> m (a -> b -> m ()) }
06:04:24 <edwardk> notice how the 'a' occurs in negative position
06:04:53 <ski> edwardk : afaiu the q' != b' : demand q'' is for the remaining elements of the inner list(s), while b : demand q is for the head, no ?
06:05:18 <ski> (hm, guess there could be some `NonEmpty' there)
06:05:41 <edwardk> yeah it could be a NonEmpty inside the outer list
06:05:49 <edwardk> i think this might predate my NonEmpty type
06:05:52 <edwardk> maybe nt
06:05:54 <edwardk> er not
06:06:37 <ski> so, then i'm wondering why `nubWith' only has one `:'
06:06:38 <edwardk> guess not
06:06:46 <edwardk> :t nub
06:06:47 <lambdabot> Eq a => [a] -> [a]
06:06:56 <edwardk> :t nubBy
06:06:57 <lambdabot> (a -> a -> Bool) -> [a] -> [a]
06:07:04 <ski> .. oh, actually, i'm dense
06:07:18 <edwardk> :t nub . on (==)
06:07:19 <lambdabot> error:
06:07:19 <lambdabot> • Couldn't match type ‘a -> a -> Bool’ with ‘[a2]’
06:07:19 <lambdabot> Expected type: (a -> a1) -> [a2]
06:07:29 <edwardk> :t nubBy . on (==)
06:07:30 <lambdabot> Eq a1 => (a2 -> a1) -> [a2] -> [a2]
06:07:31 <ski> ah, so the `_' is for skipping all the others
06:07:36 <edwardk> thats what i wanted
06:07:37 <edwardk> yeah
06:07:43 <ski> right, now it makes sense
06:08:00 <ski> (sorry, brain fart)
06:08:19 <edwardk> (b -> m (b -> m ())) -- is the computation that takes the first b used to establish an equivalence class, and gives back (after side effects) the way to consume more members of that same class
06:08:34 <edwardk> so in the general discrimination approach this becomes the stuff we cram in our buckets
06:08:35 <ski> yep, i figured
06:09:03 <ski> (didn't check the code that actually does that, but figured it must be something like that)
06:09:17 <edwardk> so the job of Group a is to take that and after some initial setup, give you something that you can feed a,b pairs to
06:09:38 <edwardk> and you can keep feeding me those pairs indefinitely, but if you stop the lazy computation runs out
06:09:50 <edwardk> and then i can know to fill in the default value for each of those promises (aka [])
06:09:59 <ski> "initial setup" being the first `m' in `m (a -> b -> m ())'
06:10:01 <edwardk> otherwise we block and keep running through the input
06:10:03 <edwardk> yep!
06:10:23 <ski> (figured that too, when looking at the code a bit)
06:10:28 <edwardk> it took me like 2-3 months to figure out how to write this type
06:11:04 <ski> i see why you wanted defaults, now
06:11:21 rosco joins (~rosco@175.136.152.56)
06:11:36 <edwardk> otherwise i'd have to track every created promise and whether i'd fulfilled it, and fulfill all the unfulfilled ones at the end with []
06:11:55 <ski> mm
06:12:07 wice joins (~wice@176.254.244.83)
06:12:25 <ski> so you keep track of whether the value is a default value, or an explicitly provided value
06:12:55 <edwardk> idk why whenever i'm about to get on a plane to go to a conference where i'm going to be entertaining a bunch of folks, i stay up super late on irc chatting all night ;)
06:13:02 × igemnace quits (~ian@user/igemnace) (Read error: Connection reset by peer)
06:13:07 <ski> hehee
06:13:08 <edwardk> i'm somewhat self-destructive that way i guess
06:13:29 <ski> well, it's fun to chat about such things :)
06:13:39 <edwardk> guessing its not a common destination for haskell folks, but is anybody going to be at NeurIPS this week?
06:14:44 <edwardk> i'm leaving my new fish all on their own (with my niece to take care of them) and going to go pal around with folks and they don't even write haskell. its a tragedy
06:15:20 <edwardk> they being the people not the fish. well both the people and the fish. neither writes haskell yet.
06:15:25 <int-e> . o O ( I bet the fish won't care. )
06:16:30 harveypwca joins (~harveypwc@2601:246:c280:7940:585a:99af:3e4c:209b)
06:17:12 <edwardk> but look at those eyes https://usercontent.irccloud-cdn.com/file/H5mxhvEx/sirius-eyes.png
06:17:27 <edwardk> he can guilt with the best of them
06:18:14 <ski> "ok, check to make sure we haven't been satisfied in the meantime" <https://hackage.haskell.org/package/promises-0.3/docs/src/Data-Promise.html> -- this makes me wonder whether there might be any inefficiency problems a la SRFI 45 <https://srfi.schemers.org/srfi-45/srfi-45.html> was solving
06:20:13 <edwardk> i think those have rather different semantics than what i capture here. lazy there is about setting up an eager way to fulfil the computation, np?
06:20:16 <edwardk> er no?
06:21:06 <edwardk> er not quite
06:21:36 <ski> it's about not building up `(force (delay (force (delay ...))))' sequences that all wait to update their mutable cell, growing space unboundedly
06:21:40 <edwardk> yeah
06:21:42 <iqubic> I think you need Klesli arrows for fish.
06:21:50 <iqubic> :t (>=>)
06:21:51 <lambdabot> Monad m => (a -> m b) -> (b -> m c) -> a -> m c
06:22:14 <iqubic> Sorry, that's a really bad joke.
06:22:31 <ski> (e.g. for a lazy `filter' on streams, where few elements satisfy the predicate)
06:22:41 <edwardk> but that looks like a normal bony fish. he's cartilaginous. he looks more like ---_===_
06:23:15 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection)
06:23:17 <edwardk> yeah i can see how that'd build up delay/force chains
06:23:29 <ski> val lazy : (unit -> 'a susp) -> 'a susp
06:23:34 <ski> in ML terms
06:23:41 <ski> taking that as primitive, instead of
06:23:44 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
06:23:46 <edwardk> i guess if you constantly did stuff like x <- promise_; y != demand x; ... as a way to delay a computation you'd hit this
06:23:48 <ski> val delay : (unit -> 'a) -> 'a susp
06:24:17 <iqubic> AI has corrupted my brain. I can only read ML as "Machine Learning"
06:24:20 <edwardk> but here since they are promises, not thunks, you can just pass off one such promise as another.
06:24:37 takuan joins (~takuan@178-116-218-225.access.telenet.be)
06:24:47 <edwardk> iqubic: it has been a rough few years in that regard
06:24:57 <iqubic> I'm sure.
06:25:30 <edwardk> "I'm going to go show off my shiny new ML hardware at the conference. Jane Street will be there." If I said that 5 years ago, I'd have meant something completely different.
06:25:52 <edwardk> but as it is I'm going to go show off my shiny new ML hardware at NeurIPS and Jane Street will indeed be there. ;)
06:26:11 <ski> .. and they'll be using an ML to program it ?
06:26:23 <edwardk> they are more than welcome to
06:26:58 <ski> hm, this is related to, i think some Groq (?) talk you held ?
06:27:13 <edwardk> oh man, i should use more haskell for Positron and then try to sell a bunch of hw to jane street just to watch Yaron scowl at me.
06:27:47 <edwardk> Nah. I left Groq in March and started a new company (Positron)
06:28:02 <ski> ah, ic
06:29:08 <ski> (thinking of "Reinventing Compilers for AI - - GroqDay December 2021" <https://www.youtube.com/watch?v=upljocX5mrk> and "Stanford Seminar - Dataflow for convergence of AI and HPC - GroqChip!" <https://www.youtube.com/watch?v=kPUxl00xys4>)
06:29:17 igemnace joins (~ian@user/igemnace)
06:29:25 <edwardk> basically we're focused on how to get more performance per dollar in the LLM (and mixed media model) space
06:29:54 <edwardk> Groq makes an interesting chip. It is the only real attempt to do determinism on that scale.
06:30:09 <edwardk> I just don't think there's a good product market fit.
06:30:23 <edwardk> and its about what, 6-7 years old now?
06:31:56 <edwardk> We'll be at NeurIPS taking preorders for Positron systems, and talking about our software stack. Big expo booth and everything.
06:32:08 <edwardk> Completely different architecture and constraints than Groq.
06:32:57 <ski> getting more performance, in which ways ?
06:33:26 <edwardk> In many ways its a harder problem, because I embrace the bits of non-determinism required to handle all the external memory architecture designs that are out there, but then manage all the processing internally in a smarter way, by replacing a traditioal cache with something fit for purpose.
06:33:48 <iqubic> What is Positron?
06:33:54 <edwardk> But doing that means knowing a lot of statistics on refresh rates.
06:34:01 <ski> <edwardk> Nah. I left Groq in March and started a new company (Positron)
06:34:34 <edwardk> A fabless semiconductor company I started with Thomas Sohmers back at the start of April.
06:34:56 <iqubic> Are there any people doing machine learning in Haskell?
06:35:26 <edwardk> We do machine learning, and a significant cross-section of the team likes haskell, but right now its a bit lower level than that
06:35:41 <edwardk> I used a fair bit of Haskell to prototype out designs
06:35:57 <iqubic> That's fair.
06:36:20 <edwardk> The company is something close to a 50/50 mix of hardware/software
06:36:39 <edwardk> needs to be to drink from the firehose of ML development
06:37:57 <edwardk> we'll actually be selling hardware at neurips. so wish me luck
06:38:09 <edwardk> i have to keep Sirius (the stingray above) in clams.
06:38:22 <ski> clams ?
06:38:35 <ski> it eats clams ?
06:38:47 <edwardk> he eats clams, bloodworm, general whitefish, occasional jumbo shrimp, krill, whatever
06:38:50 <edwardk> he eats a lot
06:39:04 <edwardk> but his favorite is either clams or huge bricks of frozen bloodworms
06:39:20 × phma quits (phma@2001:5b0:211f:f418:cffc:74b5:153b:99d9) (Read error: Connection reset by peer)
06:39:25 <ski> hm, how wide is he ? (cm ?)
06:39:44 <edwardk> the clams he actually backs up, burrows out an area in the aquarium where he can hit the glass on the bottom, and then smashes the clams on the bottom glass until the meat is out (i hand them to him half frozen)
06:39:58 <edwardk> about a ft around the disc. so er.. 30cm?
06:40:16 <int-e> > 2.54*12
06:40:18 <lambdabot> 30.48
06:40:18 <edwardk> plus another several inches of tail + stinger
06:40:18 <ski> mm. pretty big (for an aquarium fish)
06:40:20 phma joins (phma@2001:5b0:210f:7288:e7e3:fefd:fd87:d9a3)
06:40:32 <edwardk> he's in 300 gallon + aquarium
06:40:50 <edwardk> ~1135 liters
06:41:00 <edwardk> 8 ft long. its huge
06:41:19 <edwardk> https://usercontent.irccloud-cdn.com/file/mzXmviBL/i-am-the-night.mp4
06:42:02 ski 's reminded of old Gaston comic, installing (dripping) ceiling aquariums all across the (comics) office, with circular tunnels between them, all for his goldfish to get more space to explore
06:42:15 <xerox> what's the acquarium's background from?
06:42:30 <edwardk> hah. that sounds like something that would be impossible to clean. the person who had that dream never had to clean a fish tank
06:42:46 <edwardk> its an underwater downed plane. and one of the reasons why i got so large an aquarium
06:43:14 <iqubic> Those are some cute fish!
06:43:24 <edwardk> i needed about 150 gallons to take in a bunch of koi from the backyard that were born way out of season. but it was going to take 8 weeks to get the tank made, 2-4 weeks to ship + 4 weeks or more to cycle it and they'd be frozen to death by then
06:43:58 <edwardk> so i reached out to the custom aquarium place and they had one they had made for someone else but he couldnt take possession of it (too big to ship to a residential address!) and it had made a bunch of odd choices.
06:44:16 <edwardk> namely the plane background, and a oversized sump underneath for saltwater fish, etc.
06:44:34 <edwardk> but i could get it without 8 weeks worth of extra lead time.. it was just 2x the size i wanted
06:44:53 <edwardk> so now the 18 or so koi that were born late in my pond can survive the winter indoors in the aquarium
06:45:28 <edwardk> and they've been joined by Sirius, who was languishing in far too small a tank at the local fish store for like 3 years and is a bit stunted. (he should be about twice as big around at this age!)
06:45:45 nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net)
06:46:23 <xerox> lovely creature
06:46:24 <edwardk> and i added a bunch of other cleaner fish and some weather loaches to give some color and keep the tank clean, and planted the tank because thats a lot of dirty fish
06:46:31 peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com)
06:46:36 <ski> (hm, can't seem to find any image from that story)
06:47:15 <edwardk> so now its him, 18 koi, 9 weather loaches, 8 siamese algae eaters, and a couple of feeder guppies that snuck in with about 70+ shrimp. the shrimp are down to maybe a dozen or so of the wiliest ones
06:48:12 <edwardk> given the koi will be 30cm+ in a year, the loaches will be 30cm+ in a year, the SAEs will get to be 6 inches... a lot of fish are going elsewhere soon. the bulk of the koi are headed out to the pond in the spring
06:48:23 <iqubic> Are you worried that any of your fish will eat the other fish?
06:48:32 <edwardk> they are all selected to avoid that
06:48:44 × stefan-_- quits (~cri@42dots.de) (Read error: Connection reset by peer)
06:48:44 × trev quits (~trev@user/trev) (Read error: Connection reset by peer)
06:48:44 × Lears quits (~Leary]@user/Leary/x-0910699) (Write error: Connection reset by peer)
06:48:45 × peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (*.net *.split)
06:48:45 × sabino quits (~sabino@user/sabino) (*.net *.split)
06:48:45 × lg188 quits (~lg188@82.18.98.230) (*.net *.split)
06:48:45 × qqq quits (~qqq@92.43.167.61) (*.net *.split)
06:48:45 × Sgeo quits (~Sgeo@user/sgeo) (*.net *.split)
06:48:45 × haskellbridge quits (~haskellbr@069-135-003-034.biz.spectrum.com) (*.net *.split)
06:48:45 × actioninja quits (~actioninj@user/actioninja) (*.net *.split)
06:48:45 × nitrix quits (~nitrix@user/nitrix) (*.net *.split)
06:48:45 × mobivme quits (~mobivme@112.201.111.217) (*.net *.split)
06:48:45 × telser_ quits (~quassel@user/telser) (*.net *.split)
06:48:46 × tessier quits (~treed@ec2-184-72-149-67.compute-1.amazonaws.com) (*.net *.split)
06:48:46 × hamess quits (~hamess@user/hamess) (*.net *.split)
06:48:46 × np quits (~nerdypepp@user/nerdypepper) (*.net *.split)
06:48:46 × TMA quits (tma@twin.jikos.cz) (*.net *.split)
06:48:46 × jjhoo quits (~jahakala@user/jjhoo) (*.net *.split)
06:48:46 × dolio quits (~dolio@130.44.134.54) (*.net *.split)
06:48:46 × koz quits (~koz@121.99.240.58) (*.net *.split)
06:48:46 × xxpor quits (~xxpor@user/xxpor) (*.net *.split)
06:48:46 × elkcl quits (~elkcl@broadband-95-84-226-240.ip.moscow.rt.ru) (*.net *.split)
06:48:46 × tomku quits (~tomku@user/tomku) (*.net *.split)
06:48:46 × swistak quits (~swistak@185.21.216.141) (*.net *.split)
06:48:46 × qhong quits (~qhong@rescomp-21-400677.stanford.edu) (*.net *.split)
06:48:47 × andjjj23_ quits (~irc@107.170.228.47) (*.net *.split)
06:48:47 × bliminse quits (~bliminse@user/bliminse) (*.net *.split)
06:48:47 × motherfsck quits (~motherfsc@user/motherfsck) (*.net *.split)
06:48:47 × TheCatCollective quits (NyaaTheKit@user/calculuscat) (*.net *.split)
06:48:47 × Logio quits (em@kapsi.fi) (*.net *.split)
06:48:47 × leeb quits (~leeb@tk2-243-31079.vs.sakura.ne.jp) (*.net *.split)
06:48:47 × benmachine quits (bm380@pip.srcf.societies.cam.ac.uk) (*.net *.split)
06:48:55 Logio joins (em@kapsi.fi)
06:48:58 <edwardk> the weather loaches are longer than the koi are now, but are narrow. and are generally peaceful. so they won't fit down the koi's gullets.
06:48:59 stefan-_ joins (~cri@42dots.de)
06:49:00 [Leary] joins (~Leary]@user/Leary/x-0910699)
06:49:01 telser joins (~quassel@user/telser)
06:49:02 dolio joins (~dolio@130.44.134.54)
06:49:04 koz joins (~koz@121.99.240.58)
06:49:04 swistak joins (~swistak@185.21.216.141)
06:49:05 <edwardk> and the koi don't have teeth to nip them
06:49:07 trev joins (~trev@user/trev)
06:49:08 hamess joins (~hamess@user/hamess)
06:49:10 motherfsck joins (~motherfsc@user/motherfsck)
06:49:11 qqq joins (~qqq@92.43.167.61)
06:49:12 sabino joins (~sabino@user/sabino)
06:49:20 xxpor joins (~xxpor@user/xxpor)
06:49:21 elkcl joins (~elkcl@broadband-95-84-226-240.ip.moscow.rt.ru)
06:49:23 andjjj23_ joins (~irc@107.170.228.47)
06:49:27 qhong joins (~qhong@rescomp-21-400677.stanford.edu)
06:49:29 <edwardk> so the loaches can't eat the koi now, and when the sizes invert won't be eaten in turn
06:49:31 actioninja joins (~actioninj@user/actioninja)
06:49:33 jjhoo joins (~jahakala@user/jjhoo)
06:49:34 bliminse joins (~bliminse@user/bliminse)
06:49:37 Sgeo joins (~Sgeo@user/sgeo)
06:49:43 <iqubic> I see.
06:49:46 nerdypepper joins (~nerdypepp@user/nerdypepper)
06:49:46 <edwardk> the SAEs are stupidly fast and will be big enough to avoid problems
06:49:54 haskellbridge joins (~haskellbr@069-135-003-034.biz.spectrum.com)
06:49:54 ChanServ sets mode +v haskellbridge
06:50:02 mobivme joins (~mobivme@112.201.111.217)
06:50:12 × nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 252 seconds)
06:50:21 leeb joins (~leeb@tk2-243-31079.vs.sakura.ne.jp)
06:50:37 <edwardk> the closest thing to a risk is that the loaches kind of don't care about contact. and will just come right up into my hand when i feed them etc. and in general lounge around on sirius when he's eating, and will even try to dart under him to steal bloodworms and the like. and i keep expecting one to get eaten
06:50:49 <edwardk> but when they are bigger than risk will go to zero
06:51:00 <edwardk> and they have _some_ modicum of self-preservation
06:51:21 <edwardk> i've been planning on adding a couple of high-fin banded sharks to the mix (technically they are loaches, not actual sharks)
06:52:01 <edwardk> because they can go outside with the koi when spring comes. and with the koi pond remodel i'm doing they'll have time and space to get to full size (1m+)
06:52:33 ski . o O ( <https://justacarguy.blogspot.com/2017/10/gaston-lagaffe-most-famous-blunderer-in.html> )
06:53:29 <ski> and next winter ?
06:53:39 <edwardk> they'll be fine. they can handle michigan winters
06:53:55 <iqubic> I'm gonna go get some dinner. I appreciate y'all being so nice to a trans woman like me.
06:53:58 TMA joins (tma@twin.jikos.cz)
06:54:01 <edwardk> the problem with these guys is the big koi in the back are like 2ft+ long and as fry they would have fit right in their mouths.
06:54:06 × analoq quits (~yashi@user/dies) (Ping timeout: 245 seconds)
06:54:06 tomku joins (~tomku@user/tomku)
06:54:07 tessier joins (~treed@ec2-184-72-149-67.compute-1.amazonaws.com)
06:54:19 <edwardk> koi will eat anything that fits in their mouth, including koi
06:54:38 lg1882 joins (~lg188@82.18.98.230)
06:54:38 peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com)
06:54:38 lg188 joins (~lg188@82.18.98.230)
06:54:38 benmachine joins (bm380@pip.srcf.societies.cam.ac.uk)
06:54:49 × lg188 quits (~lg188@82.18.98.230) (Ping timeout: 255 seconds)
06:55:06 <edwardk> so the fact that they were born so late in the year meant i had a problem. i couldn't put them in the main pond without getting them eaten, and i couldn't net off an area in the pond to keep them safe, because it'd be too shallow for them to be able to winter.
06:55:16 <edwardk> so a gigantic aquarium plan was born
06:55:40 nitrix joins (~nitrix@user/nitrix)
06:55:54 <edwardk> but now i have a stingray who may decide he's not so stunted after all and may balloon up to 60cm around. whereupon i'll have to build an even bigger aquarium (since he can't go outside)
06:56:02 analoq joins (~yashi@user/dies)
06:56:08 <iqubic> We need more women in the Haskell world. Well, I'm trans, but I still think that counts.
06:56:09 <ski> ah, the cold itself wasn't the problem, but the lack of depth
06:56:30 <edwardk> iqubic: agreed on both fronts
06:56:50 <iqubic> Thank you for being so supportive of me!
06:56:52 <edwardk> well lack of depth was going to make the cold a problem for them if i netted off a region in the main pond
06:57:29 <edwardk> but i could put loaches, koi and high-fin banded sharks all in a pond without problem. they can all survive my temperatures here
06:57:41 ski nods
06:58:59 <edwardk> the stingray was basically aquired after our oldest koi (28 years old!) passed away a couple weeks ago. =(
06:59:36 <edwardk> my niece had grown attached to him (as had we all), and sirius gave her something to pay attention to that needed a lot of attention instead
06:59:44 <edwardk> kind of like grieving a dog by getting a puppy
07:00:14 <edwardk> and for me its been an exercise in high tech.
07:00:34 <ski> how old's the stingray ?
07:01:39 <ski> oh, you said "who was languishing in far too small a tank at the local fish store for like 3 years and is a bit stunted"
07:01:48 <edwardk> how much can i automate the tank? automatic water changes. custom ozone dosing system balanced by an ORP sensor, a huge amount of UV filtration, a sump with a saltwater style refugium to both add water mass and a place for nitrates to go, planting the tanks to sink more nitrates, jerry-rigging a saltwater skimmer with ozone so it can foam fresh water to take out heavy particulates, getting reverse osmosis setup to clean up the incoming
07:01:48 <edwardk> water..
07:01:57 <edwardk> yeah, he's about 3-4 years old
07:02:12 <edwardk> life expectancy about 19 years
07:02:22 peterbecich1 joins (~Thunderbi@047-229-123-186.res.spectrum.com)
07:02:26 <edwardk> koi and loaches are also a 20+ year life expectancy
07:02:44 <ski> "planting" ?
07:02:47 <edwardk> SAEs about 10 years old
07:03:03 <edwardk> put down a layer of soil, then a layer of sand, then put actual plants in the water
07:03:11 <ski> ah
07:03:46 × lg1882 quits (~lg188@82.18.98.230) (Read error: Connection reset by peer)
07:04:06 lg1882 joins (~lg188@82.18.98.230)
07:04:16 × peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 255 seconds)
07:04:17 peterbecich1 is now known as peterbecich
07:04:17 × benmachine quits (bm380@pip.srcf.societies.cam.ac.uk) (Read error: Connection reset by peer)
07:04:21 <edwardk> added soething like 4800gph worth of powerheads (lateral waterflow) 3600gph of actual water movement, so i'm turning over the water about 16x per hour _in_ the tank, and about 12x per hour down to the sump below the tank where there's a bunch of filtration, biological media, other plants/algae that are less sightly in a side tank that breeds copepods and daphnia for snacks
07:04:27 benmachine joins (bm380@pip.srcf.societies.cam.ac.uk)
07:04:37 <edwardk> that refugium then trickle feeds back into the main tank
07:05:21 <edwardk> and another 800gph of uv filtration, then dosing ozone and co2 into the main tank to keep the fish and plants happy respectively
07:06:13 × gdown quits (~gavin@h69-11-149-109.kndrid.broadband.dynamic.tds.net) (Remote host closed the connection)
07:06:26 <edwardk> the ozone oxidizes stuff in the water to keep the water column clean and is tuned down to where it won't make a bunch of hydrogen peroxide and kill my fish and won't _quite_ kill off all main tank algae/diatoms, and the co2 is tuned up high enough that plants can survive a bunch of fish that historically are considered very very bad for plants
07:07:12 <edwardk> i have to run that because the koi would otherwise just root up my plants and toss them everywhere, so it lets them have a strong enough root system to survive and a fast enough growth rate to not just die off when the leaves get nibbled.
07:07:44 <edwardk> i'd have covered the entire bed of the tank in carpeting plants, but sirius naps in the sand
07:07:57 <edwardk> sorry for the long fishy tangent
07:08:35 <edwardk> getting the aquarium home https://usercontent.irccloud-cdn.com/file/wTAFJq8x/aquarium-6.jpg https://usercontent.irccloud-cdn.com/file/YbzYbPiR/aquarium-7.jpg https://usercontent.irccloud-cdn.com/file/w30O1IOq/aquarium-8.jpg
07:08:45 <ski> nah, it's interesting
07:08:49 <edwardk> but you can see in those photos, getting the aquarium home was a monster job.
07:09:11 <edwardk> a 1 ton package we had to pick up on a flatbed, and offload with a tracked hi-lo
07:09:24 <edwardk> (garage for scale!)
07:09:28 <ski> big-ass container
07:10:05 <xerox> taller than the skid steer
07:10:13 <edwardk> yeah
07:10:30 × igemnace quits (~ian@user/igemnace) (Quit: WeeChat 4.1.2)
07:10:33 <edwardk> was terrifying unloading that sucker with just me and my nephew
07:10:57 <ski> wonder how you got that indoors, even
07:10:59 <edwardk> hired a small army to get it into the house with rented glass suction cups
07:11:18 <edwardk> payed a moving company so they'd be bonded and insured so the only at-risk steps were getting it from the freight yard to my door
07:11:18 <xerox> ski: they lifted the house on top of it, easier
07:11:23 <edwardk> damn nea
07:11:24 <edwardk> er near
07:11:25 <ski> ah, makes sense
07:12:08 <edwardk> if we have to do a larger tank for sirius (e.g. rip out the pool table and put in a 700+ gallon tank in its place), then we'd actually have it built in-place.
07:12:27 <edwardk> and do an overhead sump instead of underneath
07:12:43 <edwardk> by running water, etc. up into the attic nearby
07:13:29 <ski> @wn sump
07:13:30 <lambdabot> *** "sump" wn "WordNet (r) 3.0 (2006)"
07:13:30 <lambdabot> sump
07:13:31 <edwardk> easier with a tank with that much surface area to allow a smaller sump to siphon _down_ into the main display tank than it is to have a massive sump that can soak the 1 inch or so of water that would siphon down into it on power failure
07:13:31 <lambdabot> n 1: an oil reservoir in an internal combustion engine
07:13:33 <lambdabot> 2: a well or other hole in which water has collected
07:13:35 <lambdabot> 3: a covered cistern; waste water and sewage flow into it [syn:
07:13:37 <lambdabot> {cesspool}, {cesspit}, {sink}, {sump}]
07:14:18 <edwardk> https://www.youtube.com/watch?v=xVPC3CZDC68&t=35s
07:14:40 <edwardk> basically for a tank that big you don't want to hang something on the back or have a big intrusive unit inside the main tank
07:14:55 <edwardk> so you build out a separate plumbing system for all the filtration and to provide extra water volume
07:16:32 <edwardk> when power is lost the pumps that return water up to the tank start actually taking water _down_ into the sump system. and in my case that'd be about 2000 cubic inches of water (8.6 gallons, a couple of big buckets basically)
07:16:45 <edwardk> so i have to have extra volume down there for that eventuality should i lose power
07:17:14 <edwardk> but if i had a tank with 2.5-3.5x the surface area on top then i'd have to sink even more, so the sump would have to be oversized just for powerloss issues.
07:17:18 <ski> mm
07:17:20 <ski> (UPS ?)
07:17:30 LaoJi joins (~LaoJi@156.252.21.210)
07:17:36 <edwardk> otoh, if i use a smaller sump and put it overhead, then the main display tank just has to sink the extra sump backflow
07:17:55 <edwardk> i have the UPS but if i lose power for more than a few hours the failure mode would be a flood
07:18:20 <ski> yeh
07:19:05 × [_] quits (~itchyjunk@user/itchyjunk/x-7353470) (Read error: Connection reset by peer)
07:20:06 <edwardk> so i've been carefully kitting things out so it overflows into a system with a couple of siphon fallbacks to drain down into the overflow, set up a ups so it can shut down the pumps gradually, blah blah blah
07:20:30 <edwardk> once the automated water changer comes online the whole thing will be controlled by an in wall panel
07:20:34 <edwardk> a bit overkill perhaps
07:20:35 [itchyjunk] joins (~itchyjunk@user/itchyjunk/x-7353470)
07:21:11 <edwardk> but you don't want an automated water changer to go wrong, or ... flooded house. same problem
07:22:38 <ski> (reminds me of someone, up in Canada, i think, who got their house (well, whole neighbourhood), flooded, a few years back, due to some water barrier that had been put up, then forgotten about for years)
07:22:44 <edwardk> figuring out the ozone system for the indoor system basically set me up for doing the same thing for the backyard pond. there i can use a wetland/bog filter and a huge 'foam fractionator' and should be able to get crystal clear water
07:22:48 × LaoJi quits (~LaoJi@156.252.21.210) (Quit: Client closed)
07:22:54 <edwardk> my old setup was dirty and nasty and i didn't know any better
07:23:24 <edwardk> but i _had_ to do better for the stingray, and after washy (the 28yo koi who died) passed away, i'm not going to subject any more koi to those kinds of conditions.
07:25:02 <edwardk> (freshwater stingrays are a recent biological adaptation in geological time, so they still have the osmotic regulation behavior of a saltwater fish... in otherwords, he pees a lot, so produces a ton of ammonia into the water column, but then he;s also super sensitive to it, because biologically they just haven't had time to adapt to the the amazon river basin converting to fresh water over time.) so if i don't keep the tank water super
07:25:02 <edwardk> clean he'll just die
07:25:18 <edwardk> but then koi are super messy fish too
07:25:37 <edwardk> so once it became clear that that was what i was signing up for, i basically had to science the heck out of it
07:26:40 <edwardk> the loaches can survive in anything, the koi can kind of do the same, but sirius, not so much
07:26:53 <ski> river basin, like at the delta ?
07:27:24 <ski> (or the area that's dewatered by the river ?)
07:27:54 <edwardk> black diamond stingrays are found in the Tapajós, Xingu and Tocantins basins in south america
07:28:18 <ski> mhm
07:28:28 ski tries to recall the term
07:28:44 <edwardk> just don't step on him, or he can put you in the hospital screaming in pain for a couple days
07:29:08 <edwardk> otoh he's super friendly
07:29:14 <ski> you handle him ?
07:29:19 <edwardk> and loves to be touched and hand fed
07:29:20 <edwardk> yeah
07:29:26 <ski> nice :)
07:29:49 × sabino quits (~sabino@user/sabino) (Quit: Lambda _ -> x)
07:30:44 <edwardk> 'like at the delta / in the bottom of the rivers'
07:31:37 <edwardk> there they are much more dangerous, because you can accidentally step on them in the muddy water and get stung and then the jagged barb and venom are a much bigger deal and are likely to get infected, etc.
07:31:55 acidjnk_new joins (~acidjnk@p200300d6e72b9380b928f2c2e25446fb.dip0.t-ipconnect.de)
07:31:56 <ski> (hm, guess i may've been thinking of "impluvium" or "drainage basin")
07:31:57 <edwardk> decided to adopt him on steve irwin day. didn't realize it at the time. crikey.
07:32:00 × benjaminl quits (~benjaminl@user/benjaminl) (Remote host closed the connection)
07:32:36 <ski> so, they're used to muddy water, then ?
07:32:53 benjaminl joins (~benjaminl@user/benjaminl)
07:32:58 <edwardk> well, in the rainforest you get water that has lots of tannins in it, so its darker brown and lower pH
07:33:19 <edwardk> i've been compensating by adding catappa leaves and mopani wood to the tank to leach tannins over time
07:33:54 <edwardk> and letting the oxidation levels i can achieve from the ozone handle most of the decoloration of the water that would usually ensue, and waterchanges handle the rest
07:34:29 <ski> (hm, may've also confused with "alluvial")
07:34:56 ski nods
07:35:07 <edwardk> they are happier on sand than in mud, but they have spiracles next to their eyes, which can let them beathe out of either below the disc or above the disc, letting them settle down into the substrate and still breathe even in mud or sand
07:35:57 <edwardk> in the wild they usually eat crustaceans out of the substrate, not very good at catching fish. they are electrosensitive, which compensates for the fact that they can't see below the disc
07:36:32 <ski> hm, some can send an electric shock, iirc ?
07:37:00 <edwardk> none of the freshwater kind can though
07:37:09 <ski> mhm
07:38:01 <ski> bloodworms are water worms ?
07:38:24 <edwardk> he's basically the smartest thing i can get my hands on that has a decent life expectancy. a cephalopod like a cuttlefish or octopi may be smarter, but you can't get anything that lives more than like 1.5-2.5 years that could be kept in a home aquarium at all, even an enormous one
07:38:48 <edwardk> because all the cephalopods are basically anti-social asshole escape artists that die after or during giving birth
07:39:14 <edwardk> yeah, red nasty little things, easily bought in frozen bulk from the fish store
07:39:14 <ski> hm, didn't know that
07:39:39 <edwardk> i adore cuttlefish, but i don't think i could take having basically a lifecycle pet like that
07:39:55 <edwardk> where you have have a few of them because they keep dying off sequentially
07:41:30 <edwardk> i'm not vegan but have enough vegan friends that i don't feel too bad about feeding sirius, because well bivalves have like 13 neurons, and the worms aren't _much_ smarter.
07:42:23 <edwardk> and he only really likes the bloodworms and clams anyways
07:43:03 <edwardk> but with octopi or cuttlefish i'd basically have to feed live
07:43:24 <ski> some birds use stones to crack open clams. or drop them from a high altitude
07:43:56 <edwardk> he's really figured out how to weaponize the glass of the aquarium for it. so much he keeps a corner of the aquarium bare for clam cracking duty
07:44:30 <ski> as long as it doesn't damage the glass, with repeated hammerings around the same spot
07:45:02 <edwardk> its tempered at least
07:53:36 <ski> well, time to sleep, perhaps (?)
07:54:43 <edwardk> yeah i should get a couple hours before my flight
07:54:47 <edwardk> wish me luck =)
07:55:02 <ski> good night, pleasant dreams. and good luch
07:55:04 <ski> luck
08:00:30 <petrichor> time for the western europe morning crew to pick up :D
08:04:05 <xerox> petrichor: sorry only had 1 goldfish as a kid and that was it
08:07:57 <petrichor> yeah, i just have a cat and recently also a dog, unless you also count the ramshorn snails in the pond
08:09:27 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
08:10:04 <edwardk> hah
08:10:16 <edwardk> i have a couple of cats too. the fish were sort of accidental
08:11:01 <edwardk> mostly its just that one of the cats likes to close my laptop whenever she detects me writing haskell
08:11:20 <edwardk> so far the fish have demonstrated more restraint
08:11:26 <edwardk> perhaps due to circumstances
08:11:49 <petrichor> kitty only permits imperative programming >_<
08:13:45 <petrichor> i would love to have a cephalopod friend but that would be way too much commitment with my level of executive functioning... XD
08:15:52 × peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 268 seconds)
08:18:23 <ski> "whenever she detects me writing haskell" -- heh, wonder how that happens :þ
08:26:12 fendor joins (~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c)
08:29:14 ski . o O ( "ceiling cat" <https://lambdacats.github.io/unsafeperformio/>,"simon cat" <https://lambdacats.github.io/fixed-in-head/>,"laptop" <https://lambdacats.github.io/multicore/> )
08:35:44 × maars quits (uid160334@id-160334.uxbridge.irccloud.com) (Quit: Connection closed for inactivity)
08:37:19 × azimut quits (~azimut@gateway/tor-sasl/azimut) (Ping timeout: 240 seconds)
08:39:29 <petrichor> presumably any time his hands are on the keyboard... :p
08:41:35 akegalj joins (~akegalj@78-1-124-77.adsl.net.t-com.hr)
08:49:02 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:11bf:d345:9651:e652) (Remote host closed the connection)
08:50:08 × tzh quits (~tzh@c-71-193-181-0.hsd1.or.comcast.net) (Quit: zzz)
08:54:56 × todi quits (~todi@p4fd1aa52.dip0.t-ipconnect.de) (Ping timeout: 245 seconds)
08:55:05 todi1 joins (~todi@p5dca55c4.dip0.t-ipconnect.de)
08:56:47 coot joins (~coot@89-69-206-216.dynamic.chello.pl)
09:00:47 lane joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
09:03:36 _ht joins (~Thunderbi@28-52-174-82.ftth.glasoperator.nl)
09:11:57 newsham joins (~newsham@2603-800c-2c01-6825-1466-59ff-d06f-d621.res6.spectrum.com)
09:12:29 <newsham> is there a way to tell haskell that a pattern match against an empty set cant happen?  or do you just omit it from the patterns in match and func defns?
09:12:49 <newsham> `f Void = ...`
09:14:19 × phma quits (phma@2001:5b0:210f:7288:e7e3:fefd:fd87:d9a3) (Read error: Connection reset by peer)
09:15:19 × econo_ quits (uid147250@id-147250.tinside.irccloud.com) (Quit: Connection closed for inactivity)
09:15:39 phma joins (~phma@2001:5b0:2143:b148:7b24:e989:5355:982f)
09:17:36 <tomsmeding> newsham: have you tried just omitting it?
09:17:45 <tomsmeding> the pattern match checker should be able to determine that the match is unnecessary
09:18:15 <tomsmeding> that is, _if_ the pattern is really unnecessary! Remember that haskell is lazy, so values may well be 'undefined' that is not yet evaluated, and you _do_ need to match those
09:18:43 <tomsmeding> if you're in this situation, a typical trick is writing 'f x = case x of {}' using EmptyCase
09:19:59 <tomsmeding> see the definition of 'absurd' in base: https://hackage.haskell.org/package/base-4.17.0.0/docs/src/Data.Void.html#absurd
09:20:13 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
09:21:14 <newsham> i would prefer to be explicit about it.
09:22:12 <newsham> `absurd` is what i want. thank you.
09:22:36 × bilegeek quits (~bilegeek@2600:1008:b049:5a95:99c5:8ca9:6c97:5a13) (Quit: Leaving)
09:22:58 <ski> `EmptyCase' would also work fine
09:24:14 <ski> (for a GADT matching, where some cases would be impossible in the current situation, you'd just omit those. if it's matching in the definiendums, though, you'd need at least one case left, or else it thinks you've forgotten to provide a definition)
09:24:17 × flounders quits (~flounders@24.246.176.178) (Quit: WeeChat 4.1.1)
09:25:09 <ski> Agda has an "absurd pattern", that can be used instead, in cases like this
09:26:23 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:1fe:ac5a:8c23:9cce)
09:28:06 <ski> conceptually, it's the neutral element of disjunctive / "or"- patterns. just like the wildcard pattern `_' is the neutral element of conjunctive patterns (`@' in haskell, generalized to allow an arbitrary pattern on both sides)
09:28:39 × harveypwca quits (~harveypwc@2601:246:c280:7940:585a:99af:3e4c:209b) (Quit: Leaving)
09:29:05 lane1 joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
09:29:30 igemnace joins (~ian@user/igemnace)
09:30:26 <newsham> yah thats what confused me because i started to use the agda syntax and couldnt remember the haskell syntax :)
09:30:51 <newsham> coprodUnitLeft :: Iso a (CoProd Zero a)
09:30:51 <newsham> coprodUnitLeft = IsoProof{ isoAB = unitLeft, isoBA = unUnitLeft }
09:30:52 <newsham>   where unitLeft = InR
09:30:52 <newsham>         unUnitLeft = uncoprod absurd id
09:31:26 <newsham> not that i know agda all that well but i was looking at agda code recently and i guess that syntax stuck in my head
09:31:36 <ski> yea, makes sense
09:31:39 × lane quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Ping timeout: 256 seconds)
09:32:28 <ski> personally, i write
09:32:36 <ski> foo ‾ = ‾
09:32:38 <ski> rather than
09:32:42 <ski> foo ()
09:35:01 LaoJi joins (~LaoJi@156.252.21.210)
09:35:17 × LaoJi quits (~LaoJi@156.252.21.210) (Client Quit)
09:35:33 <tomsmeding> fancy overline
09:36:56 × rosco quits (~rosco@175.136.152.56) (Quit: Lost terminal)
09:41:51 × acidjnk_new quits (~acidjnk@p200300d6e72b9380b928f2c2e25446fb.dip0.t-ipconnect.de) (Ping timeout: 256 seconds)
09:43:01 × tcard quits (~tcard@2400:4051:5801:7500:cf17:befc:ff82:5303) (Read error: Connection reset by peer)
09:43:27 tcard joins (~tcard@2400:4051:5801:7500:cf17:befc:ff82:5303)
09:44:14 <newsham> whats the preferred codepad for haskell these days?  i think hpaste and codepad went away?
09:44:26 todi1 is now known as todi
09:45:45 <ski> @where paste
09:45:45 <lambdabot> Help us help you: please paste full code, input and/or output at e.g. https://paste.tomsmeding.com
09:47:09 Simikando joins (~Simikando@adsl-dyn56.91-127-158.t-com.sk)
09:47:24 wootehfoot joins (~wootehfoo@user/wootehfoot)
09:48:24 <newsham> https://play-haskell.tomsmeding.com/saved/XlVvX7z6
09:57:16 × bollu quits (~bollu@159.65.151.13) (Quit: The Lounge - https://thelounge.chat)
09:57:50 bollu joins (~bollu@159.65.151.13)
09:57:58 <ski> s/coswap/mirror/
09:58:08 whatsupdoc joins (uid509081@id-509081.hampstead.irccloud.com)
09:59:19 <ski> no `prod :: (a -> b) -> (a -> c) -> (a -> Prod b c)',`coprodMap :: (a0 -> a1) -> (b0 -> b1) -> (CoProd a0 b0 -> CoProd a1 b1)' ?
09:59:52 × lane1 quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Ping timeout: 255 seconds)
10:01:28 <newsham> not yet i guess :)
10:01:48 × not_reserved quits (~not_reser@194.124.76.8) (Quit: Client closed)
10:03:29 <newsham> also didnt do `(a :+ b) : * c` yet
10:03:56 × m1dnight quits (~christoph@78-22-4-67.access.telenet.be) (Quit: WeeChat 4.1.0)
10:04:19 <ski> exponentials, too ?
10:06:02 <newsham> lots to do
10:06:17 danza joins (~danza@151.47.25.81)
10:07:24 <ski> data Proc a b = MkProc (a -> (b,Proc a b))
10:07:26 <ski> or
10:07:57 <ski> data Proc a b = forall s. MkProc (s,(s,a) -> (s,b))
10:08:25 <ski> in Charity, you define this something like
10:08:39 <ski> datatype s -> Proc a b
10:08:41 <ski> where
10:08:54 <ski> MkProc : s * a -> s * b
10:09:18 <ski> @where Charity
10:09:18 <lambdabot> http://pll.cpsc.ucalgary.ca/charity1/www/home.html
10:10:19 Tlsx joins (rscastilho@189.61.140.215)
10:12:24 × Tlsx quits (rscastilho@189.61.140.215) (Remote host closed the connection)
10:17:28 Lord_of_Life_ joins (~Lord@user/lord-of-life/x-2819915)
10:18:06 × Lord_of_Life quits (~Lord@user/lord-of-life/x-2819915) (Ping timeout: 252 seconds)
10:18:50 Lord_of_Life_ is now known as Lord_of_Life
10:19:15 × Simikando quits (~Simikando@adsl-dyn56.91-127-158.t-com.sk) (Ping timeout: 256 seconds)
10:19:25 m1dnight joins (~christoph@78-22-4-67.access.telenet.be)
10:25:18 idgaen joins (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
10:26:51 × wootehfoot quits (~wootehfoo@user/wootehfoot) (Quit: Leaving)
10:28:17 <danza> !bots
10:29:31 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 245 seconds)
10:30:24 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
10:30:42 machinedgod joins (~machinedg@93-136-130-2.adsl.net.t-com.hr)
10:33:32 <todi> !bots
10:33:57 <todi> !list
10:35:31 × machinedgod quits (~machinedg@93-136-130-2.adsl.net.t-com.hr) (Remote host closed the connection)
10:35:36 Simikando joins (~Simikando@adsl-dyn56.91-127-158.t-com.sk)
10:36:43 × m1dnight quits (~christoph@78-22-4-67.access.telenet.be) (Quit: WeeChat 4.1.0)
10:37:04 wootehfoot joins (~wootehfoo@user/wootehfoot)
10:38:02 m1dnight joins (~christoph@78-22-4-67.access.telenet.be)
10:38:15 machinedgod joins (~machinedg@93-136-130-2.adsl.net.t-com.hr)
10:39:35 × YoungFrog quits (~youngfrog@39.129-180-91.adsl-dyn.isp.belgacom.be) (Ping timeout: 264 seconds)
10:41:47 YoungFrog joins (~youngfrog@39.129-180-91.adsl-dyn.isp.belgacom.be)
10:42:29 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
10:42:29 finn_elija joins (~finn_elij@user/finn-elija/x-0085643)
10:42:29 finn_elija is now known as FinnElija
10:44:46 <edwardk> newsham: my preferred method is `f = \case`. and then just move on without proving any cases
10:46:31 <newsham> hey edk. you're still around. neat.  whats the backslash here?
10:46:57 nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net)
10:47:06 <newsham> oh, lambda.
10:48:54 <newsham> absurd :: Zero -> a
10:48:54 <newsham> absurd = \case
10:48:56 <newsham> cool thats easier
10:51:11 × akegalj quits (~akegalj@78-1-124-77.adsl.net.t-com.hr) (Quit: leaving)
10:51:23 <newsham> i guess you're saying you would just use '\case' in place of absurd.   gonna keep the absurd in there for my mental note for the time being.  not trying to make this super haskell looking (not using any of prelude even), just trying to do this from scratch in a way that reads cleanly to me for now.
10:51:37 × nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 255 seconds)
10:51:44 <edwardk> that is "LambdaCase" syntax
10:51:58 <edwardk> foo = \case [] -> ...; (x:xs) -> ...
10:52:09 sawilagar joins (~sawilagar@user/sawilagar)
10:52:17 <edwardk> it introduces a layout block like foo blah = case blah of
10:53:57 <newsham> yup, got it.
10:54:54 target_i joins (~target_i@217.175.14.39)
10:59:29 <newsham> i was watching some of your talks recently, inspirational.
10:59:29 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
11:00:18 <newsham> "i found other people had better ways of doing what I was doing... so I adopted their methods"
11:04:55 × m1dnight quits (~christoph@78-22-4-67.access.telenet.be) (Quit: WeeChat 4.1.0)
11:05:37 × alexherbo2 quits (~alexherbo@2a02-8440-b214-7d9d-8410-795e-9151-6da8.rev.sfr.net) (Remote host closed the connection)
11:06:10 Tlsx joins (rscastilho@189.61.140.215)
11:06:10 m1dnight joins (~christoph@78-22-4-67.access.telenet.be)
11:06:59 × machinedgod quits (~machinedg@93-136-130-2.adsl.net.t-com.hr) (Ping timeout: 260 seconds)
11:08:53 × Tlsx quits (rscastilho@189.61.140.215) (Remote host closed the connection)
11:10:13 alexherbo2 joins (~alexherbo@2a02-8440-b210-cea0-a800-a38a-3c94-a861.rev.sfr.net)
11:11:14 <tromp> AoC day 9 is literally a 3-liner in Haskell
11:11:26 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 256 seconds)
11:11:49 euleritian joins (~euleritia@dynamic-046-114-206-176.46.114.pool.telefonica.de)
11:12:40 Tuplanolla joins (~Tuplanoll@91-159-68-236.elisa-laajakaista.fi)
11:14:29 × Simikando quits (~Simikando@adsl-dyn56.91-127-158.t-com.sk) (Ping timeout: 240 seconds)
11:21:04 × yaroot quits (~yaroot@p3152107-ipngn5801souka.saitama.ocn.ne.jp) (Ping timeout: 256 seconds)
11:23:16 <ncf> zipWith subtract`ap`tail, the aztec god of discrete derivatives
11:24:26 <danza> % :t zipWith ((-) . ap . tail) -- type error
11:24:26 <yahb2> zipWith ((-) . ap . tail) -- type error ; :: Num ([a] -> [b]) => [[a -> b]] -> [[a] -> [b]] -> [[a] -> [b]]
11:24:47 <danza> was a bit too pessimistic ^^
11:25:09 <ncf> :t zipWith subtract`ap`tail
11:25:11 <lambdabot> Num c => [c] -> [c]
11:25:26 <danza> oh, thanks
11:26:03 × igemnace quits (~ian@user/igemnace) (Remote host closed the connection)
11:27:17 <srk> I can't decide if someRecordName_field or someRecordNameField :((
11:27:40 <danza> just `field` and some extensions
11:29:02 <srk> that was bad last time I've tried but I don't remember why
11:29:24 <srk> maybe due to lenses
11:29:35 <srk> danza: don't give me a third option! :D
11:31:17 yaroot joins (~yaroot@2400:4052:ac0:d901:1cf4:2aff:fe51:c04c)
11:33:41 tremon joins (~tremon@83.80.159.219)
11:34:16 danza is under the impression that third options are underrated
11:34:38 machinedgod joins (~machinedg@93-136-130-2.adsl.net.t-com.hr)
11:35:29 Simikando joins (~Simikando@adsl-dyn56.91-127-158.t-com.sk)
11:36:35 × euleritian quits (~euleritia@dynamic-046-114-206-176.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
11:36:53 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
11:37:06 <srk> there's also 4th like _someRecordName_field
11:37:45 <srk> consequences of any choice surface only after you try to generate lenses heh
11:37:47 <probie> I'm a fan of just `field` and `-XNoFieldSelectors` :p
11:39:46 × idgaen quits (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1)
11:41:05 <probie> and `-XDuplicateRecordFields`
11:41:26 × alexherbo2 quits (~alexherbo@2a02-8440-b210-cea0-a800-a38a-3c94-a861.rev.sfr.net) (Remote host closed the connection)
11:41:45 alexherbo2 joins (~alexherbo@2a02-8440-b210-cea0-a800-a38a-3c94-a861.rev.sfr.net)
11:43:07 mrd joins (~mrd@user/mrd)
11:44:29 × machinedgod quits (~machinedg@93-136-130-2.adsl.net.t-com.hr) (Ping timeout: 240 seconds)
11:46:41 × yaroot quits (~yaroot@2400:4052:ac0:d901:1cf4:2aff:fe51:c04c) (Read error: Connection reset by peer)
11:46:55 yaroot joins (~yaroot@p2987138-ipngn7501souka.saitama.ocn.ne.jp)
11:47:46 × wootehfoot quits (~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
11:52:03 × Sgeo quits (~Sgeo@user/sgeo) (Read error: Connection reset by peer)
11:55:30 [_] joins (~itchyjunk@user/itchyjunk/x-7353470)
11:55:55 igemnace joins (~ian@user/igemnace)
11:56:46 × krei-se quits (~krei-se@p5085dea2.dip0.t-ipconnect.de) (Ping timeout: 256 seconds)
11:58:59 × [itchyjunk] quits (~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 256 seconds)
11:59:08 krei-se joins (~krei-se@p5085dea2.dip0.t-ipconnect.de)
12:04:23 × danza quits (~danza@151.47.25.81) (Ping timeout: 260 seconds)
12:07:48 acidjnk_new joins (~acidjnk@p200300d6e72b9380b928f2c2e25446fb.dip0.t-ipconnect.de)
12:08:12 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
12:08:59 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
12:12:13 × m1dnight quits (~christoph@78-22-4-67.access.telenet.be) (Quit: WeeChat 4.1.0)
12:12:39 m1dnight joins (~christoph@78-22-4-67.access.telenet.be)
12:16:11 × Simikando quits (~Simikando@adsl-dyn56.91-127-158.t-com.sk) (Ping timeout: 264 seconds)
12:17:02 × m1dnight quits (~christoph@78-22-4-67.access.telenet.be) (Client Quit)
12:17:18 m1dnight joins (~christoph@78-22-4-67.access.telenet.be)
12:26:30 Simikando joins (~Simikando@adsl-dyn56.91-127-158.t-com.sk)
12:32:25 × Simikando quits (~Simikando@adsl-dyn56.91-127-158.t-com.sk) (Ping timeout: 255 seconds)
12:36:54 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
12:39:14 × mrd quits (~mrd@user/mrd) (Ping timeout: 250 seconds)
12:42:14 Simikando joins (~Simikando@adsl-dyn56.91-127-158.t-com.sk)
12:42:48 ht_ joins (~Thunderbi@194.110.115.49)
12:43:14 × _ht quits (~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Ping timeout: 256 seconds)
12:43:14 ht_ is now known as _ht
12:46:01 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 256 seconds)
12:46:14 euleritian joins (~euleritia@dynamic-046-114-206-176.46.114.pool.telefonica.de)
12:50:08 × driib quits (~driib@vmi931078.contaboserver.net) (Quit: The Lounge - https://thelounge.chat)
12:51:36 maars joins (uid160334@id-160334.uxbridge.irccloud.com)
12:51:49 waleee joins (~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
12:53:23 × newsham quits (~newsham@2603-800c-2c01-6825-1466-59ff-d06f-d621.res6.spectrum.com) (Quit: Client closed)
12:57:04 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
13:01:56 × sawilagar quits (~sawilagar@user/sawilagar) (Remote host closed the connection)
13:02:20 sawilagar joins (~sawilagar@user/sawilagar)
13:04:50 andreabedini joins (~andreabed@159.196.202.200)
13:07:41 gmg joins (~user@user/gehmehgeh)
13:08:47 driib joins (~driib@vmi931078.contaboserver.net)
13:15:49 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
13:22:07 Unhammer joins (~Unhammer@user/unhammer)
13:23:12 <Unhammer> Hi, "The Network.Wai.HTTP2 module was removed. " in 3.2.0 – how do I ensure I get HTTP2-support when doing Warp.run on a Wai.Application when running wai 3.2.3 ?
13:26:55 × andreabedini quits (~andreabed@159.196.202.200) (Quit: andreabedini)
13:28:08 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
13:29:53 pretty_dumm_guy joins (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655)
13:36:48 <Unhammer> Oh, hm if I use runTLS I get http2 with no other changes; maybe it just doesn't support h2c
13:41:34 × Simikando quits (~Simikando@adsl-dyn56.91-127-158.t-com.sk) (Ping timeout: 260 seconds)
13:45:03 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
13:55:01 <Unhammer> So that lets me locally reproduce my actual problem: I'm proxying server-sent events, and when running under tls1.2/http2, the browser will sometimes get "partial" chunks – anyone aware why this would happen?
13:55:03 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
13:55:11 <Unhammer> https://gist.github.com/unhammer/4edf172ef8ae7722232f16e5fb57ab71 is the haskell proxy code
13:55:33 <Unhammer> I'm requesting from the proxy from js, and then reading the response stream from js
13:56:00 <Unhammer> when going directly, I'm getting at least one full line at a time
13:56:13 <Unhammer> but when going via the proxy, it sometimes chops lines in the middle so they can't be parsed
13:56:59 <exarkun> Sure. HTTP bodies are not line-oriented. You need a proper parser if you have line-oriented data you want to extract from othem.
13:59:21 <exarkun> A really simple line parser is "append new data to the buffer, split the buffer on line separator, consume the successfully split prefix, save the suffix as the buffer, repeat"
13:59:36 <exarkun> but maybe you can find a better one in the javascript ecosystem
14:01:00 bienjensu joins (~user@user/bienjensu)
14:01:09 zzz joins (~z@user/zero)
14:02:28 zero- joins (~z@user/zero)
14:04:47 × zero quits (~z@user/zero) (Ping timeout: 260 seconds)
14:04:47 zero- is now known as zero
14:06:25 × zzz quits (~z@user/zero) (Ping timeout: 276 seconds)
14:07:58 <haskellbridge> 12<C​elestial> I have no idea how to use lenses idiomatically
14:08:30 <haskellbridge> 12<C​elestial> ```hs
14:08:31 <haskellbridge> 12<C​elestial> onTick :: ApplicationState -> ApplicationState
14:08:32 <haskellbridge> 12<C​elestial> onTick st'
14:08:34 <haskellbridge> 12<C​elestial>  | view paused st' = st'
14:08:35 <haskellbridge> 12<C​elestial>  | view (sort . finished) st' = st'
14:08:36 <haskellbridge> 12<C​elestial>  | Just z <- right $ view (sort . values) st' = set (sort . values) z st'
14:08:38 <haskellbridge> 12<C​elestial>  | otherwise = set (sort . finished) True st'
14:08:39 <haskellbridge> 12<C​elestial> ```
14:08:40 <haskellbridge> 12<C​elestial> this works but feels sloppy and i don't know what to do about it lol
14:09:00 <haskellbridge> 12<C​elestial> I can combine the top two guards but that's about it?
14:10:55 <[exa]> Celestial: you might need more operators
14:11:23 <[exa]> e.g. view (x.y.z) obj == obj ^. x.y.z
14:11:38 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
14:12:14 <[exa]> also if your ApplicationState is a State, you can use stuff like `sort.finished .= True`
14:12:33 <haskellbridge> 12<C​elestial> you mean `MonadState`?
14:12:42 <haskellbridge> 12<C​elestial> or whatever the typeclass is
14:12:47 <[exa]> yeah something like that
14:13:08 <haskellbridge> 12<C​elestial> it's not but I guess I could make it that?
14:13:41 <[exa]> like, you're passing the st' in anyway, so I guess a properly positioned runState or runStateT would do it
14:15:01 <[exa]> then you can go with the usual monadic helpers like unlessM (use paused) $ unlessM (use $ sort.finished) $ do ...
14:15:16 <[exa]> `use` = `view` from state
14:16:25 <haskellbridge> 12<C​elestial> Thanks!
14:16:25 azimut joins (~azimut@gateway/tor-sasl/azimut)
14:16:39 <haskellbridge> 12<C​elestial> I guess this is already better:
14:16:40 <haskellbridge> 12<C​elestial> ```hs
14:16:41 <haskellbridge> 12<C​elestial> onTick :: ApplicationState -> ApplicationState
14:16:42 <haskellbridge> 12<C​elestial> onTick st
14:16:44 <haskellbridge> 12<C​elestial>  | (st ^. paused) || (st ^. sort . finished) = st
14:16:45 <haskellbridge> 12<C​elestial>  | Just z <- right $ st ^. sort . values = set (sort . values) z st
14:16:46 <haskellbridge> 12<C​elestial>  | otherwise = st & sort . finished .~ True
14:16:48 <haskellbridge> 12<C​elestial> ```
14:17:35 × m1dnight quits (~christoph@78-22-4-67.access.telenet.be) (Quit: WeeChat 4.1.1)
14:17:38 <[exa]> btw pls pastebin :]
14:17:57 <[exa]> ah yeah I'd say this is already good enough
14:18:06 × lg1882 quits (~lg188@82.18.98.230) (Quit: Bye.)
14:18:26 <[exa]> with State you're simply going to trade off some `st` occurences for other things dragged in
14:18:41 <[exa]> might be useful if you did more state changes in 1 step
14:19:15 <haskellbridge> 12<C​elestial> I removed some of the spaces and it looks fine
14:19:18 <haskellbridge> 12<C​elestial> thanks again :)
14:20:49 <[exa]> kinda wondering, is there a good way to combine the patterns with monads
14:20:57 <[exa]> s/patterns/guards/
14:21:02 <haskellbridge> 12<C​elestial> Oh I just realized I get the state monad thing for free
14:21:22 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
14:21:38 <haskellbridge> 12<C​elestial> I was just using this as a hof which simply calls `modify tickHandler` in an `EventM`
14:22:01 <haskellbridge> 12<C​elestial> if I instead allow it to handle that itself and not force `modify` I can utilize all the state monad shenaningans
14:22:03 <haskellbridge> 12<C​elestial> amazing
14:22:38 <[exa]> ah the sublime feeling of things clicking together and glue disappearing
14:22:57 <haskellbridge> 12<C​elestial> haha indeed
14:23:10 <haskellbridge> 12<C​elestial> lens is still new to me
14:23:21 <haskellbridge> 12<C​elestial> but so is everything in haskell, really
14:23:29 azimut_ joins (~azimut@gateway/tor-sasl/azimut)
14:23:42 × azimut quits (~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection)
14:23:43 × cimento quits (CO2@gateway/vpn/protonvpn/cimento) (Quit: WeeChat 4.1.2)
14:24:38 cimento joins (CO2@gateway/vpn/protonvpn/cimento)
14:33:06 lg1882 joins (~lg188@82.18.98.230)
14:38:06 tomsmeding . o O ( what is the line count limit for the bridge to send stuff to the built-in pastebin )
14:39:31 × ft quits (~ft@p3e9bc784.dip0.t-ipconnect.de) (Remote host closed the connection)
14:40:50 × waleee quits (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 260 seconds)
14:40:57 billchenchina joins (~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe)
14:43:57 [_] is now known as [itchyjunk]
14:44:05 ft joins (~ft@p3e9bc784.dip0.t-ipconnect.de)
14:46:05 × euleritian quits (~euleritia@dynamic-046-114-206-176.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
14:46:22 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
14:48:30 nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net)
14:48:53 m1dnight joins (~christoph@78-22-4-67.access.telenet.be)
14:49:59 idgaen joins (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
14:51:42 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
14:52:22 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
14:53:52 × nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 276 seconds)
14:54:17 × kaskal- quits (~kaskal@2001:4bb8:2d2:5771:29a:c01c:fefc:78b5) (Quit: ZNC - https://znc.in)
14:54:22 × lg1882 quits (~lg188@82.18.98.230) (Ping timeout: 260 seconds)
14:54:37 kaskal joins (~kaskal@89.144.222.250)
14:54:48 <ephemient> [exa]: LambdaCase/MultiWayIf?
14:56:46 wootehfoot joins (~wootehfoo@user/wootehfoot)
14:57:01 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
14:57:54 × m1dnight quits (~christoph@78-22-4-67.access.telenet.be) (Quit: WeeChat 4.1.1)
14:59:43 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 276 seconds)
14:59:56 euleritian joins (~euleritia@dynamic-046-114-206-176.46.114.pool.telefonica.de)
15:00:03 m1dnight joins (~christoph@78-22-4-67.access.telenet.be)
15:00:06 Simikando joins (~Simikando@adsl-dyn56.91-127-158.t-com.sk)
15:02:52 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
15:06:04 ht_ joins (~Thunderbi@28-52-174-82.ftth.glasoperator.nl)
15:07:54 × _ht quits (~Thunderbi@194.110.115.49) (Ping timeout: 260 seconds)
15:07:54 ht_ is now known as _ht
15:12:16 <Unhammer> exarkun: i know, but the upstream server always sends full lines per chunk (if i print chunk in that gist i never see a split line, but on the js side i do)
15:14:05 <Unhammer> And i can't figure out if the issue is on the consuming or serving side, since it works fine with http1 / no tls
15:18:03 × notzmv quits (~zmv@user/notzmv) (Ping timeout: 260 seconds)
15:23:15 dhil joins (~dhil@2001:8e0:2014:3100:3783:1717:6803:631d)
15:29:39 <[exa]> tomsmeding: where do we find that
15:32:02 × wootehfoot quits (~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
15:32:11 × jmdaemon quits (~jmdaemon@user/jmdaemon) (Ping timeout: 256 seconds)
15:33:46 × gawen quits (~gawen@user/gawen) (Ping timeout: 256 seconds)
15:33:54 gawen_ joins (~gawen@user/gawen)
15:37:54 lg1882 joins (~lg188@82.18.98.230)
15:41:36 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
15:44:55 × cimento quits (CO2@gateway/vpn/protonvpn/cimento) (Quit: WeeChat 4.1.2)
15:49:54 × euleritian quits (~euleritia@dynamic-046-114-206-176.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
15:49:57 mechap joins (~mechap@user/mechap)
15:50:11 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
15:54:07 × Simikando quits (~Simikando@adsl-dyn56.91-127-158.t-com.sk) (Remote host closed the connection)
15:56:43 <ski> [exa] : i don't really think so
15:57:08 <ski> (well, i guess perhaps in my reflective syntax .. i should probably try to work some more on it)
15:59:43 × azimut_ quits (~azimut@gateway/tor-sasl/azimut) (Ping timeout: 240 seconds)
16:00:26 <tomsmeding> [exa]: I think you ask geekosaur :p
16:01:18 <ski> (sorry, re guards and monads, in case it was unclear)
16:02:21 Unicorn_Princess joins (~Unicorn_P@user/Unicorn-Princess/x-3540542)
16:04:27 <geekosaur> hm?
16:05:19 aruns joins (~aruns@user/aruns)
16:05:56 wootehfoot joins (~wootehfoo@user/wootehfoot)
16:06:05 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
16:06:15 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
16:06:33 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
16:12:28 <tomsmeding> geekosaur: what's the limit on the number of lines in a message before the bridge puts it in the built-in pastebin
16:13:40 <geekosaur> this bridge doesn't have a pastebin, sadly; it splits on lines and sends separate messages
16:13:52 <geekosaur> it's sent some pretty long things that way
16:13:59 <tomsmeding> ah I see
16:14:12 <tomsmeding> so ∞, then :)
16:14:23 <geekosaur> probably for the best as my machine isn't accessible from outside so the message would effectively disappear
16:14:37 <tomsmeding> oh lol
16:15:08 <tomsmeding> how does that work with matrix? Can you run appservices on a machine without a public IP as long as the matrix server it's attached (matrix.org, in this case?) to is publicly accessible?
16:15:20 <geekosaur> will be discussing with the infra team about getting a vm to run it on
16:15:38 <geekosaur> no, appservices need to run on the same machine as the homeserver
16:15:49 <geekosaur> matterbridge doesn't use an appserver
16:16:09 tomsmeding thought homeservers needed a public IP
16:16:28 <geekosaur> right, no homeserver here
16:16:47 <tomsmeding> then I clearly don't know enough about matrix stuff to be commenting on this :p
16:17:12 <tomsmeding> oh it's just a matrix client?
16:17:28 <geekosaur> matterbridge is dumb, it uses a dedicated account on each service and relays messages not from that account
16:17:32 <tomsmeding> which works because it's not plumbed, it's just a bot on both sides
16:17:33 <tomsmeding> _right_
16:17:36 <tomsmeding> okay makes sense
16:17:37 <geekosaur> otherwise it's just a normal matrix and irc client
16:17:53 <geekosaur> which makes it easy to set up but quite dumb
16:17:57 <tomsmeding> yep
16:18:24 <geekosaur> when I move it to a haskell.org machine I'm going to look at setting up a homeserver and heisenbridge as an appservice instead
16:18:41 <geekosaur> sadly, it still doesn't do puppeting, at least on the IRC side
16:18:48 <tomsmeding> meh
16:19:36 <geekosaur> the only bridge that does is EMS's appservice_irc, but that one won't be permitted for the same reason the original bridge went away
16:21:24 cimento joins (CO2@gateway/vpn/protonvpn/cimento)
16:21:40 <geekosaur> IRC puppeting is a lot of load and a lot of state in the bridge, and hard to get right
16:21:55 <geekosaur> and in particular a lot of load on libera's servers
16:22:13 <geekosaur> not that I'm planning to puppet 20,000+ users like EMS was
16:23:19 <geekosaur> it took like half an hour to reestablish IRC puppets every time they restarted the bridge
16:24:01 <geekosaur> it was much easier matrix-side because the homeserver retains the state for puppets the same way it does for ordinary users
16:31:14 Guest10 joins (~Guest10@ool-18bc2e74.dyn.optonline.net)
16:31:33 × shapr quits (~user@2600:1700:c640:3100:6b1f:4416:e400:c56a) (Ping timeout: 256 seconds)
16:32:25 × Guest10 quits (~Guest10@ool-18bc2e74.dyn.optonline.net) (Client Quit)
16:32:36 Guest10 joins (~Guest10@ool-18bc2e74.dyn.optonline.net)
16:44:44 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
16:44:57 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
16:45:33 × fendor quits (~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c) (Remote host closed the connection)
16:45:47 mikess joins (~sam@user/mikess)
16:46:06 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
16:55:20 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
17:00:12 arkoinad joins (~abhinav@c-67-169-139-16.hsd1.ca.comcast.net)
17:00:15 tri joins (~tri@ool-18bc2e74.dyn.optonline.net)
17:01:26 × billchenchina quits (~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe) (Remote host closed the connection)
17:01:44 billchenchina joins (~billchenc@103.152.35.21)
17:03:40 <tri> hello, test sending message
17:05:20 econo_ joins (uid147250@id-147250.tinside.irccloud.com)
17:05:45 <tri> instance Semigroup (Person [x] [y]) where (Person first1 last1) <> (Person first2 last2) = Person (first1 ++ first2) (last1 ++ last2)
17:05:48 <tri> data Trivial = Trivial deriving (Eq, Show)
17:06:20 <tri> sorry for spamming, just pasted a block of code into irssi and it auto sent...
17:07:32 <geekosaur> generally we don't paste code directly into IRC, it ends up a mess especially if someone else sends something in the middle of it
17:07:35 <geekosaur> @where paste
17:07:35 <lambdabot> Help us help you: please paste full code, input and/or output at e.g. https://paste.tomsmeding.com
17:09:01 <tri> thank you, i just installed irrsi and see if it can handle multiline chat. Clearly it cannot
17:09:19 <geekosaur> nope, IRC doesn't handle it
17:09:34 <geekosaur> it's an old protocol and not very smart
17:10:34 <tri> yea it striked me as odd when many haskellers choose IRC over slack or discord, guess im the younger generation haha
17:11:10 <geekosaur> there's a fairly large community on matrix also, #haskell:matrix.org
17:11:40 <geekosaur> and the FP discord, although I don't have a link for that off the top of my head
17:12:18 <tri> oh ok, I think I have ran into the FP discord before. That shouldn't be hard to look up
17:13:17 <monochrom> Slack Discord Matrix etc didn't even exist back then. There were only IRC, mailing lists, and newsgroups.
17:13:23 <dsal> I use slack and discord, but many in my generation find it odd to centralize communication onto a centralized proprietary service.
17:14:02 <monochrom> But it is true that it is now IRC and mailing lists that are dying. (newsgroups already did.)
17:15:28 <dsal> A few minutes ago, I looked up an old computer I'd bought in my email. The footer had a link that said "Check the status of this order anytime in your Google Checkout Account." The link was to checkout.google.com (NXDOMAIN). Lies.
17:17:10 <dsal> I have so many dead links to services that were cool for a bit, but now gone. So much good information in dead or closed services that you won't be able to find.
17:18:19 <[exa]> ski: yeah, monads vs guards :] actually recalled that I though about that already once and found that there wouldn't be many better solutions than something like `choice` + monadFail
17:18:19 <tri> @dsal i guess you are pointing out the reason as to why we use oos then
17:18:19 <lambdabot> Maybe you meant: keal eval
17:18:53 <[exa]> tri: @nick doesn't work on irc, we use just nick: (and even then it doesn't semantically mean anything, just some irc clients highlight messages that contain your nick)
17:18:53 <tri> oss i mean
17:19:26 <monochrom> That is also Richard Stallman's reason.
17:20:11 <tri> i just checked out Matrix and it seems like a better client for chatting, it at least has the chat history
17:20:16 <dsal> tri: Yeah. I like having things that work after companies die. :) I wrote my GoPro stuff because, while I greatly appreciate their unsustainably cheap storage, I assume they'll shut it down someday: https://dustin.sallings.org/2020/04/29/gopro-plus.html
17:20:26 <monochrom> Before he began, he was really scarred by a printer company going bust therefore no one could fix a bug in his printer's driver.
17:20:31 lane joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
17:21:01 <hc> Actually, it's Free Software, not oss ;-)
17:21:03 <dsal> I tried running a Matrix instance at one point and it seemed unnecessarily hard to get started.
17:21:04 <probie> tri: Lack of chat history is a feature
17:21:31 <geekosaur> luckily you don't need to run one, you can use an existing homeserver
17:22:12 <dsal> Back when I used to do stuff with xmpp, I could spin up my own servers and clients and stuff pretty easily and interact. I had all kinds of helpful XMPP services.
17:22:16 <tri> when i join irc, it's a clean slate, and personally I feel disconnected from the community because everyone can just use a new username everytime they join. And there is no history to retain my previous discussion
17:22:27 <geekosaur> I think they're planning to address rough edges in dendrite, but that's still in development
17:22:30 <monochrom> In line with this tangent, chat history is accessible until whoever maintains it goes bust. >:)
17:22:40 <tri> so it's like i don't get to know anybody
17:22:54 <dsal> tri: there's a history link in the discussion. Most of us have stable usernames. I've been connected for years and have my own local history for several channels.
17:23:05 <probie> The problem with the term "free software" is to people who aren't familiar with the term, you need to explain it means "free" as in "freedom"
17:23:07 <dsal> er, topic, not discussion. Brain wants to go outside.
17:23:07 <monochrom> But I don't use a new username every time I join.
17:23:07 <geekosaur> likewise
17:24:04 <monochrom> In fact, in the special case of libera, it has an account registering system, therefore encouraging people to be stable about their usernames.
17:25:22 <geekosaur> including reserving usernames so other people can't use them
17:26:45 <tri> i saw that, but im using irssi so it's a bit hard to get around
17:27:14 <monochrom> Then use hexchat. >:)
17:27:41 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
17:27:56 notzmv joins (~zmv@user/notzmv)
17:28:00 <tri> ok i'll check it out, im just looking for something user friendly
17:28:44 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 252 seconds)
17:28:45 <geekosaur> hexchat will be much friendlier than irssi, which is really intended for people comfortable with the command line
17:29:00 euleritian joins (~euleritia@dynamic-046-114-206-176.46.114.pool.telefonica.de)
17:29:14 <geekosaur> there's also KDE's Konversation, an IRC plugin for Thunderbord Mail if you use that, etc.
17:29:28 <tri> oh hexchat is not on Mac
17:29:33 <geekosaur> Quassel, Textual for Macs, etc.
17:29:41 <geekosaur> you want Textual then
17:29:47 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:1fe:ac5a:8c23:9cce) (Remote host closed the connection)
17:30:02 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:1fe:ac5a:8c23:9cce)
17:31:24 <monochrom> probie: "The Free Left" is now how I remember that in the free-forgetful adjunction, free is on the left. >:)
17:32:08 tri_ joins (~textual@ool-18bc2e74.dyn.optonline.net)
17:32:08 <tri_> tseting on textual
17:32:25 <monochrom> "Now there are two of them!"
17:33:30 <tri_> dsa: now i need to figure out how to get the chat history
17:34:21 lane1 joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
17:34:37 azimut joins (~azimut@gateway/tor-sasl/azimut)
17:34:46 <tri> can anyone tell me how to retain or at least view the chat history please
17:35:28 <monochrom> If you see the "topic" line or box, it has a lot of stuff, and there is a website holding logs by a volunteer.
17:36:29 <tri_> oh it's literally called logs
17:36:31 <geekosaur> IRC doesn't keep logs. Matrix does
17:36:51 × lane quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Ping timeout: 256 seconds)
17:36:55 <tri_> alright thank you everyone, you are really helpful
17:37:04 <geekosaur> Various channels have their own log bots
17:37:35 <monochrom> In general this is IRC culture: 1. Global history is unimportant. 2. If you want to save up things when you are online, tell your software to do it yourself.
17:38:32 <tri> gotcha
17:39:02 <monochrom> I won't insist that this is the only right way, but I will insist that other ways are not more right. This is just another endian question.
17:39:17 <[exa]> tbh I find it quite healthily similar to how people talk normally
17:39:35 <int-e> monochrom is always fighting the holy war
17:39:38 <[exa]> 1] global history wth, 2] you can carry a tape recorder :D
17:40:10 <tri> [exa]: that's a good way to think about it
17:40:54 waleee joins (~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
17:41:01 <[exa]> tri: as a result you won't ever do this "three hour search in slack workspace history on the cool link that you just cannot find"
17:41:06 <[exa]> it's just lost™ :D
17:41:17 <[exa]> time = saved
17:42:24 <monochrom> Yeah we don't mind answering a question for the second time where the first time was like 5 years ago :)
17:42:42 hamess parts (~hamess@user/hamess) (WeeChat 4.1.2)
17:42:56 <[exa]> ski: ........contemplating more on the previous -- given we've got this special syntax for `guard` and `fail`, I guess eventually adding `choice` to the mix wouldn't hurt too much, right.
17:43:44 × euleritian quits (~euleritia@dynamic-046-114-206-176.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
17:44:03 euleritian joins (~euleritia@77.22.252.56)
17:44:34 × coot quits (~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
17:44:48 tzh joins (~tzh@c-71-193-181-0.hsd1.or.comcast.net)
17:45:10 Joao003 joins (~Joao003@190.108.99.32)
17:47:00 <ski> tri : some reasons to prefer IRC : anyone can make clients; there isn't any single organization in control of the protocol; no officially blessed public logging/history; no inline images, sound clips, videos, page previews; less heavy on resources
17:47:04 <ski> tri : "everyone can just use a new username everytime they join" -- except you can register your nickname. and regulars tend to stick mostly to one or a few nicknames
17:47:51 <tri> gotcha
17:48:14 <tri> anyway i can filter out the joined and quit logs?
17:48:21 <tri> they are just noise
17:48:38 <ski> some clients support that
17:48:41 ski prefers not to
17:49:39 ski would not be surprised if Textual,Quassel,HexChat,Irssi all had ways to do that
17:49:42 <[exa]> tri: most clients support pretty wide /ignore syntax, something like /ignore * joins parts quits
17:49:47 <[exa]> your manual may vary
17:50:07 <geekosaur> https://help.codeux.com/textual/Frequently-Asked-Questions.kb#
17:50:28 <ski> [exa] : the `guard' one bineg ?
17:50:31 <slideshow6052> hi
17:50:35 <ski> lo slideshow6052
17:50:44 <slideshow6052> ayy
17:50:55 <[exa]> ski: in the list comprehensions
17:50:59 × euleritian quits (~euleritia@77.22.252.56) (Ping timeout: 264 seconds)
17:50:59 <ski> right
17:51:03 <geekosaur> hm, that was kinda useless, it's apparently javascript instead of an actual link
17:51:08 <ski> (monad comprehensions)
17:51:14 <[exa]> (also)
17:51:52 euleritian joins (~euleritia@dynamic-046-114-206-176.46.114.pool.telefonica.de)
17:51:58 <slideshow6052> is there a built in function which takes [a->a] and an a and keeps applying it?
17:52:04 <slideshow6052> i tried hoogle but i didnt find
17:52:10 <slideshow6052> but it seems like it should be there
17:52:57 <ski> i usually call that `compose', defined as `foldr (.) id' or `flip (foldr ($))'
17:53:26 <slideshow6052> i mean sometihng like g (f:fs) x = g fs (f x)
17:53:32 <slideshow6052> ah i see
17:54:12 × Guest10 quits (~Guest10@ool-18bc2e74.dyn.optonline.net) (Quit: Client closed)
17:54:20 <ski> ok, sounds like you're looking for `foldl (.) id' / `flip (foldr (&))', then
17:54:42 <ski> `revCompose', i guess you could call it
17:55:18 <ski> (er, `flip (foldl (&))', i meant)
17:56:12 <ski> although .. i suppose it would probably make more sense to use foldl' for this, given that we will be bulky in the list regardless
17:56:14 <[exa]> slideshow6052: kinda sounds like `fix` tbh
17:56:28 <[exa]> ah I missed hte []
17:56:41 <ski> @type iterate
17:56:42 <lambdabot> (a -> a) -> a -> [a]
17:58:25 <[exa]> :t ala Endo foldMap --- do we have this loaded?
17:58:26 <lambdabot> Foldable t => t (b -> b) -> b -> b
17:58:36 <[exa]> yay!
17:58:51 <ski> @type flip (scanl (&))
17:58:52 <lambdabot> [a -> a] -> a -> [a]
17:59:29 <Joao003> context?
17:59:45 <ski> composing a list of functions
18:00:10 <ski> [exa] : how would the `choice' work ?
18:00:23 <Joao003> oh so like you have a list and you run each of them in order on an argument?
18:00:43 <ski> <slideshow6052> is there a built in function which takes [a->a] and an a and keeps applying it?
18:01:46 × wootehfoot quits (~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
18:02:04 <Joao003> applyAll but it applies from the last function to the first function
18:02:21 <Joao003> @type applyAll
18:02:22 <lambdabot> error: Variable not in scope: applyAll
18:02:25 <Joao003> ...
18:02:31 <Joao003> in diagramslib
18:02:33 <Joao003> ...
18:02:39 wryish joins (~wryish@216.246.119.62)
18:02:46 <Joao003> hoogle sucks when you're trying to find in prelude only
18:03:24 <ski> @hoogle applyAll
18:03:24 <lambdabot> Diagrams.Util applyAll :: [a -> a] -> a -> a
18:03:37 <ski> is basically `compose'
18:03:45 <Joao003> @type compose
18:03:45 <lambdabot> error:
18:03:46 <lambdabot> • Variable not in scope: compose
18:03:46 <lambdabot> • Perhaps you meant one of these:
18:04:18 <ski> @let compose :: [a -> a] -> (a -> a); compose = foldr (.) id
18:04:19 <lambdabot> Defined.
18:04:48 <Joao003> @type foldl1 (flip ($))
18:04:49 <lambdabot> error:
18:04:49 <lambdabot> • Occurs check: cannot construct the infinite type: a ~ a -> a
18:04:49 <lambdabot> Expected type: a -> a -> a
18:05:04 <Joao003> @djinn [a -> a] -> a -> a
18:05:04 <lambdabot> Error: Undefined type []
18:05:09 <Joao003> .
18:05:21 <geekosaur> djinn doesn't do recursive types, sadly
18:05:24 <ski> i'd argue that `compose' is more generally useful than `revCompose', since the former will work on infinite lists (and will be incremental, for long finite lists, if you pass in an incremental callback), while `revCompose' won't
18:05:33 <ski> Djinn doesn't understand lists
18:05:48 <ski> @type foldl (&)
18:05:49 <lambdabot> Foldable t => a -> t (a -> a) -> a
18:06:23 <Joao003> @type flip (foldl (&))
18:06:24 <lambdabot> Foldable t => t (c -> c) -> c -> c
18:06:41 × pavonia quits (~user@user/siracusa) (Quit: Bye!)
18:06:47 <ski> @type foldl (flip (.))
18:06:48 <lambdabot> Foldable t => (a -> b) -> t (b -> b) -> a -> b
18:06:54 <ski> @type foldl (flip (.)) id
18:06:55 <lambdabot> Foldable t => t (b -> b) -> b -> b
18:07:55 <Joao003> > flip $ foldl $ (&) [*3, +4] 4
18:07:57 <lambdabot> error:
18:07:57 <lambdabot> A section must be enclosed in parentheses thus: (* 3)error:
18:07:57 <lambdabot> A section must be enclosed in parentheses thus: (+ 4)
18:08:04 <Joao003> > flip $ foldl $ (&) [(*3), (+4)] 4
18:08:06 <lambdabot> error:
18:08:06 <lambdabot> • Could not deduce (Num a0)
18:08:06 <lambdabot> from the context: (Foldable t, Num a,
18:08:19 <Joao003> > flip (foldl (&)) [(*3), (+4)] 4
18:08:20 <lambdabot> 16
18:08:26 <Joao003> works!
18:08:39 <ski> yea .. was just about to say to quit the `$'s
18:09:14 <ski> > flip (scanl (&)) [(3 *),(4 +)] 4
18:09:16 <lambdabot> [4,12,16]
18:09:41 <Joao003> scanl gives you a list of partial results
18:09:57 <ski> yes (off-by-one, one could say)
18:10:02 <Joao003> so that's what you want?
18:10:18 <ski> ask slideshow6052 ?
18:10:50 <slideshow6052> oh for now i just used f (x:xs) t = f xs (go t x); f [] t = t
18:11:00 <slideshow6052> i need to improve this all later my code is very bad
18:11:01 <ski> and `go' ?
18:11:23 <tri> i already install a package by cabal install, how do i use it in my source file to later use in ghci? Do i need to cabal init it?
18:11:24 <slideshow6052> go is defiuned somewhere else
18:11:31 <slideshow6052> but look i just got it working isn't this cool
18:11:33 <ski> mhm
18:11:40 <Joao003> can you show us `go'?
18:11:40 <slideshow6052> ghci> runner (Lam X (Lam Y (Var Y)))
18:11:40 <slideshow6052> \X. \Y. Y : (a -> (b -> b))
18:11:52 <slideshow6052> basic type inference thingy
18:12:34 <ski> slideshow6052 : you may want to make sure that `f' is strict in `t'
18:12:52 <Joao003> if you still code like this: f (x:xs) t = f xs (go t x); f [] t = t
18:12:58 <Joao003> you might need to learn about folding
18:13:13 <ski> slideshow6052 : also, (unless `runner' is in `IO'), i'd suggest not using `Show' like that
18:13:44 <slideshow6052> runner is M -> IO ()
18:13:59 <ski> ok, ignore that comment, then :)
18:14:04 <slideshow6052> yes my code is very bad atm
18:14:08 <slideshow6052> i still need to learn lots
18:14:16 <Joao003> i can help!
18:14:17 <slideshow6052> one sec i will go eat and then tidy it a bit and post it on here
18:14:34 <slideshow6052> and then you guys can suggest if you are not cringing at it too much haha
18:14:44 <slideshow6052> thank you
18:14:53 <Joao003> ^_^
18:15:20 <monochrom> tri: There are two ways, depending on how toy your use case is. More toy: You have to include "--lib" in "cabal install --lib", then you can use it in raw ghci. More productional: Forget "cabal install", use "cabal init" and edit the *.cabal file to list dependencies.
18:15:51 × forell quits (~forell@user/forell) (Quit: ZNC - https://znc.in)
18:16:08 forell joins (~forell@user/forell)
18:16:45 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
18:16:59 <tri> so i need to import that lib in to a haskell file first, and then will load that hs file into ghci
18:17:24 <tri> so i used cabal install, is it ok to use wihtout the --lib flag?
18:17:49 <tri> anyway, my hs file (i didn't use cabal init) complains that it doesn't see the lib when import
18:17:55 <monochrom> It is harmless. It just almost doesn't do anything.
18:18:11 <tri> im using the QuickCheck library
18:18:18 <tri> so i cabal install QuickCheck
18:18:23 <monochrom> Yeah you need --lib for libraries.
18:19:18 <tri> right, i saw the cabal install log to suggest using --lib so i ran it again with cabal install --lib QuickCheck. This time it says Resolving Dependencies.. Up to date
18:19:26 <tri> so clearly it's already on my system
18:19:29 <monochrom> Omitting --lib means you just want the executables. Well, QuickCheck comes with no executables. So vacuous success and nothing is done. :)
18:19:43 <tri> yea
18:19:52 <tri> I also see the package installed in .cabal directory
18:20:00 <tri> so that's on my system
18:20:14 <tri> but why my haskell file doesn't see it
18:20:20 <sclv> the lib flag should have added it to the ghc env file
18:20:29 <sclv> try and see if it works
18:20:46 <monochrom> In the Haskell code, you say "import Test.QuickCheck" etc.
18:21:13 <monochrom> At this point, you realize that package name ≠ module name because package ≠ module.
18:21:36 <monochrom> Soon you will discover many more levels of bureacracy than this. >:)
18:21:36 <tri> import Test.QuickCheck and import QuickCheck both squawked at me
18:22:15 <tri> monochrom: yes, im reading a book which use cabal sandbox, which is now removed from cabal so it's driving me crazy to figure cabal out
18:23:15 <tri> anyway, now i installed QuickCheck already, but hs file is not seeing it on import, where else do i need to configure this QuickCheck library?
18:23:15 <sclv> if you always use cabal packages and projects for development you need never call cabal install
18:23:23 <Joao003> What's your cabal version?
18:23:26 <monochrom> cabal sandbox commands can be easily mapped to today's cabal commands. So you don't have to give up the *.cabal file way.
18:23:33 <sclv> how are you loading the file? ghci or cabal?
18:23:44 <tri> i use ghci
18:24:06 <tri> and i am writing code in a .hs file, which later will be loaded into ghci
18:24:25 <tri> my cabal version is 3.6.2.0
18:25:39 <tri> can someone help me? adding a package must not be this hard...
18:26:18 × pastly quits (~pastly@gateway/tor-sasl/pastly) (Remote host closed the connection)
18:26:20 <sclv> cabal install —lib should have updated a ghc environment file to enable ghci to find the lib
18:26:41 <sclv> if thats not happening you should look at the env file, and the output of the install lib cmd
18:26:42 pastly joins (~pastly@gateway/tor-sasl/pastly)
18:26:52 <sclv> or just use a package as we recommend!
18:27:34 <tri> what's the ghci env file name?
18:27:41 <Joao003> i'm here after a long break from haskell, can you challenge me so i can see if i forgot some stuff?
18:28:28 <tri> sclv: and also what do you recommend again?
18:29:00 <sclv> when you launch ghci it will tell you the env file it is loading
18:29:07 ACuriousMoose joins (~ACuriousM@142.166.18.53)
18:29:45 <tri> sclv: yea i see quickcheck is mentioned in the env file
18:29:48 <sclv> what we recommend is creating a package by running “cabal init” and adding your deps to the deps of that package, then developing that package. then you never need to manage deps manually
18:30:08 <sclv> ok if quickcheck is in the env file, then loading a file using it with ghci should now work
18:31:37 <tri> sclv: yea i can loads into ghci now, BUT the hs file still have compile error. Meaning, the language server doesn't see the package
18:31:41 <monochrom> I think I should see the exact error message first.
18:31:45 <tri> ok
18:31:49 <tri> i will screenshot
18:32:04 <sclv> use the pastebin in the channel desc
18:32:14 <monochrom> Oh language server. I don't know how to get that to work. I don't use it.
18:32:19 jle` joins (~jle`@2603-8001-3b02-84d4-bd21-edb6-1dc1-99d4.res6.spectrum.com)
18:32:23 <sclv> https://paste.tomsmeding.com/
18:32:58 <sclv> language server doesn’t work well with random files. you need a package for it
18:32:59 <tri> monochrom: you are telling me you don't rely on real-time feedback of the language server? and have to compile the code to see where errors are??
18:33:06 Guest0 joins (~Guest0@31.193.221.194)
18:33:38 <tri> like you guys just type in the text editor blindly without any syntax checking???
18:33:45 <monochrom> I use emacs and its haskell-mode, it's just a ctrl-c ctrl-r away.
18:33:51 <sclv> most seasoned haskellers do. we’ve been writing well before there were ides
18:34:12 <tri> mother of god...
18:34:19 <Joao003> tri: (´°o°)´ =⊥_⊥
18:34:43 <tri> you guys are hardcore...
18:34:50 <sclv> we out here, just rawdogging syntax.
18:34:59 <tri> it's like hiking with bare feet
18:35:08 <monochrom> NO
18:35:19 <monochrom> It's merely like hiking without jetpack.
18:35:22 <Joao003> we don't use ides, we use NOTEPAD
18:35:43 <tri> ok, notepad is too far
18:35:51 <monochrom> My analogy is deliberate. It is a roast. Jetpack defeats the point of hiking.
18:35:53 <Joao003> NOTEPAD and GHCI
18:36:12 <slideshow6052> ok i am back
18:36:22 <yushyin> i use C-x M-c M-butterfly
18:36:23 <slideshow6052> and here to be roasted
18:36:29 <yushyin> like a real programmer
18:36:52 <Joao003> Think of syntax highlighting as that smart kid in class who knows everything
18:37:13 <slideshow6052> here is the code https://paste.tomsmeding.com/jkKXglCM
18:37:20 <slideshow6052> please give feedback/advice
18:38:33 <monochrom> What's wrong with IDEs is they solve the symptom not the root problem.
18:38:55 <tri> ok i will try cabal init now.
18:39:14 <Guest0> Hey, I wanted to ask if there is a way to comunicate with the os without having to rely on FFI, to do things like opening sockets without third party libs.
18:39:50 TheCatCollective joins (NyaaTheKit@user/calculuscat)
18:40:13 <monochrom> And therefore we will still be stuck with "plain text files" for another decade.
18:40:30 <[exa]> Guest0: does libc count as "third party lib" ?
18:41:22 <Joao003> ô_ǒ
18:41:23 <[exa]> Guest0: or, like, do you want to do the syscall directly yourself? (that would be possible but not easily at all :D )
18:41:51 <Guest0> Yeah i was thinking about the syscall
18:42:33 <[exa]> tri: btw I was trying some of the haskell IDE possibilities but in the end just editing stuff without disturbance and then calmly reading the ghc output to find about what's wrong turned out to be most productive
18:43:33 <Joao003> [exa]: Ü
18:43:34 <monochrom> Well, my students use vscode and hls, it's really helpful to them, they have shown me what it looks like.
18:43:42 <monochrom> I just don't need that much handholding.
18:44:04 <slideshow6052> i like ghicd
18:44:08 <monochrom> I need a little bit of aid and handholding, but not that much.
18:44:15 <[exa]> like, I might have some attention disorder or so but I tend to be quite disturbed by the stupid IDE tricks like "you certainly wanted to write this other parenthesis, here it is for you!" and "you didn't finish writing yet, lemme put a thiiiiiiiiick red warning all over the place"
18:44:24 <slideshow6052> it runs ghci in another terminal and refershes each time you write the file
18:44:51 <monochrom> I need to be told my errors, yes. But it's just a hot key away, I don't need it real time.
18:44:51 <slideshow6052> but i am not good at haskell so my opinion is not that relevant
18:45:11 <monochrom> I need auto-completion, yes. But it's just a hot key away, I don't need it real time.
18:45:24 <[exa]> Guest0: well that might require you to somehow put stuff into the output of c--, i.e. to pipe the description of your syscall all the way through Core, STG and other language layers
18:45:54 <[exa]> Guest0: tbh having a tiny FFI'd urchin instead will just help (also for making sure that stack behaves as the (expected) C stack etc.)
18:46:12 <Guest0> where can I read more about it?
18:46:33 <[exa]> good question. :D
18:46:45 <[exa]> people usually don't want to do this with haskell so you might need darker magicks
18:46:58 × pastly quits (~pastly@gateway/tor-sasl/pastly) (Remote host closed the connection)
18:47:02 <monochrom> And I certainly don't appreciate how the hi-tech way also comes with the hi-brow ideology that insists on packages and "project"s.
18:47:20 pastly joins (~pastly@gateway/tor-sasl/pastly)
18:47:23 <[exa]> Guest0: if no one responds here I'd try in #ghc and ask for pointers
18:47:26 <monochrom> Everything is not a package. Everything is not a project.
18:47:56 <glguy> slideshow6052: I use ghcid - especially when doing advent of code problems. I have it using -r so that my solutions run every time I save
18:47:57 <Guest0> Thanks a lot :)
18:48:10 <[exa]> monochrom: "apparently you weren't able to set up your project, here, try copilot to help you set up your project 50000% faster"
18:48:24 <geekosaur> the problem with doing linux syscalls directly is they change a lot. glibc hides this for you and knows which syscall to use with which kernel
18:48:44 dsrt^ joins (~cd@c-98-242-74-66.hsd1.ga.comcast.net)
18:49:09 <int-e> [exa]: have we gone meta yet? "how to structure your project to get the most out of copilot"?
18:49:23 ski . o O ( "It looks like you're trying to write Smalltalk in Haskell; here, let me helpfully translate your program to Smalltalk and fire up Squeak for you." )
18:50:00 nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net)
18:50:04 <int-e> copy-lot
18:50:14 <[exa]> Guest0: on a very side note, if you just want to play with it, I've got my stupid-but-working assembly project here and it can certainly do syscalls from haskellish lazy evaluation directly: https://gitea.blesmrt.net/exa/uskel
18:50:55 <Guest0> Yeah I'll take a look
18:51:16 × bienjensu quits (~user@user/bienjensu) (Ping timeout: 246 seconds)
18:51:41 <[exa]> int-e: that reminds me that stupid note I saw in nature the last week.... here https://www.nature.com/articles/d41586-023-03739-3
18:51:46 <ski> slideshow6052 : right. i'd not use `Show' like that
18:52:33 <int-e> [exa]: Perfect, I'll take it. (It's a different niche, of course.)
18:53:25 <monochrom> Speaking of copi vs copy, when I was reading a Unix book a long time ago and when it came to uucp, it said "Unix-to-Unix CoPy", and for a decade I separated that into Co Py and wondered what it meant.
18:53:41 <ski> slideshow6052 : `Show' is for generating a string representation of *Haskell* code that, in the appropriate environment, will evaluate to an equal value. different `Show' instances are intended to work together. if we use `show' on `Maybe Lam', the result will be a mix of Haskell and non-Haskell
18:55:01 × nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 276 seconds)
18:57:12 <[exa]> Guest0: it's unlikely to be useful for anything practical, take the label "if you just want to tinker with stuff" seriously :D
18:57:42 <monochrom> Rust is great at explaining the Show business, by starting off with two classes instead of one, becasue "print it out for normal output" is different from "print it out for debugging messages".
18:57:57 <ski> slideshow6052 : even disregarding that, you should not be defining `show' for recursive datatypes, you should be defining `showsPrec', because (a) efficiency; and (b) handling brackets (which you do not do at all, currently, so your output is broken). anyway, if you want to pretty-print, define your own function for that, please don't use `Show' for pretty-printing or custom output format
18:59:04 <slideshow6052> ah i see
18:59:10 <monochrom> or rather, "for users" vs "for another programmer".
18:59:21 <slideshow6052> yeah i was using the repl a lot and got annoyed by Arr t1 t2 instead of t1 -> t2
18:59:27 <slideshow6052> But youre right, i'll change that
18:59:34 <slideshow6052> also what do you mean by handling brackets?
18:59:49 <ski> slideshow6052 : you should probably use `data Substitution = Subst Int T deriving Show', mapping only (ids of) tyvars to types
18:59:57 <monochrom> "(x -> y) -> z" vs "x -> (y -> z)"
19:00:11 <ski> (also, "substitution" usually means not just a single mapping, but potentially mapping many identifiers to things)
19:00:38 <ski> monochrom : yea, they actually handled that case correctly (although redundantly, given right-associatedness of `->')
19:01:08 <slideshow6052> oh yep good point
19:01:09 <ski> slideshow6052 : `App (App Tru Tru) Tru' and `App Tru (App Tru Tru)' will display the same
19:01:27 <monochrom> Well, the issue becomes very accute when you have two infix operators. "x -> y * z".
19:02:19 <slideshow6052> are you using backticks by any chance? because my irc client i think automatically turns those into monospace but it looks weird with your message
19:02:23 <monochrom> at which point, you will eventually come to appreciate showsPrec, one way or another.
19:02:23 × Guest0 quits (~Guest0@31.193.221.194) (Quit: Client closed)
19:02:39 <haskellbridge> 12<C​elestial> Do I need to list all the modules my program has under `other-modules` in the cabal file or can I somehow tell it to take every file under the hs-source-dir?
19:02:58 <ski> slideshow6052 : i'm using TeX-style quotes, yes
19:02:58 <slideshow6052> oh right i see
19:03:06 <geekosaur> Celestial, you need to list all of them
19:03:29 <monochrom> Currently you have to list them all. A future cabal version plans to offer a wildcard syntax.
19:03:45 pagnol joins (~user@2a02:a210:a3c:b00:3e0f:bab7:90e2:2f26)
19:03:59 × erty quits (~user@user/aeroplane) (Ping timeout: 268 seconds)
19:04:10 <haskellbridge> 12<C​elestial> thanks, it's getting quite annoying to explicitly list all of them even though its "just" like 10 modules
19:04:28 <pagnol> Hi, would anyone happen to have a snippet that shows how to set up lsp with Haskell in (vanilla) Emacs?
19:04:47 <monochrom> "cabal sdist" is why some kind of "other-modules:" is necessary. (Wildcard or not being an orthogonal question.)
19:04:56 <slideshow6052> ah i see
19:06:17 __monty__ joins (~toonn@user/toonn)
19:06:21 <slideshow6052> i heard that using explicit recursion is less preferable to folds. for example, i list out the same cases for substTy, fv, and tvars. but how can i improve this?
19:06:46 <monochrom> I don't believe in that religion.
19:07:23 <monochrom> You and whoever you work with define what's elegant, then code to that.
19:07:43 <monochrom> The religion I believe in is simply "write for your audience".
19:08:06 <ski> slideshow6052 : in your `compose', i suppose i'd put the new element at the front, rather than at the back. also, in `go', i think you probably want to substitute everywhere inside y' .. not just check if it's itself a tyvar, and then substitute
19:08:15 <monochrom> OK, the other religion I believe in is "learn everything, know your options", so learn both ways and appreciate them.
19:08:32 <ski> slideshow6052 : i'd also use an accumulator for `fv'
19:08:39 × euleritian quits (~euleritia@dynamic-046-114-206-176.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
19:08:58 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
19:10:45 <ski> slideshow6052 : ditto for `tyvars' .. also, i think `rename' can run into trouble, since it's not doing simultaneous substitution
19:12:31 <slideshow6052> sorry to be a pain but would you mind using normal quotes or symmetric backticks instead? because the message atm is matching your opening and closing backticks and looks weird
19:12:58 <slideshow6052> i was following along with a lecture and that's the way we showed it so that's why i kept it at the back in compose
19:13:25 <ski> slideshow6052 : perhaps `unify' should fail gracefully, instead of `error'ing out on mismatch (or occurs check)
19:13:45 <slideshow6052> oh yep i should do that
19:14:23 ski would second both monochrom's statements there
19:14:34 <slideshow6052> yes i agree
19:14:34 <ski> learn why some people think
19:14:44 <slideshow6052> do you have any way how i could use folds here though
19:14:46 <int-e> ski: good one, why do we think?
19:14:47 <slideshow6052> like a starting idea
19:14:51 <int-e> it's so painful
19:15:01 <ski> learn why some people think explicit recursion is less preferable. learn how to not use explicit recursion. then decide for yourself, possibly on a case-by-case basis
19:15:26 <slideshow6052> ok i think i understand why but my issue is i don't see how i can use it in my program here
19:17:04 <int-e> for me it's mostly about having fewer stupid helper functions (which then require a name)
19:17:10 <monochrom> Yeah recognizing a catamorphism is not easy. Until you realize that it is purely syntactical and mechanical, there is nothing to understand, just shut up and calculate. :)
19:17:29 <slideshow6052> like i define the same pattern for functions involving T a few times.. but each case is a bit different so i don't see how it's gonna help
19:18:22 <int-e> foldl (+) 0 replaces sum = go 0 where go acc [] = acc; go acc (x:xs) = go (acc + x) xs
19:18:44 <int-e> (of course `sum` exists, but imagine it was a less common binary operation instead of (+))
19:19:18 <ski> slideshow6052 : i don't think you should be using `State' for `Context'. `Reader' is more suited for that (or simply pass it as an explicit argument)
19:19:48 <slideshow6052> i i didn't know about reader ill look into that
19:19:54 <Joao003> int-e: or even sum [] = 0; sum (x:xs) = x + sum xs
19:19:57 <slideshow6052> yes initially i wanted to split that whole thing into two functions
19:20:02 <int-e> And emphasis is on *stupid*. If the function does something interesting I usually start with explicit recursion and keep it that way even if it's a fold.
19:20:08 <int-e> Joao003: that's a foldr though
19:20:28 <Joao003> but it does the same thing
19:21:07 <int-e> > (foldr (+) x [1..3], foldl (+) x [1..3])
19:21:08 <lambdabot> (1 + (2 + (3 + x)),x + 1 + 2 + 3)
19:21:09 <ski> slideshow6052 : `State' for the `T' part (iow `fresh_tyvar') seems reasonable
19:21:16 <Joao003> i'm waiting for a challenge
19:21:24 <slideshow6052> like in C or something i can have a simple global called type_Var and each time I want a fresh one i just increase that by 1. but i was a bit confused on how to do it if i split it up. because then i would need to have an extra param for gen and also return an extra param from the other function telling me how much i incremented fresh_Var by. so i did that
19:21:24 × chiselfuse quits (~chiselfus@user/chiselfuse) (Remote host closed the connection)
19:21:29 <int-e> it's only the same because + is (hopefully!) associative and commutative
19:21:39 <monochrom> Yeah Context (environment) is definitely a Reader.
19:22:00 chiselfuse joins (~chiselfus@user/chiselfuse)
19:22:13 <slideshow6052> oh ye i added the context there later as i realised while working on it that i didn't know which tyvars refer to which param haha so i just made it a tuple
19:22:27 <ski> and yea, `gen' could also use more graceful failure than `error
19:22:29 <ski> '
19:23:41 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 245 seconds)
19:24:01 <ski> slideshow6052 : state for your current variable counter is fine. but it's not suited for the environment/context
19:24:02 <monochrom> If you use mutable state for environment, you are opening yourself to a bug or a lot of chore.
19:24:08 <ski> ^
19:24:28 <slideshow6052> but i still need state then right?
19:24:35 <ski> yes, for the variable counter
19:24:35 <slideshow6052> how can i have a state and redaer?
19:24:47 <ski> StateT T (Reader Context)
19:24:50 euleritian joins (~euleritia@dynamic-046-114-206-176.46.114.pool.telefonica.de)
19:24:54 <monochrom> RWS >:)
19:25:18 <Joao003> i don't understand this state stuff
19:25:18 <ski> or the other way around
19:25:22 <ski> @unmtl StateT T (Reader Context) a
19:25:22 <lambdabot> T -> Context -> (a, T)
19:25:24 <ski> @unmtl ReaderT Context (State T) a
19:25:24 <lambdabot> Context -> T -> (a, T)
19:25:32 <slideshow6052> what does rws mean?
19:25:39 <ski> @unmtl StateT T (ReaderT Context Maybe) a
19:25:39 <lambdabot> T -> Context -> Maybe (a, T)
19:25:45 <ski> for graceful failure
19:25:47 <monochrom> It's a monolith of reader-writer-state
19:25:58 <ski> or use `Either TypeError' instead of `Maybe'
19:26:13 <ski> @unmtl RWS r w s a
19:26:13 <lambdabot> r -> s -> (a, s, w)
19:26:22 <Joao003> reciting: i don't understand this state stuff
19:26:29 <ski> @unmtl ReaderT r (WriterT w (State s)) a
19:26:29 <lambdabot> r -> s -> (a, w, s)
19:26:41 <slideshow6052> sorry how do i read this
19:26:45 <slideshow6052> what is StateT
19:26:56 <ski> it's the monad transformer version of `State'
19:27:18 <ski> used for combining state effects with other monads
19:27:21 <slideshow6052> ...
19:27:26 <Joao003> and what is a `State'?
19:27:26 <slideshow6052> so you can combine monads?
19:27:37 <ski> no, you can combine monad transformers with a monad
19:27:51 <ski> you don't combine monads themselves, typically
19:28:02 <monochrom> If M is a monad, then StateT S M a gives you S -> M (a, S), so you have both state and M effects.
19:28:37 <ski> (you can do `IO (IO Something)' or `Parser (TypeCheck Something)', if you like, i suppose .. but it's not what's meant by "combining" here)
19:29:00 <ski> @unmtl StateT S M a
19:29:00 <lambdabot> S -> M (a, S)
19:29:24 <slideshow6052> so what will be the type of my gen function if i wanted to both read and write?
19:29:31 <slideshow6052> also i never knew about this
19:29:35 <slideshow6052> just learnt about monads
19:29:48 <slideshow6052> and now you're telling me there's all this haha
19:29:57 <slideshow6052> i guess there is always more haskll
19:29:57 <ski> `@unmtl' will show you the "underlying" implementation, to double-check that you get the behaviour that you want
19:31:05 <monochrom> It is also OK to omit transformers for now and handroll your own monad that newtypes "S -> Context -> (a, S)". Which is what I do to my students.
19:31:29 <ski> slideshow6052 : i guess your `[Constraint]' argument to `gen' could also possibly be part of your state
19:31:42 <slideshow6052> monochrom would you happen to hvae an example worksheet or lecture or something for that?
19:31:52 <ski> (and your `[Goal]' part also could. but that could be a little bit more awkward, i guess)
19:33:07 <ski> in any case, it's probably a good idea to make your custom `TypeCheck' monad anyway, instead of explicitly naming `State',&c. in type signatures
19:33:12 <monochrom> Yeah https://www.cs.utoronto.ca/~trebla/CSCC24-2023-Summer/10-semantics-2.html#model look for MutM
19:33:40 <monochrom> In fact, I didn't even mention "monad". >:)
19:34:13 <ski> newtype TypeCheck a = MkTC {runTC :: State (T,Context) a} -- your current monad
19:34:29 <ski> gen :: [Constraint] -> [Goal] -> TypeCheck [Constraint]
19:34:31 × aruns quits (~aruns@user/aruns) (Ping timeout: 245 seconds)
19:34:31 <ski> and so on
19:34:40 <monochrom> Later on, you also find out that I really have some kind of "Context -> MutM a" but I kept the "Context ->" separate. (It doesn't matter either way.)
19:34:59 peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com)
19:35:39 <ski> newtype TypeCheck a = MkTC {runTC :: (T,Context) -> (a,T,Context)} -- or, if you prefer being explicit, and making your own `Monad' instance
19:35:57 <statusbot> Maintenance update: Hackage server going down for upgrade. -- http://status.haskell.org/pages/maintenance/537c07b0cf1fad5830000093/6574bd68258f4509bf35a548
19:35:59 <ski> newtype TypeCheck a = MkTC {runTC :: StateT T (ReaderT Context (Either TypeError)) a} -- what we suggested
19:36:03 <slideshow6052> oh this all looks very useful thanks
19:36:09 <slideshow6052> thanks ski i have made notes of this
19:36:22 <ski> newtype TypeCheck a = MkTC {runTC :: T -> Context -> Either TypeError (a,T)} -- which amounts to this
19:37:16 <slideshow6052> unfortunately i won't be able to do any more haskell for a few months :( but i will be back with vengeance haha
19:37:24 <slideshow6052> i will implement your suggestions too
19:37:27 falafel joins (~falafel@94.red-79-153-65.dynamicip.rima-tde.net)
19:39:13 <ski> slideshow6052 : with a `newtype', using `StateT',&c., you can use `deriving (Functor,Applicative,Monad)' (if you enable the extensions for that). with the explicit version, you'll need to make your own instances of `Functor',`Applicative',`Monad' (although the first two can just defer to the last one, using `fmap = liftM', and `pure = return',`(<*>) = ap')
19:40:40 <ski> slideshow6052 : "i won't be able to do any more haskell for a few months" -- effective immediately ?
19:40:49 not_reserved joins (~not_reser@185.216.201.100)
19:41:33 <monochrom> I haven't done Haskell for months. But it was Lean instead so it was OK. >:)
19:41:54 <monochrom> "I now understand recursion."
19:42:44 <slideshow6052> yeh basically, well ill do a bit more tonight but i have other stuff to do
19:42:51 ski nods
19:43:14 <slideshow6052> but on the plus side, next semester im taking a class which uses agda
19:43:23 <slideshow6052> so i think that may be useful for haskell understanding
19:43:23 <ski> sounds fun
19:43:25 <monochrom> QED
19:43:31 <ski> QEF !
19:43:53 <ski> (Quod Erat Faciendum)
19:44:05 <ski> ("Which was to be constructed". Euclid)
19:46:50 <monochrom> Oh hey OO has factorem abstractum. >:)
19:47:08 jargon joins (~jargon@32.sub-174-238-226.myvzw.com)
19:48:39 × euleritian quits (~euleritia@dynamic-046-114-206-176.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
19:48:58 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
19:51:01 <slideshow6052> but that you guys for help and have a good night
19:51:04 <statusbot> Maintenance update: Hackage Server back up, update complete. -- http://status.haskell.org/pages/maintenance/537c07b0cf1fad5830000093/6574bd68258f4509bf35a548
19:51:05 <slideshow6052> or morning depending were you are
19:51:23 <ski> yw, good night, pleasant dreams
19:51:50 <slideshow6052> :)
19:53:23 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 260 seconds)
19:53:44 euleritian joins (~euleritia@dynamic-046-114-206-176.46.114.pool.telefonica.de)
19:54:36 × tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Quit: Lost terminal)
19:56:31 renzhi joins (~xp@2607:fa49:6500:b100::3ce6)
19:57:13 × euleritian quits (~euleritia@dynamic-046-114-206-176.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
19:57:26 tri joins (~tri@ool-18bc2e74.dyn.optonline.net)
19:57:30 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
19:58:50 × cimento quits (CO2@gateway/vpn/protonvpn/cimento) (Quit: WeeChat 4.1.2)
20:00:35 × waleee quits (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 264 seconds)
20:01:15 <tomsmeding> is statusbot new?
20:01:34 × tri_ quits (~textual@ool-18bc2e74.dyn.optonline.net) (Quit: Textual IRC Client: www.textualapp.com)
20:02:57 <monochrom> No, it's been around for a while.
20:03:20 cimento joins (CO2@gateway/vpn/protonvpn/cimento)
20:05:10 <geekosaur> it just doesn't say very much
20:05:30 <geekosaur> which is generally a good thing because a chatty statusbot means infrastructure problems
20:10:31 × azimut quits (~azimut@gateway/tor-sasl/azimut) (Ping timeout: 240 seconds)
20:13:54 azimut joins (~azimut@gateway/tor-sasl/azimut)
20:14:12 <Joao003> just asking: do you use lambdabot or yahb2 for demoing code on this channel?
20:15:06 <monochrom> Yes I toss a coin and choose one. Unless when it matters.
20:15:53 <Joao003> > putStrLn "lambdabot."
20:15:55 <lambdabot> <IO ()>
20:15:58 <sclv> statusbot only posts when infra admins are disrupting service (or dealing with an unplanned service disruption)
20:16:03 <ski> usually lambdabot, unless i want/need something specific that yahb2 provides
20:16:05 × lane1 quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Ping timeout: 256 seconds)
20:16:14 <Joao003> % putStrLn "lambdabot. but yahb2 for io"
20:16:14 <yahb2> lambdabot. but yahb2 for io
20:17:29 <tomsmeding> geekosaur: fair :)
20:18:43 <tomsmeding> Joao003: lambdabot has a more packages in the environment, but yahb2 doesn't have the SafeHaskell requirement
20:21:37 waleee joins (~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
20:21:50 aruns joins (~aruns@user/aruns)
20:26:43 × pagnol quits (~user@2a02:a210:a3c:b00:3e0f:bab7:90e2:2f26) (Ping timeout: 255 seconds)
20:27:00 coot joins (~coot@89-69-206-216.dynamic.chello.pl)
20:28:14 lane joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
20:35:57 <tri> hey sorry for a simple question, I have data Person a = PersonCtr a, how do i constraint a to use be of a typeclass, say Num?
20:36:10 × lane quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Remote host closed the connection)
20:36:33 lane joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
20:36:35 <tri> to be clear, i don't want to make an instance of of (Person a) under Num, just constraint the type variable a
20:36:52 <tri> I feel like i should know this, but probably having a brain fart
20:37:07 <ski> (no need to be sorry for asking simple questions)
20:37:17 <geekosaur> you don't, because if you did it would only check it on creation but not make it available when you really want it
20:37:30 <ski> the general answer is, you typically don't
20:37:54 <tri> oh yea i think i read about it, that we don't constaint typeclass on type variable
20:38:04 <tri> but only on function argument
20:38:51 <ski> (you can pack a constraint with `GADTs' .. but it's not that common that this is sensible. and the legacy way of saying `data Num a => Person a = PersonCtr a' is most likely not what you want (it's mostly useless), due to what geekosaur said)
20:39:22 <ski> if you have a lot of constraints, you can make a constraint synonym
20:39:50 <ski> type MyConstraints a = (Show a,Read a,Integral a)
20:41:25 <tri> ski: i've never seen that syntax before, is it uncommon? because I don't want to dive too much into the advanced, corner of haskell just yet, im still learning from a book
20:42:30 <tomsmeding> tri: you remembered correctly, you'll need to put that constraint on the functions using Person that require that constraint
20:42:34 <ski> yes, it's uncommon, since it's basically useless
20:42:53 <tri> ok thank you everyone
20:43:09 <ski> (this is like a deprecated corner)
20:43:23 <tomsmeding> there are various reasons why putting the constraint _in the data type_ is typically not what you want, even if there are some tricks that let you do it (GADTs)
20:43:48 <tri> yea, i heard ocaml have GADT, but let's not go there :)
20:44:04 <tri> totally not knowing what im talking about, just picked it up from a podcast
20:44:04 <ski> GHC does, too
20:45:32 <tri> 🙂
20:45:37 <tri> oh i can send emoji
20:45:41 <tri> cool
20:45:55 ski , thankfully, can't see them
20:45:59 <tri> LOL
20:47:02 Guest10 joins (~Guest10@ool-18bc2e74.dyn.optonline.net)
20:47:08 × billchenchina quits (~billchenc@103.152.35.21) (Quit: Leaving)
20:50:37 × coot quits (~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
20:51:31 × trev quits (~trev@user/trev) (Quit: trev)
20:52:11 × falafel quits (~falafel@94.red-79-153-65.dynamicip.rima-tde.net) (Ping timeout: 264 seconds)
20:56:34 × azimut quits (~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection)
20:56:52 azimut joins (~azimut@gateway/tor-sasl/azimut)
20:58:02 `2jt joins (~jtomas@90.162.208.36)
21:00:14 fendor joins (~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c)
21:01:32 <haskellbridge> 14<m​auke> 😛
21:02:01 <monochrom> Unpopular opinion: Emojis are overrated.
21:02:18 <Joao003> Unpopular opinion: we should use emoticons more
21:02:36 ski prefers smileys
21:03:09 <tomsmeding> 1😃
21:04:43 <Joao003> Ô_Ǒ
21:05:24 <Joao003> 💀💀💀💀
21:05:41 <tomsmeding> monochrom: happy now with the on-topic conversation? :)
21:05:47 <Joao003> y e s
21:06:02 <[exa]> c'mon guys people's ancient terminals explode on widechar unicode
21:06:09 <Joao003> lol
21:06:25 <Joao003> Ô_Ǒ
21:06:46 <haskellbridge> 12<C​elestial> o_O
21:08:24 × Guest10 quits (~Guest10@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 250 seconds)
21:08:43 <Joao003> .-.
21:09:45 [exa] slaps hood of pdp-7 printer "this baby does 300 standard width characters per second! you need no emoji!"
21:10:15 <Joao003> (`v•-•v´)
21:16:04 × peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 256 seconds)
21:16:09 Joao003 wants to be challenged
21:21:11 <EvanR> an old oscilliscope-like vector graphs display should be able to handle whatever unicode is required xD
21:21:15 <EvanR> graphics*
21:21:41 <monochrom> Now that's hardcore.
21:23:11 <tri> https://paste.tomsmeding.com/qZEXIezR
21:23:20 <tri> please help me with the above
21:23:43 <tri> im trying to implement a semigroup for Identity a = Identity a (Eq, Show)
21:23:54 <monochrom> instance Semigroup a => Semigroup (Identity a)
21:24:00 <tri> and stuck at using quickCheck to run random test for it
21:24:00 <monochrom> then you will not be stuck
21:24:13 <tri> oh hmm
21:24:55 × aruns quits (~aruns@user/aruns) (Ping timeout: 246 seconds)
21:25:04 <monochrom> Hrm you really want x<>y = x? I guess that's also a semigroup.
21:25:32 <monochrom> But you can only quickcheck-test a type you pick, not "test polymorphic type".
21:25:32 <tri> oh i see what you saying, yea im not focus on the actual semigroup implementation
21:25:40 <tri> oh
21:25:52 <[exa]> tri: check out First in Data.Monoid
21:26:02 <tri> yea i know about First
21:26:35 <tri> I understand semigroup & monoid, just that im try to use the test library quickcheck and get stuck
21:26:48 <ski> pick say `Int' for `a'
21:27:05 <tri> yea but a could be anything right, is there anyway to run test for all?
21:27:13 <ski> no
21:27:23 <tomsmeding> "all types" is kind of a large number of types :)
21:28:06 <monochrom> There is still no "choose a random type".
21:28:07 <ski> but since `Semigroup (Identity a)' doesn't depend on any `Semigroup a', you're only depending on `Eq a'. `Eq Int' should be fine
21:28:12 × eggplantade quits (~Eggplanta@2600:1700:38c5:d800:1fe:ac5a:8c23:9cce) (Remote host closed the connection)
21:28:13 <tomsmeding> as in, if you give me a list of all types, I'll write the quickcheck code to test them all
21:28:56 <tri> yea i skipped the chapter on quickcheck so now struggling with it 🙁
21:29:07 <tri> thanks for the help guys
21:29:08 <ski> (you could pick `a' as `Bool', but then you might miss counterexamples that require three different values. `Int' or `Integer' will probably work satisfactorially)
21:29:59 falafel joins (~falafel@94.red-79-153-65.dynamicip.rima-tde.net)
21:30:10 <tri> hmm, so how do i prove my <> implementation for Identity a is a monoid?
21:30:21 <tri> i mean semigroup
21:30:28 <ski> (and your `Semigroup (Identity a)' code does not depend on which type is picked for `a', it's parametric. so the only dependency of the particular choice of `a' would be `Eq a' (and `Arbitrary a', yes))
21:31:04 <ski> testing can (in general) only show the presence of errors, not the absence
21:31:42 <Logio> tri: pen and paper usually works for proving
21:31:43 <ski> tri : pick `a' as `Int' or `Integer'
21:32:00 <tri> i have to prove that (Identity a <> Identity a) <> Identity a == Identity a <> (Identity a <> Identity a)
21:32:10 <tri> so i have to prove it for all type right?
21:32:20 <ski> s/a/a0/,s/a/a1/,s/a/a2/
21:32:43 <ski> if you're doing a proof (so no QuickCheck), yes
21:33:08 <tri> oh ok
21:33:29 × _ht quits (~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Remote host closed the connection)
21:34:09 machinedgod joins (~machinedg@93-136-130-2.adsl.net.t-com.hr)
21:34:26 eggplantade joins (~Eggplanta@2600:1700:38c5:d800:1fe:ac5a:8c23:9cce)
21:34:43 <tri> i maybe too pedantic here, but is it common that we implement Monoid for custom business app type? Because that's my learning goal, to apply haskell to F#, and C#
21:34:43 <ski> (nitpick, the proof would presumably be for `... = ...', not for `... == ... = True', btw)
21:35:11 <tri> and if i ever implement a Monoid for a business type, but can't prove that it's correct, then it's a hazard
21:35:11 <ski> monoid is useful for various "summary" operations
21:35:35 <ski> it can also be useful, if you want to parallelize some computation
21:36:07 <tri> yea i read about Monoid being the foundation for parallelizing stuff, but that's too low-level and i may never go there
21:37:13 <tri> Im imagining about implement a monoid function for an order (i work at a trading company), and not being able to prove that function follows monoidal rule, then it's hazardous code
21:37:28 <tri> im not sure if that's a realistic scenario im thinking of
21:37:47 <ski> > sortBy (comparing length <> compare) (words "The quick brown fox jumps over the lazy dog") -- primarily sort on word length, secondarily on lexicographic order of words (having the same length)
21:37:49 <lambdabot> ["The","dog","fox","the","lazy","over","brown","jumps","quick"]
21:37:57 <ski> @where monoids
21:37:57 <lambdabot> comment on "Monoids? In my programming language?" by Cale in 2008 (or 2009 ?) at <http://www.reddit.com/r/programming/comments/7cf4r/monoids_in_my_programming_language/c06adnx> about a use of `
21:37:57 <lambdabot> instance Monoid a => Monoid (rho -> a)'
21:39:57 <monochrom> I don't know what "business type" means. Is there a mathematical definition?
21:40:53 tri- joins (~igloo@ool-18bc2e74.dyn.optonline.net)
21:40:59 <monochrom> But the tautological answer is the only correct answer ever. Iff you find an operator that makes it a monoid and you find it useful.
21:41:41 × tri- quits (~igloo@ool-18bc2e74.dyn.optonline.net) (Remote host closed the connection)
21:41:51 <tri> oh sorry didn't mean to type that above sentence, was a keyboard misttyped
21:42:29 <monochrom> Configurations are usually monoids.
21:43:12 <monochrom> It's pretty much the same reason First a is a monoid, and you do it for every field in your configuration record.
21:43:27 tri- joins (~igloo@ool-18bc2e74.dyn.optonline.net)
21:44:05 Guest10 joins (~Guest10@ool-18bc2e74.dyn.optonline.net)
21:44:06 × tri- quits (~igloo@ool-18bc2e74.dyn.optonline.net) (Remote host closed the connection)
21:44:29 × fendor quits (~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c) (Remote host closed the connection)
21:44:51 <monochrom> In this case though it is useful because "defaultConfig <> stuffFromConfigFile <> stuffFromCmdLine <> ..." is extremely convenient and clear.
21:45:05 × Guest10 quits (~Guest10@ool-18bc2e74.dyn.optonline.net) (Client Quit)
21:46:10 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
21:48:56 × falafel quits (~falafel@94.red-79-153-65.dynamicip.rima-tde.net) (Ping timeout: 256 seconds)
21:48:57 <fluffyballoon> Is there any good place to report bugs? There's a doc typo ("stirctly" -> "strictly") in https://hackage.haskell.org/package/strict-0.5/docs/src/System.IO.Strict.html#getContents
21:49:47 × tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 264 seconds)
21:51:23 <geekosaur> most packages have a bug tracker listed on their top hackage page
21:51:40 <monochrom> You take a step back to https://hackage.haskell.org/package/strict-0.5 , then look for "home page" etc.
21:53:53 <fluffyballoon> Thank you geekosaur and monochrom, I was looking for mailing lists, instead.
21:58:25 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
21:59:13 jtomas joins (~jtomas@90.162.208.36)
22:00:52 × mechap quits (~mechap@user/mechap) (Quit: WeeChat 4.1.2)
22:01:38 mechap joins (~mechap@user/mechap)
22:02:23 × `2jt quits (~jtomas@90.162.208.36) (Ping timeout: 264 seconds)
22:12:17 <Joao003> @type fix (pure [])
22:12:18 <lambdabot> [a]
22:12:26 <Joao003> @type fix
22:12:27 <lambdabot> (a -> a) -> a
22:12:49 <Joao003> @type fix (pure :: List)
22:12:50 <lambdabot> error:
22:12:50 <lambdabot> • Pattern synonym ‘List’ used as a type
22:12:50 <lambdabot> • In an expression type signature: List
22:12:55 <Joao003> @type fix (pure :: [a])
22:12:55 <ski> Monad (rho ->)
22:12:56 <lambdabot> error:
22:12:56 <lambdabot> • Couldn't match expected type ‘[a2]’
22:12:56 <lambdabot> with actual type ‘a1 -> f0 a1’
22:13:18 <ski> @type fix (pure :: (->) [a] [a])
22:13:19 <lambdabot> error:
22:13:19 <lambdabot> • Occurs check: cannot construct the infinite type: a1 ~ [a1]
22:13:19 <lambdabot> Expected type: [a1] -> [a1]
22:13:24 <Joao003> What does that mean
22:13:41 <ski> @type fix (pure [] :: (->) [a] [a])
22:13:42 <lambdabot> [a]
22:13:53 <ski> (sorry, missed spelling out the `[]')
22:14:22 <Joao003> Is that really the type of the list [[[[[...]]]]]
22:14:27 <ski> no
22:14:41 <Joao003> Then what is it
22:14:48 <ski> pure :: a -> i a
22:15:01 <ski> pick this `a' to be `[a]', for a new tyvar `a'
22:15:08 <ski> pure :: [a] -> i [a]
22:15:08 <monochrom> It may be more interesting to wonder what fix (pure []) does. >:)
22:15:18 <ski> [] :: [a]
22:15:21 <ski> so
22:15:25 <ski> pure [] :: i [a]
22:15:57 <ski> now, pick `i' to be `(rho ->)' / `(->) rho' (which is an instance of `Functor',`Applicative', and `Monad')
22:16:08 <ski> pure [] :: (rho ->) [a]
22:16:18 <ski> pure [] :: (->) rho [a]
22:16:21 <ski> pure [] :: rho -> [a]
22:16:29 <ski> now, pick `rho' to be `[a]'
22:16:33 <ski> pure [] :: [a] -> [a]
22:16:40 <ski> fix :: (b -> b) -> b
22:16:44 <ski> pick `b' as `[a]'
22:16:51 <ski> fix :: ([a] -> [a]) -> [a]
22:16:54 <ski> finally
22:17:03 <ski> fix (pure []) :: [a]
22:17:37 <ski> `pure []' here is basically `\xs -> []'
22:18:11 <ski> so `fix (pure [])' is `let xs = (\xs -> []) xs in xs', which is `let xs = [] in xs', which is `[]'
22:18:23 <Joao003> am i the only one who hates having to quote like `this'
22:19:28 × Joao003 quits (~Joao003@190.108.99.32) (Quit: Bye!)
22:19:54 <geekosaur> I think ski's the only one who uses Oxford quotes
22:19:59 <geekosaur> (here at least)
22:20:20 <ski> (afaicr, yea)
22:20:37 <monochrom> I think there are two: you and someone else today.
22:21:00 <monochrom> earlier today
22:21:23 <geekosaur> I use ` because some IRC clients recognize it as "use fixed width font"
22:21:50 <ski> ingrained habit, on my end
22:22:19 <monochrom> It's telephone games all the way down. All is lost.
22:22:23 × driib quits (~driib@vmi931078.contaboserver.net) (Quit: The Lounge - https://thelounge.chat)
22:23:09 <ski> "telephone games" ?
22:23:18 coot joins (~coot@89-69-206-216.dynamic.chello.pl)
22:23:28 <ski> hm, is that the same as what's apparently called "chinese whispers" in english ?
22:23:37 <monochrom> Yes.
22:23:56 <ski> hm, looks like it
22:24:03 <ski> (it's called something else, here)
22:24:44 <monochrom> If you have a linear sequence of people, or a layer cake of software, then every person/layer feels obliged to add a misinterpretation.
22:25:23 <monochrom> "to show that I understand"
22:26:32 driib joins (~driib@vmi931078.contaboserver.net)
22:28:01 <ski> reminds me of that idea that the longer the chain of command, the greater the chance of the field information getting distorted along the way up, and the greater the chance of directions to implement also getting distorted, on the way down
22:32:44 × dhil quits (~dhil@2001:8e0:2014:3100:3783:1717:6803:631d) (Ping timeout: 268 seconds)
22:36:01 × takuan quits (~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection)
22:38:31 drdo4 joins (~drdo@bl14-14-49.dsl.telepac.pt)
22:39:16 × drdo quits (~drdo@bl14-14-49.dsl.telepac.pt) (Ping timeout: 276 seconds)
22:39:16 drdo4 is now known as drdo
22:47:13 TobiasAbramovitz joins (~TobiasAbr@71.134.151.220)
22:47:56 <TobiasAbramovitz> Hello, how is everyone doing today?
22:48:43 <ski> a bit sleepy
22:51:31 nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net)
22:51:47 Sgeo joins (~Sgeo@user/sgeo)
22:55:30 tommy___ joins (~tommy@2601:681:5a00:a260:2216:9438:8afd:c460)
22:56:37 × nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 246 seconds)
23:01:36 × TobiasAbramovitz quits (~TobiasAbr@71.134.151.220) (Quit: Client closed)
23:05:23 × acidjnk_new quits (~acidjnk@p200300d6e72b9380b928f2c2e25446fb.dip0.t-ipconnect.de) (Ping timeout: 256 seconds)
23:07:51 × alexherbo2 quits (~alexherbo@2a02-8440-b210-cea0-a800-a38a-3c94-a861.rev.sfr.net) (Remote host closed the connection)
23:11:17 pavonia joins (~user@user/siracusa)
23:12:25 × jtomas quits (~jtomas@90.162.208.36) (Ping timeout: 276 seconds)
23:15:22 × coot quits (~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
23:21:51 jtomas joins (~jtomas@90.162.208.36)
23:30:35 <haskellbridge> 12<C​elestial> how does one effectively use lenses in combination with `Maybe` fields? Specifically if I have a `Maybe Foo` record field and I want to apply a transformation to `Foo` or replace it with a default value, is there something idiomatic for that?
23:31:24 <ncf> yourLens %~ maybe default transformation
23:31:27 <haskellbridge> 12<C​elestial> maybe I was just too dumb but I tried a combination of `set` and `view` using `fromMaybe` but it didn't work properly
23:31:43 <haskellbridge> 12<C​elestial> oh, thanks haha
23:31:45 <haskellbridge> 12<C​elestial> amazing
23:32:19 <ncf> maybe (Just default) i guess
23:32:50 <ncf> and (Just . transformation)... this is clunky
23:32:54 <haskellbridge> 12<C​elestial> right
23:33:21 <haskellbridge> 12<C​elestial> the transformation itself returns `Maybe Foo` so it does work out
23:33:40 <haskellbridge> 12<C​elestial> this has the form of `>>=` sort of
23:38:40 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
23:38:48 × igemnace quits (~ian@user/igemnace) (Quit: WeeChat 4.1.2)
23:44:34 × gmg quits (~user@user/gehmehgeh) (Quit: Leaving)
23:45:16 × __monty__ quits (~toonn@user/toonn) (Quit: leaving)
23:45:19 andreabedini joins (~andreabed@159.196.202.200)
23:47:37 × target_i quits (~target_i@217.175.14.39) (Quit: leaving)
23:52:02 peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com)
23:55:30 [_] joins (~itchyjunk@user/itchyjunk/x-7353470)
23:55:52 × jtomas quits (~jtomas@90.162.208.36) (Ping timeout: 256 seconds)
23:56:11 bilegeek joins (~bilegeek@2600:1008:b065:6c8a:2877:790c:5cda:9f45)
23:59:26 × [itchyjunk] quits (~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 260 seconds)

All times are in UTC on 2023-12-09.