2023/12/10

2023-12-10 00:01:36 +0100TobiasAbramovitz(~TobiasAbr@71.134.151.220) (Quit: Client closed)
2023-12-10 00:05:23 +0100acidjnk_new(~acidjnk@p200300d6e72b9380b928f2c2e25446fb.dip0.t-ipconnect.de) (Ping timeout: 256 seconds)
2023-12-10 00:07:51 +0100alexherbo2(~alexherbo@2a02-8440-b210-cea0-a800-a38a-3c94-a861.rev.sfr.net) (Remote host closed the connection)
2023-12-10 00:11:17 +0100pavonia(~user@user/siracusa)
2023-12-10 00:12:25 +0100jtomas(~jtomas@90.162.208.36) (Ping timeout: 276 seconds)
2023-12-10 00:15:22 +0100coot(~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
2023-12-10 00:21:51 +0100jtomas(~jtomas@90.162.208.36)
2023-12-10 00:30:35 +0100 <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?
2023-12-10 00:31:24 +0100 <ncf> yourLens %~ maybe default transformation
2023-12-10 00:31:27 +0100 <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
2023-12-10 00:31:43 +0100 <haskellbridge> 12<C​elestial> oh, thanks haha
2023-12-10 00:31:45 +0100 <haskellbridge> 12<C​elestial> amazing
2023-12-10 00:32:19 +0100 <ncf> maybe (Just default) i guess
2023-12-10 00:32:50 +0100 <ncf> and (Just . transformation)... this is clunky
2023-12-10 00:32:54 +0100 <haskellbridge> 12<C​elestial> right
2023-12-10 00:33:21 +0100 <haskellbridge> 12<C​elestial> the transformation itself returns `Maybe Foo` so it does work out
2023-12-10 00:33:40 +0100 <haskellbridge> 12<C​elestial> this has the form of `>>=` sort of
2023-12-10 00:38:40 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-10 00:38:48 +0100igemnace(~ian@user/igemnace) (Quit: WeeChat 4.1.2)
2023-12-10 00:44:34 +0100gmg(~user@user/gehmehgeh) (Quit: Leaving)
2023-12-10 00:45:16 +0100__monty__(~toonn@user/toonn) (Quit: leaving)
2023-12-10 00:45:19 +0100andreabedini(~andreabed@159.196.202.200)
2023-12-10 00:47:37 +0100target_i(~target_i@217.175.14.39) (Quit: leaving)
2023-12-10 00:52:02 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com)
2023-12-10 00:55:30 +0100[_](~itchyjunk@user/itchyjunk/x-7353470)
2023-12-10 00:55:52 +0100jtomas(~jtomas@90.162.208.36) (Ping timeout: 256 seconds)
2023-12-10 00:56:11 +0100bilegeek(~bilegeek@2600:1008:b065:6c8a:2877:790c:5cda:9f45)
2023-12-10 00:59:26 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 260 seconds)
2023-12-10 01:02:59 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 264 seconds)
2023-12-10 01:05:13 +0100tommy___(~tommy@2601:681:5a00:a260:2216:9438:8afd:c460) (Ping timeout: 246 seconds)
2023-12-10 01:08:47 +0100Tuplanolla(~Tuplanoll@91-159-68-236.elisa-laajakaista.fi) (Quit: Leaving.)
2023-12-10 01:10:07 +0100waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 256 seconds)
2023-12-10 01:14:42 +0100idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1)
2023-12-10 01:18:55 +0100mhatta(~mhatta@www21123ui.sakura.ne.jp) (Quit: ZNC 1.8.2+deb3.1 - https://znc.in)
2023-12-10 01:23:16 +0100lane(~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Ping timeout: 276 seconds)
2023-12-10 01:25:53 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-10 01:26:59 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Client Quit)
2023-12-10 01:29:40 +0100mhatta(~mhatta@www21123ui.sakura.ne.jp)
2023-12-10 01:36:28 +0100lane(~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
2023-12-10 01:36:31 +0100juri____(~juri@79.140.117.56)
2023-12-10 01:39:37 +0100juri_(~juri@79.140.117.90) (Ping timeout: 255 seconds)
2023-12-10 01:57:00 +0100cimento(CO2@gateway/vpn/protonvpn/cimento) (Quit: WeeChat 4.1.2)
2023-12-10 02:02:14 +0100califax(~califax@user/califx) (Remote host closed the connection)
2023-12-10 02:03:43 +0100machinedgod(~machinedg@93-136-130-2.adsl.net.t-com.hr) (Ping timeout: 260 seconds)
2023-12-10 02:08:37 +0100newsham(~newsham@2603-800c-2c01-6825-857b-69b9-29f4-97e6.res6.spectrum.com)
2023-12-10 02:10:12 +0100 <newsham> I can write identity and composition for pairs of functions (https://paste.debian.net/1300666/).  Is it possible to write a Category instance for this?
2023-12-10 02:12:41 +0100sawilagar(~sawilagar@user/sawilagar) (Remote host closed the connection)
2023-12-10 02:12:52 +0100 <int-e> :t arr
2023-12-10 02:12:53 +0100 <lambdabot> Arrow a => (b -> c) -> a b c
2023-12-10 02:13:06 +0100sawilagar(~sawilagar@user/sawilagar)
2023-12-10 02:13:13 +0100califax(~califax@user/califx)
2023-12-10 02:13:59 +0100 <newsham> ahh yah
2023-12-10 02:18:29 +0100emmanuelux_(~emmanuelu@user/emmanuelux)
2023-12-10 02:19:32 +0100 <[Leary]> newsham: Sounds like you want the product category? You'd need to use GADT trickery to pair up the objects. Something like `data ProdCat p q is js where ProdCat :: p i j -> q i' j' -> ProdCat p q '(i, i') '(j, j')` with `instance (Category p, Category q) => Category (ProdCat p q)`.
2023-12-10 02:19:39 +0100 <int-e> newsham: You can embed Prod (a -> b) (c -> d) into Either a c -> Either b d.
2023-12-10 02:20:06 +0100 <int-e> (But the latter has more arrows than the former)
2023-12-10 02:20:08 +0100 <shachaf> Oh man, does Haskell's Category support kinds other than * now? I thought you had to use wacky alternative classes.
2023-12-10 02:20:23 +0100emmanuelux(~emmanuelu@user/emmanuelux) (Ping timeout: 264 seconds)
2023-12-10 02:31:16 +0100cimento(CO2@gateway/vpn/protonvpn/cimento)
2023-12-10 02:35:46 +0100mhatta(~mhatta@www21123ui.sakura.ne.jp) (Quit: ZNC 1.8.2+deb3.1 - https://znc.in)
2023-12-10 02:36:19 +0100tomboy64(~tomboy64@user/tomboy64) (Ping timeout: 255 seconds)
2023-12-10 02:38:14 +0100mhatta(~mhatta@www21123ui.sakura.ne.jp)
2023-12-10 02:40:21 +0100 <ski> @kind Category
2023-12-10 02:40:22 +0100 <lambdabot> (k -> k -> *) -> Constraint
2023-12-10 02:41:11 +0100ski's use numbering, rather than primes
2023-12-10 02:41:19 +0100tomboy64(~tomboy64@user/tomboy64)
2023-12-10 02:42:21 +0100 <shachaf> I am behind the times.
2023-12-10 02:42:42 +0100 <geekosaur> how much of that is just the PolyKinds extension?
2023-12-10 02:46:45 +0100 <shachaf> Presumably most of it?
2023-12-10 02:46:49 +0100cimento(CO2@gateway/vpn/protonvpn/cimento) (Quit: WeeChat 4.1.2)
2023-12-10 02:46:49 +0100andreabedini(~andreabed@159.196.202.200) (Quit: andreabedini)
2023-12-10 02:47:00 +0100 <shachaf> @kind Functor
2023-12-10 02:47:01 +0100 <lambdabot> (* -> *) -> Constraint
2023-12-10 02:47:26 +0100 <shachaf> I guess you'll still need all sorts of fancy things to define the diagonal functor and so on.
2023-12-10 02:48:58 +0100sawilagar(~sawilagar@user/sawilagar) (Remote host closed the connection)
2023-12-10 02:49:19 +0100cimento(CO2@gateway/vpn/protonvpn/cimento)
2023-12-10 02:49:22 +0100sawilagar(~sawilagar@user/sawilagar)
2023-12-10 02:52:55 +0100 <newsham> I want to say something like "if k1 is a morphism, and k2 is a morphism, then (Prod k1 k2) is a morphism".
2023-12-10 02:53:11 +0100 <newsham> but failing to get there with the syntax i am trying to use
2023-12-10 02:53:30 +0100 <EvanR> that description seems to be missing the source and target of the morphism
2023-12-10 02:53:46 +0100 <EvanR> unless there's only 1 object
2023-12-10 02:54:02 +0100 <newsham> was trying to go with:
2023-12-10 02:54:02 +0100 <newsham> class Morph k where
2023-12-10 02:54:03 +0100 <newsham>     apply :: (a `k` b) -> a -> b
2023-12-10 02:54:14 +0100 <shachaf> newsham: Hmm, doesn't that work with the thing [Leary] was suggesting?
2023-12-10 02:54:34 +0100 <newsham> i was trying to use heavy gadtery here if possible.  but perhaps thats misguided
2023-12-10 02:54:45 +0100 <newsham> trying to avoid
2023-12-10 02:55:32 +0100 <ski> that `Morph' doesn't seem to make much sense, to me
2023-12-10 02:55:50 +0100 <newsham> yah probably that too :)
2023-12-10 02:56:08 +0100 <jackdk> newsham: https://hackage.haskell.org/package/categories-1.0.7/docs/Control-Category-Cartesian-Closed.html ?
2023-12-10 02:56:18 +0100 <shachaf> Yes, I'm not sure what that Morph is trying to be.
2023-12-10 02:56:55 +0100 <ski> i guess it's expressing `k' is (the morphism type of a) concrete category
2023-12-10 02:56:59 +0100 <newsham> jackdk: thank you. i'm trying to build this as an exercise.
2023-12-10 02:57:30 +0100 <ski> (being a category with an underlying/forgetful functor to `Set', which we approximate with `Hask' here)
2023-12-10 02:58:37 +0100 <newsham> was hoping that Morph would help me define a morphism on products which i could then use to more easily write out an instance of cat for products.
2023-12-10 02:59:04 +0100 <ski> i don't think it would help with that
2023-12-10 02:59:54 +0100 <newsham> but the latter is the real goal here.. i just want to write out that for Prod (a `k` a') (b `k` b') form morphisms in product category.
2023-12-10 03:01:19 +0100 <newsham> with this https://github.com/timnewsham/hask-cats/blob/main/src/Alg.hs
2023-12-10 03:02:43 +0100wice(~wice@176.254.244.83) (Ping timeout: 276 seconds)
2023-12-10 03:06:39 +0100 <ski> (g . f) x = g (f x)
2023-12-10 03:08:27 +0100 <haskellbridge> 13<d​xtr> How is "a `foo` b `bar` c" evaluated?
2023-12-10 03:08:28 +0100 <ski> [Leary]'s suggestion sounds relevant
2023-12-10 03:08:48 +0100 <haskellbridge> 13<d​xtr> How is ```a `foo` b `bar` c``` evaluated?
2023-12-10 03:09:10 +0100sawilagar(~sawilagar@user/sawilagar) (Ping timeout: 255 seconds)
2023-12-10 03:10:20 +0100 <ski> > let a `foo` b = (a,b); a `bar` b = (a,b) in 0 `foo` 1 `bar` 2
2023-12-10 03:10:21 +0100 <lambdabot> ((0,1),2)
2023-12-10 03:12:10 +0100 <EvanR> > let foo = (,); bar = (,) in a `foo` b `bar` c
2023-12-10 03:12:11 +0100 <lambdabot> ((a,b),c)
2023-12-10 03:12:50 +0100Unicorn_Princess(~Unicorn_P@user/Unicorn-Princess/x-3540542) (Remote host closed the connection)
2023-12-10 03:13:16 +0100 <EvanR> but this depends on the defined precedence of foo and bar right
2023-12-10 03:13:34 +0100 <EvanR> and fixity
2023-12-10 03:16:29 +0100 <ski> "An operator is either an operator symbol, such as + or $$, or is an ordinary identifier enclosed in grave accents (backquotes), such as `op`. For example, instead of writing the prefix application op x y, one can write the infix application x `op` y. If no fixity declaration is given for `op` then it defaults to highest precedence and left associativity (see Section 4.4.2)."
2023-12-10 03:16:35 +0100 <ski> <https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-240003.2>
2023-12-10 03:16:51 +0100 <ski> this means that, without a fixity declaration for `foo' and `bar', you'll effectively get
2023-12-10 03:16:59 +0100 <ski> infixl 9 `foo`,`bar`
2023-12-10 03:17:12 +0100 <ski> dxtr ^
2023-12-10 03:18:21 +0100 <haskellbridge> 13<d​xtr> Alright
2023-12-10 03:18:51 +0100 <newsham> where does the bridge comm with?
2023-12-10 03:19:38 +0100 <ski> newsham : you may even be able to use `Prod' at kind level, and `:*' at type level, for the product category, with `DataKinds'
2023-12-10 03:20:16 +0100 <newsham> you mean to make the product types more readable?
2023-12-10 03:21:52 +0100 <ski> more like reusing your `Prod' definition
2023-12-10 03:23:09 +0100 <geekosaur> newsham, #haskell-irc:matrix.org
2023-12-10 03:23:24 +0100 <newsham> not sure i follow. i know a little of data kinds (ie. put data defn of Nat into types), but not sure i know what you mean for using prod at kind level.
2023-12-10 03:23:29 +0100 <ski> (replacing the '(i0,i1) with i0 :* i1 that is)
2023-12-10 03:25:51 +0100 <ski> so that [Leary]'s `ProdCat' (i'd call it `ProdMor', probably), gets kind `(k -> k -> *) -> (k -> l -> *) -> Prod k l -> Prod k l -> *'
2023-12-10 03:25:58 +0100lane1(~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
2023-12-10 03:26:31 +0100 <[Leary]> Blame `class Category`.
2023-12-10 03:26:54 +0100 <geekosaur> newsham, /whois haskellbridge gives more information, in particular a link to what channels it bridges to what Matrix rooms
2023-12-10 03:28:54 +0100 <newsham> guh is it possible to turn off emojis in libera's web chat?
2023-12-10 03:28:55 +0100lane(~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Ping timeout: 268 seconds)
2023-12-10 03:29:40 +0100 <geekosaur> I don't think so
2023-12-10 03:29:52 +0100 <newsham> found it. upper left gear.
2023-12-10 03:30:01 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 03:30:49 +0100 <newsham> and yet i still see the emojis for messages above.   test :* this.
2023-12-10 03:31:09 +0100 <newsham> i guess its not retroactive on prev msgs
2023-12-10 03:31:21 +0100 <geekosaur> you might prefer checking the log (see the /topic)
2023-12-10 03:33:07 +0100sagax(~sagax_nb@user/sagax)
2023-12-10 03:34:47 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 264 seconds)
2023-12-10 03:36:50 +0100 <ski> newsham : it turns off auto-replacing smileys with emoji, i think, but doesn't affect incoming messages
2023-12-10 03:37:30 +0100 <ski> (hm, or maybe it was the emoji selection button it disabled .. some times since i was on Kiwi)
2023-12-10 03:38:20 +0100jmdaemon(~jmdaemon@user/jmdaemon)
2023-12-10 03:44:53 +0100td_(~td@i5387091B.versanet.de) (Ping timeout: 240 seconds)
2023-12-10 03:47:34 +0100mechap(~mechap@user/mechap) (Ping timeout: 276 seconds)
2023-12-10 03:53:15 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-10 03:57:01 +0100 <newsham> in the category constructed by coproducts, are the morphisms also constructed as coproducts?
2023-12-10 03:58:31 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 268 seconds)
2023-12-10 04:02:05 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 04:04:47 +0100igemnace(~ian@user/igemnace)
2023-12-10 04:07:56 +0100igemnace_(~ian@user/igemnace)
2023-12-10 04:09:12 +0100igemnace1(~ian@user/igemnace)
2023-12-10 04:10:11 +0100igemnace1(~ian@user/igemnace) (Remote host closed the connection)
2023-12-10 04:10:14 +0100igemnace(~ian@user/igemnace) (Ping timeout: 268 seconds)
2023-12-10 04:10:54 +0100igemnace(~ian@user/igemnace)
2023-12-10 04:11:26 +0100td_(~td@i5387091B.versanet.de)
2023-12-10 04:12:10 +0100igemnace_(~ian@user/igemnace) (Ping timeout: 255 seconds)
2023-12-10 04:12:21 +0100igemnace_(~ian@user/igemnace)
2023-12-10 04:12:52 +0100thegeekinside(~thegeekin@177.245.195.141)
2023-12-10 04:14:52 +0100Square(~Square@user/square) (Ping timeout: 276 seconds)
2023-12-10 04:15:25 +0100igemnace(~ian@user/igemnace) (Ping timeout: 256 seconds)
2023-12-10 04:20:25 +0100lottaquestions(~nick@2607:fa49:503d:b200:8455:7551:a8b5:adb1)
2023-12-10 04:29:53 +0100lane1(~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Quit: WeeChat 4.1.2)
2023-12-10 04:35:38 +0100 <ski> newsham : hm, which category ?
2023-12-10 04:36:03 +0100 <ski> the one int-e sketched ?
2023-12-10 04:41:39 +0100 <int-e> :t id +++ id
2023-12-10 04:41:40 +0100 <lambdabot> Either b b' -> Either b b'
2023-12-10 04:41:44 +0100tremon(~tremon@83.80.159.219) (Quit: getting boxed in)
2023-12-10 04:42:14 +0100 <int-e> :t either Right Left -- something extra
2023-12-10 04:42:15 +0100 <lambdabot> Either b a -> Either a b
2023-12-10 04:42:37 +0100td_(~td@i5387091B.versanet.de) (Ping timeout: 256 seconds)
2023-12-10 04:42:44 +0100 <newsham> how does Either (a' -> a'') (b' -> b'') compose with (Either (a -> a') (b -> b') ?
2023-12-10 04:43:10 +0100 <newsham> given that you might have Left (g :: a -> a'') and Right (f :: b -> b')
2023-12-10 04:43:19 +0100 <int-e> newsham: It doesn't
2023-12-10 04:43:35 +0100 <newsham> so what is the proper type for composition?  do the left and right have to be more compat?
2023-12-10 04:44:02 +0100 <int-e> @djinn Either (a -> b) (a' -> b') -> Either (b -> c) (b' -> c') -> Either (a -> c) (a' -> c')
2023-12-10 04:44:02 +0100 <lambdabot> -- f cannot be realized.
2023-12-10 04:44:05 +0100td_(~td@i53870907.versanet.de)
2023-12-10 04:44:22 +0100 <ski> newsham : is that supposed to be ordinary `Either' in Haskell ?
2023-12-10 04:44:45 +0100 <ski> (or some data constructor for a datakind, maybe ?)
2023-12-10 04:44:47 +0100 <int-e> "You can embed Prod (a -> b) (c -> d) into Either a c -> Either b d."
2023-12-10 04:45:15 +0100 <int-e> In which case the composition you want is just function composition. But there are extra functions in there like that `either Right Left` thing.
2023-12-10 04:45:28 +0100 <int-e> So it's really just an embedding.
2023-12-10 04:45:55 +0100 <int-e> But it would work with the existing `Category` class.
2023-12-10 04:47:09 +0100 <int-e> :t (+++)
2023-12-10 04:47:10 +0100 <lambdabot> ArrowChoice a => a b c -> a b' c' -> a (Either b b') (Either c c')
2023-12-10 04:47:12 +0100 <ski> (note that the `Prod' in `Prod (a -> b) (c -> d)' doesn't really have to do with product categories)
2023-12-10 04:47:16 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-10 04:47:25 +0100 <newsham> bartosz' cat theory for programmers talks about constructing a category from a prod of two categories, and shows the construction.  he also mentions constructing a category from a coprod of two categories but does not go into details.  i'm trying to figure out what it means.
2023-12-10 04:47:47 +0100 <int-e> ski: yeah good point
2023-12-10 04:47:51 +0100 <ski> the coproduct category is more involved, iirc
2023-12-10 04:48:17 +0100 <newsham> ok, maybe i should wait till later in the series to try to figure this out then.
2023-12-10 04:48:51 +0100 <int-e> (a -> b, c -> d) captures fewer functions than (a,c) -> (b,d).
2023-12-10 04:48:53 +0100 <int-e> :t (***)
2023-12-10 04:48:54 +0100 <ski> i like the search/optimization analogy that Bartosz uses for limits and colimits
2023-12-10 04:48:55 +0100 <lambdabot> Arrow a => a b c -> a b' c' -> a (b, b') (c, c')
2023-12-10 04:49:09 +0100 <int-e> (another embedding)
2023-12-10 04:49:44 +0100 <ski> .. a philosophy paper i read, that talks about category theory, and Plato's theory of forms, uses the same analogy more or less, iirc
2023-12-10 04:51:09 +0100 <ski> "Category Theory and Concrete Universals" by David P. Ellerman in 1998-05 at <https://www.ellerman.org/wp-content/uploads/2012/12/Erkenntnis-Concrete-Universals.CV_.pdf> -- although, iirc, some of the formulae in the paper were unfortunately somewhat confused
2023-12-10 04:53:14 +0100finn_elija(~finn_elij@user/finn-elija/x-0085643)
2023-12-10 04:53:14 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
2023-12-10 04:53:14 +0100finn_elijaFinnElija
2023-12-10 04:57:19 +0100mosul(~mosul@user/mosul) (Read error: Connection reset by peer)
2023-12-10 05:02:35 +0100mosul(~mosul@user/mosul)
2023-12-10 05:03:01 +0100drdo(~drdo@bl14-14-49.dsl.telepac.pt) (Ping timeout: 255 seconds)
2023-12-10 05:13:04 +0100szkl(uid110435@id-110435.uxbridge.irccloud.com)
2023-12-10 05:19:40 +0100jargon(~jargon@32.sub-174-238-226.myvzw.com) (Remote host closed the connection)
2023-12-10 05:24:55 +0100 <ski> right, on page eight, it says "As a universality condition, this is: ⟨f,g⟩ uniquely factors through ⟨π₁,π₂⟩ iff for some x, f: x ⟶ a and g: x ⟶ b.", but it ought to say "As a universality condition, this is: ⟨f,g⟩ uniquely factors through ⟨π₁,π₂⟩ iff for some unique h: x ⟶ a × b, f = π₁ ∘ h and g = π₂ ∘ h."
2023-12-10 05:25:04 +0100 <ski> also, on page thirteen, when it talks about union, it ought to use the union symbol ⌜∪⌝, not the intersection symbol ⌜∩⌝, iow ought to say ⌜for all x, x ≥ a ∪ b iff a ≤ x & b ≤ x⌝, rather than ⌜for all x, x ≥ a ∩ b iff a ≤ x & b ≤ x⌝. and on page fourteen, it ought to say ⌜⋂{x ∣ a ≤ x & b ≤ x} = a ∪ b⌝ rather than ⌜⋂{x ∣ a ≤ x & b ≤ x} = a ∩ b⌝
2023-12-10 05:26:45 +0100araujo(~araujo@45.131.194.89)
2023-12-10 05:26:50 +0100 <araujo> howdy :)
2023-12-10 05:28:01 +0100 <ski> oy
2023-12-10 05:28:34 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5)
2023-12-10 05:31:43 +0100araujo(~araujo@45.131.194.89) (Remote host closed the connection)
2023-12-10 05:32:36 +0100araujo(~araujo@45.131.194.89)
2023-12-10 05:36:00 +0100 <araujo> :)
2023-12-10 05:41:04 +0100aforemny(~aforemny@2001:9e8:6cf6:8a00:1295:f852:5f8f:52b5)
2023-12-10 05:42:35 +0100aforemny_(~aforemny@i59F516ED.versanet.de) (Ping timeout: 264 seconds)
2023-12-10 05:44:42 +0100igemnace_(~ian@user/igemnace) (Quit: WeeChat 4.1.2)
2023-12-10 05:45:15 +0100thegeekinside(~thegeekin@177.245.195.141) (Ping timeout: 252 seconds)
2023-12-10 05:45:18 +0100lane(~lane@pool-98-113-180-17.nycmny.fios.verizon.net)
2023-12-10 05:45:34 +0100sagax(~sagax_nb@user/sagax) (Remote host closed the connection)
2023-12-10 05:46:07 +0100lane(~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Remote host closed the connection)
2023-12-10 05:46:31 +0100igemnace(~ian@user/igemnace)
2023-12-10 05:47:54 +0100araujo(~araujo@45.131.194.89) (Quit: Leaving)
2023-12-10 05:48:30 +0100araujo(~araujo@45.131.194.89)
2023-12-10 05:48:47 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 256 seconds)
2023-12-10 05:51:52 +0100araujo(~araujo@45.131.194.89) (Client Quit)
2023-12-10 05:52:15 +0100araujo(~araujo@45.131.194.89)
2023-12-10 06:00:37 +0100DerDummNemetzkii(~John_Ivan@user/john-ivan/x-1515935) (Ping timeout: 255 seconds)
2023-12-10 06:09:12 +0100hgolden_(~hgolden@2603-8000-9d00-3ed1-dd4f-298a-9c49-a0ed.res6.spectrum.com) (Remote host closed the connection)
2023-12-10 06:09:58 +0100trev(~trev@user/trev)
2023-12-10 06:10:39 +0100trev(~trev@user/trev) (Read error: Connection reset by peer)
2023-12-10 06:11:20 +0100hgolden(~hgolden@2603-8000-9d00-3ed1-dd4f-298a-9c49-a0ed.res6.spectrum.com)
2023-12-10 06:11:57 +0100trev(~trev@user/trev)
2023-12-10 06:22:45 +0100azimut(~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection)
2023-12-10 06:25:58 +0100azimut(~azimut@gateway/tor-sasl/azimut)
2023-12-10 06:27:52 +0100azimut(~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection)
2023-12-10 06:28:11 +0100azimut(~azimut@gateway/tor-sasl/azimut)
2023-12-10 06:32:08 +0100takuan(~takuan@178-116-218-225.access.telenet.be)
2023-12-10 06:33:05 +0100Pozyomka_(~pyon@user/pyon)
2023-12-10 06:33:07 +0100Pozyomka(~pyon@user/pyon) (Ping timeout: 256 seconds)
2023-12-10 06:35:25 +0100igemnace(~ian@user/igemnace) (Remote host closed the connection)
2023-12-10 06:36:10 +0100igemnace(~ian@user/igemnace)
2023-12-10 06:45:52 +0100igemnace(~ian@user/igemnace) (Remote host closed the connection)
2023-12-10 06:46:36 +0100igemnace(~ian@user/igemnace)
2023-12-10 06:52:24 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com)
2023-12-10 07:04:29 +0100araujo(~araujo@45.131.194.89) (Quit: Leaving)
2023-12-10 07:06:48 +0100araujo(~araujo@216.73.163.11)
2023-12-10 07:08:42 +0100ec(~ec@gateway/tor-sasl/ec) (Remote host closed the connection)
2023-12-10 08:06:53 +0100sagax(~sagax_nb@user/sagax)
2023-12-10 08:20:13 +0100notzmv(~zmv@user/notzmv) (Ping timeout: 256 seconds)
2023-12-10 08:22:05 +0100skyres(~skyres@176.254.244.83)
2023-12-10 08:22:45 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-10 08:23:16 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 255 seconds)
2023-12-10 08:29:01 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 08:32:51 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-10 08:33:10 +0100smalltalkman(uid545680@id-545680.hampstead.irccloud.com) (Quit: Connection closed for inactivity)
2023-12-10 08:36:36 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 245 seconds)
2023-12-10 08:43:26 +0100cwdar^(~cd@c-98-242-74-66.hsd1.ga.comcast.net)
2023-12-10 08:44:14 +0100acidjnk_new(~acidjnk@p200300d6e72b93299103c78233b0ca81.dip0.t-ipconnect.de)
2023-12-10 08:45:54 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 08:46:33 +0100igemnace(~ian@user/igemnace) (Quit: WeeChat 4.1.2)
2023-12-10 08:48:45 +0100m1dnight(~christoph@78-22-4-67.access.telenet.be) (Quit: WeeChat 4.1.1)
2023-12-10 08:50:46 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 260 seconds)
2023-12-10 08:51:41 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 252 seconds)
2023-12-10 09:04:18 +0100bilegeek(~bilegeek@2600:1008:b065:6c8a:2877:790c:5cda:9f45) (Quit: Leaving)
2023-12-10 09:05:17 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-10 09:06:00 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 09:23:29 +0100m1dnight(~christoph@78-22-4-67.access.telenet.be)
2023-12-10 09:25:52 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 256 seconds)
2023-12-10 09:39:52 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 09:44:20 +0100fendor(~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c)
2023-12-10 09:45:42 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 268 seconds)
2023-12-10 09:46:11 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-10 09:48:07 +0100phma(~phma@2001:5b0:2143:b148:7b24:e989:5355:982f) (Read error: Connection reset by peer)
2023-12-10 09:51:15 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 268 seconds)
2023-12-10 09:56:02 +0100waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
2023-12-10 09:57:52 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 10:00:14 +0100phma(phma@2001:5b0:215d:95d8:ddad:50d4:4c93:5f61)
2023-12-10 10:01:20 +0100Tuplanolla(~Tuplanoll@91-159-68-236.elisa-laajakaista.fi)
2023-12-10 10:02:08 +0100arkoinad(~abhinav@c-67-169-139-16.hsd1.ca.comcast.net) (Ping timeout: 256 seconds)
2023-12-10 10:02:10 +0100tzh(~tzh@c-71-193-181-0.hsd1.or.comcast.net) (Quit: zzz)
2023-12-10 10:03:53 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 268 seconds)
2023-12-10 10:06:28 +0100idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
2023-12-10 10:12:05 +0100sagax(~sagax_nb@user/sagax) (Excess Flood)
2023-12-10 10:15:57 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 10:16:10 +0100_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl)
2023-12-10 10:19:45 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:1fe:ac5a:8c23:9cce) (Remote host closed the connection)
2023-12-10 10:24:06 +0100jmdaemon(~jmdaemon@user/jmdaemon) (Ping timeout: 260 seconds)
2023-12-10 10:26:37 +0100phma(phma@2001:5b0:215d:95d8:ddad:50d4:4c93:5f61) (Read error: Connection reset by peer)
2023-12-10 10:30:52 +0100phma(~phma@2001:5b0:211c:d608:d6b3:ddaf:3415:a75)
2023-12-10 10:30:58 +0100notzmv(~zmv@user/notzmv)
2023-12-10 10:35:02 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Read error: Connection reset by peer)
2023-12-10 10:38:59 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 264 seconds)
2023-12-10 10:43:21 +0100rosco(~rosco@175.136.152.56)
2023-12-10 10:43:37 +0100coot(~coot@89-69-206-216.dynamic.chello.pl)
2023-12-10 10:48:20 +0100gmg(~user@user/gehmehgeh)
2023-12-10 10:50:41 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 10:54:48 +0100econo_(uid147250@id-147250.tinside.irccloud.com) (Quit: Connection closed for inactivity)
2023-12-10 10:56:23 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 264 seconds)
2023-12-10 10:58:45 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:d128:ce35:54e1:65e2)
2023-12-10 11:09:58 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 11:18:28 +0100Lord_of_Life_(~Lord@user/lord-of-life/x-2819915)
2023-12-10 11:19:10 +0100Lord_of_Life(~Lord@user/lord-of-life/x-2819915) (Ping timeout: 260 seconds)
2023-12-10 11:21:24 +0100Lord_of_Life_Lord_of_Life
2023-12-10 11:22:06 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655)
2023-12-10 11:29:58 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 256 seconds)
2023-12-10 11:32:58 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 11:33:38 +0100target_i(~target_i@217.175.14.39)
2023-12-10 11:38:39 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 260 seconds)
2023-12-10 11:49:15 +0100Sgeo(~Sgeo@user/sgeo) (Read error: Connection reset by peer)
2023-12-10 11:51:47 +0100sawilagar(~sawilagar@user/sawilagar)
2023-12-10 11:52:14 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 11:57:02 +0100mikess(~sam@user/mikess) (Ping timeout: 252 seconds)
2023-12-10 12:05:25 +0100Katty(~osboxes@185.98.164.21)
2023-12-10 12:07:56 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 256 seconds)
2023-12-10 12:09:57 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-10 12:10:14 +0100xff0x(~xff0x@ai085147.d.east.v6connect.net) (Ping timeout: 252 seconds)
2023-12-10 12:12:05 +0100xff0x(~xff0x@178.255.149.135)
2023-12-10 12:14:53 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 240 seconds)
2023-12-10 12:16:23 +0100Katty(~osboxes@185.98.164.21) (Quit: Konversation terminated!)
2023-12-10 12:20:09 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 12:21:17 +0100billchenchina(~billchenc@103.152.35.21)
2023-12-10 12:22:23 +0100machinedgod(~machinedg@93-136-52-133.adsl.net.t-com.hr)
2023-12-10 12:22:27 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
2023-12-10 12:23:04 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-10 12:30:10 +0100rosco(~rosco@175.136.152.56) (Ping timeout: 276 seconds)
2023-12-10 12:32:16 +0100Joao003(~Joao003@190.108.99.32)
2023-12-10 12:36:49 +0100xff0x(~xff0x@178.255.149.135) (Ping timeout: 268 seconds)
2023-12-10 12:38:44 +0100xff0x(~xff0x@ai085147.d.east.v6connect.net)
2023-12-10 12:39:17 +0100rosco(~rosco@175.136.152.56)
2023-12-10 12:40:22 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 260 seconds)
2023-12-10 12:53:40 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 12:55:09 +0100alexherbo2(~alexherbo@2a02-8440-3141-30c9-9c1f-1fa2-2dd0-8b5b.rev.sfr.net)
2023-12-10 12:56:04 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470)
2023-12-10 13:00:04 +0100[_](~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 276 seconds)
2023-12-10 13:01:11 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 245 seconds)
2023-12-10 13:01:45 +0100mrmr15533(~mrmr@user/mrmr) (Quit: Bye, See ya later!)
2023-12-10 13:05:05 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470) (Remote host closed the connection)
2023-12-10 13:06:54 +0100mrmr15533(~mrmr@user/mrmr)
2023-12-10 13:09:25 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-10 13:10:19 +0100mniip_mniip
2023-12-10 13:14:19 +0100vgtw(~vgtw@user/vgtw) (Ping timeout: 256 seconds)
2023-12-10 13:15:35 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 13:34:19 +0100target_i(~target_i@217.175.14.39) (Quit: leaving)
2023-12-10 13:34:46 +0100billchenchina(~billchenc@103.152.35.21) (Remote host closed the connection)
2023-12-10 13:34:57 +0100billchenchina(~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe)
2023-12-10 13:37:39 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 260 seconds)
2023-12-10 13:37:51 +0100not_reserved(~not_reser@185.216.201.100) (Quit: Client closed)
2023-12-10 13:41:42 +0100Ashkan(~Ashkan@147.161.173.72)
2023-12-10 13:42:03 +0100jtomas(~jtomas@90.162.208.36)
2023-12-10 13:46:13 +0100foul_owl(~kerry@157.97.134.165) (Ping timeout: 276 seconds)
2023-12-10 13:47:00 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 13:47:42 +0100 <Joao003> me waiting for someone to ask something:
2023-12-10 13:48:10 +0100 <Ashkan> Hi folks. Got a question regarding a datatype + possibly a monad to model a search across a Foldable.
2023-12-10 13:48:11 +0100 <Ashkan> I have a Foldable (a `Vector a` to be exact) and I need to run an `f :: a -> ??? s b ` on it and exit when the first `a` is found such that `f` produces a result that satisfies a certain condition. Not sure how to model this though. Lots of dark spots in my head:D
2023-12-10 13:50:11 +0100 <[Leary]> :t find
2023-12-10 13:50:12 +0100 <lambdabot> Foldable t => (a -> Bool) -> t a -> Maybe a
2023-12-10 13:50:14 +0100 <Ashkan> `f` is "state-full" in `s`, meaning there is an initial `s0` and then as `f` progresses on the input Foldable, it updates the `s` until eventually one `a` arrives that results in the `??? s b` to "short-circuit" (using monad terminology) and exit
2023-12-10 13:50:54 +0100 <Rembane> :t First -- along with foldMap could perhaps also help you, if you want a Monoid solution to this problem.
2023-12-10 13:50:55 +0100 <lambdabot> Maybe a -> First a
2023-12-10 13:51:08 +0100 <Rembane> Hm... wrong First.
2023-12-10 13:51:29 +0100 <Ashkan> so far I think closest is `foldlM`
2023-12-10 13:51:32 +0100 <Ashkan> :t foldlM
2023-12-10 13:51:33 +0100 <lambdabot> (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
2023-12-10 13:51:56 +0100 <Rembane> Ashkan: But I think [Leary]'s solution is the simplest one.
2023-12-10 13:52:03 +0100 <Joao003> yeah
2023-12-10 13:52:57 +0100Aworks(~Aworks@2a09:bac2:c63:3cd::61:26e)
2023-12-10 13:53:04 +0100 <Joao003> but the tricky thing is extracting the result from the `Maybe a' that `find' produces
2023-12-10 13:53:10 +0100 <Ashkan> Please notice `f :: b -> a -> m b` which is actually closest to my needs but not quite. Because (1) my action is monadic (it's an `IO` in fact) and (2) I don't want the matching `a` itself, I want the result of the operation
2023-12-10 13:53:34 +0100 <Joao003> oh ok
2023-12-10 13:54:20 +0100 <Joao003> you could use something like a `Maybe' for `m'
2023-12-10 13:55:11 +0100 <Aworks> upi
2023-12-10 13:55:34 +0100 <Aworks> Buddies have build an full Windows with husk
2023-12-10 13:55:49 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 255 seconds)
2023-12-10 13:56:10 +0100 <Ashkan> Okay let me put this way then:
2023-12-10 13:56:10 +0100 <Ashkan> I'm doing a Vulkan thingie and I have a list of devices `Vector Vk.Device` . Now I need to do some magic `IO` thing on each device to extract some `b` out (`doMagic :: Device -> IO b`) and exit with the first `b` that passes a certain check. I don't want the device itself, I want the `b`.
2023-12-10 13:57:09 +0100 <Joao003> OK, I understand.
2023-12-10 13:59:02 +0100 <Joao003> So you have a list of `Device's, and want do do some `IO' thing to each one, checking for a condition until you find the first one that passes. Am I correct?
2023-12-10 13:59:12 +0100 <Ashkan> Joao003 `Maybe b` doesn't have the `IO` in it. If I make it `MaybeT IO b` then it will short-circut on `Nothing` which means I stop at the right spot but then I get nothing out. I was thinking `ExceptT IO found state` and model "success" (in `found`) as left and "contiunue with the search" (in `state`) as right. But I'm not sure if this is
2023-12-10 13:59:12 +0100 <Ashkan> idiomatic ...
2023-12-10 13:59:55 +0100foul_owl(~kerry@174-21-66-189.tukw.qwest.net)
2023-12-10 14:00:03 +0100aruns(~aruns@user/aruns)
2023-12-10 14:00:09 +0100 <Ashkan> Joao003 yes but : the check involves an accumulating state. So first device the state is `s0` but next device the state has changed. the `f` updates the state
2023-12-10 14:00:21 +0100 <Joao003> Oh.
2023-12-10 14:00:48 +0100 <Ashkan> Also I don't want the device itself, I want the output of `Device -> IO b` (the `b`)
2023-12-10 14:00:54 +0100 <Joao003> I KNOW.
2023-12-10 14:01:26 +0100 <Joao003> So you want a function kinda like a fold and `find', right?
2023-12-10 14:02:15 +0100 <Ashkan> like this `f: Device -> ExceptT IO b s`. `IO Left b` means we found it, exit with the `Left b`, `IO Right s` means "continue with the next device and new state `s`"
2023-12-10 14:02:37 +0100 <Joao003> Ok.
2023-12-10 14:04:02 +0100 <Ashkan> Joao003 Yes. I'm "interpreting" (maybe I'm wrong ?) from `foldlM` that choosing the right `m` with the short-circuting behaviour would in effect achieve what I want. But the only monad I can think of that short-circuts with a value AND can do `IO` is `ExceptT`
2023-12-10 14:04:35 +0100 <Joao003> So a `foldl' which after each function application checks the result for something and prematurely stops if it finds the right one?
2023-12-10 14:06:13 +0100 <Joao003> BTW, what is an `ExceptT'?
2023-12-10 14:06:56 +0100alexherbo2(~alexherbo@2a02-8440-3141-30c9-9c1f-1fa2-2dd0-8b5b.rev.sfr.net) (Ping timeout: 250 seconds)
2023-12-10 14:07:18 +0100 <Ashkan> Joao003 actually if it was *not* monadic (the need for `IO`) then a `foldr` would be what I want because I needed the `f` to be lazy in the accumulator
2023-12-10 14:07:24 +0100 <Ashkan> :t ExceptT
2023-12-10 14:07:25 +0100 <lambdabot> m (Either e a) -> ExceptT e m a
2023-12-10 14:07:40 +0100 <Ashkan> It's the new EitherT
2023-12-10 14:07:43 +0100 <Ashkan> :t EitherT
2023-12-10 14:07:44 +0100 <lambdabot> error:
2023-12-10 14:07:44 +0100 <lambdabot> • Data constructor not in scope: EitherT
2023-12-10 14:07:44 +0100 <lambdabot> • Perhaps you meant variable ‘either’ (imported from Data.Either)
2023-12-10 14:07:55 +0100 <Ashkan> They just removed the EitherT I guess
2023-12-10 14:08:27 +0100 <[Leary]> :t \p -> traverse_ (when <$> p <*> throwE)
2023-12-10 14:08:28 +0100 <lambdabot> (Foldable t, Monad m) => (a -> Bool) -> t a -> ExceptT a m ()
2023-12-10 14:08:36 +0100 <Joao003> :t Either
2023-12-10 14:08:37 +0100 <lambdabot> error:
2023-12-10 14:08:37 +0100 <lambdabot> • Data constructor not in scope: Either
2023-12-10 14:08:37 +0100 <lambdabot> • Perhaps you meant variable ‘either’ (imported from Data.Either)
2023-12-10 14:08:45 +0100 <Ashkan> `ExceptT b IO s` = can model two states: continue with `s` or exit with `b`
2023-12-10 14:08:48 +0100 <[Leary]> :t \f p -> traverse_ (when <$> p <*> throwE <=< lift . f)
2023-12-10 14:08:48 +0100 <lambdabot> (Foldable t, Monad m) => (a -> m b) -> (b -> Bool) -> t a -> ExceptT b m ()
2023-12-10 14:08:57 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 14:09:28 +0100 <[Leary]> :t \f p -> fmap (either Just (const Nothing)) . runExceptT . traverse_ (when <$> p <*> throwE <=< lift . f)
2023-12-10 14:09:29 +0100 <lambdabot> (Foldable t, Monad f) => (a -> f b) -> (b -> Bool) -> t a -> f (Maybe b)
2023-12-10 14:09:31 +0100 <Ashkan> This is very close actually. Let me see ...
2023-12-10 14:09:38 +0100 <[Leary]> Looks about right.
2023-12-10 14:09:43 +0100 <Joao003> So basically `ExceptT b IO s' is `IO (Either b s)', right?
2023-12-10 14:10:26 +0100 <Ashkan> Joao003 yes. Not sure what call it `ExceptT` and confuse the hell out of everyone. But yes. Basically an `EitherT`
2023-12-10 14:11:02 +0100 <Joao003> Yeah, Haskell naming is pretty confusing. Like, who named `return'/`pure'?
2023-12-10 14:12:05 +0100alexherbo2(~alexherbo@2a02-8440-3140-ec03-d472-b551-beb0-2cfa.rev.sfr.net)
2023-12-10 14:12:37 +0100 <Ashkan> `IO (Either b s)` has the right data structure to model my two paths (continue the chain with a new state value or exit with a value) *but* it does NOT have the right short-circuting because the monad then is `IO`, `ExceptT` will exit if it's value is `IO (Left b)` but `IO` will *not*
2023-12-10 14:12:56 +0100 <Joao003> Hmm.
2023-12-10 14:13:09 +0100 <Ashkan> actually that point is the key here
2023-12-10 14:13:20 +0100 <Ashkan> Think about it. Maybe I'm woring.
2023-12-10 14:14:33 +0100 <Ashkan> I want the `IO (Left b)` to stop the search. I want the `IO (Right s)` to continue the search with the new `s`. `IO (Either b s)` will not do that but `ExceptT s IO b` will do that.
2023-12-10 14:14:54 +0100 <Joao003> This is kinda off-topic, but GHC quotes with `' instead of ``.
2023-12-10 14:15:08 +0100 <Ashkan> and I'm using a `fold*` variant to model the "search"
2023-12-10 14:16:18 +0100 <Joao003> Can you explain why the `ExceptT' is important?
2023-12-10 14:17:58 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Read error: Connection reset by peer)
2023-12-10 14:18:03 +0100 <Ashkan> Because `IO (Left b)` will not exit, because monad is `IO` and `IO` exits on io exceptions. `IO Left x` continues the chain with a `Left x`
2023-12-10 14:18:57 +0100 <Joao003> Ok.
2023-12-10 14:19:11 +0100 <Ashkan> I want a monad that exits when it holds a `Left b`. `ExceptT` does that. But if I can find another monad that can do `IO` *and* can model two outcomes (continue with `s` or exit with `b`) , that would also do.
2023-12-10 14:20:06 +0100 <Joao003> What do you mean by "exit"?
2023-12-10 14:20:17 +0100 <Ashkan> [Leary] since you came up with the best signature, would you please comment on my last message ? specially do you know of a way I can get the behaviour I want other than ExceptT ? thanks
2023-12-10 14:21:06 +0100 <[Leary]> It would also work to embed the `b` in an IO exception and catch it on the outside, but that would involve a little more boilerplate. I'm sure you could do it with ContT too, but there's no reason to go there.
2023-12-10 14:21:12 +0100 <Ashkan> Joao003 short-circut the monadic chain created by `fold**`. e.g. `Maybe` will exit on `Nothing`. `Either` will exit on `Left`. `IO` will exit if an exception is thrown
2023-12-10 14:21:55 +0100 <Ashkan> Joao003 The essence of monad is when it continues with the flatMap and when it short-circuts
2023-12-10 14:22:24 +0100szkl(uid110435@id-110435.uxbridge.irccloud.com) (Quit: Connection closed for inactivity)
2023-12-10 14:22:37 +0100 <Joao003> I think the monads conflict what you want
2023-12-10 14:23:22 +0100 <Ashkan> [Leary] `IO` with an exception is exactly what I thought at first but then it sounds way far off to model a "found it" outcome with an IO exception. Didn't think about `ContT` though ...
2023-12-10 14:24:34 +0100cwdar^(~cd@c-98-242-74-66.hsd1.ga.comcast.net) (Remote host closed the connection)
2023-12-10 14:25:33 +0100vgtw(~vgtw@user/vgtw)
2023-12-10 14:25:51 +0100 <Ashkan> wdyt of introducing my own monad like `data Search m b s = m Found b | m Continue s` with the proper `>>=` ? too much ?
2023-12-10 14:26:22 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 246 seconds)
2023-12-10 14:26:31 +0100 <Joao003> @hoogle ContT
2023-12-10 14:26:31 +0100 <lambdabot> Control.Monad.Trans.Cont newtype ContT r m a
2023-12-10 14:26:31 +0100 <lambdabot> Control.Monad.Trans.Cont ContT :: ((a -> m r) -> m r) -> ContT r m a
2023-12-10 14:26:31 +0100 <lambdabot> Control.Monad.Cont newtype ContT (r :: k) (m :: k -> *) a
2023-12-10 14:26:32 +0100euleritian(~euleritia@dynamic-046-114-204-242.46.114.pool.telefonica.de)
2023-12-10 14:26:32 +0100 <Ashkan> Joao003 Could be. Why do you say ?
2023-12-10 14:27:39 +0100alexherbo2(~alexherbo@2a02-8440-3140-ec03-d472-b551-beb0-2cfa.rev.sfr.net) (Remote host closed the connection)
2023-12-10 14:27:54 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 256 seconds)
2023-12-10 14:28:00 +0100 <Joao003> Here is some docs of `ContT' from Hackage: "The continuation monad transformer. Can be used to add continuation handling to any type constructor: the Monad instance and most of the operations do not require m to be a monad."
2023-12-10 14:28:52 +0100alexherbo2(~alexherbo@54.149.22.93.rev.sfr.net)
2023-12-10 14:29:05 +0100 <Joao003> Ashkan: I think you can make a monad on your own for this.
2023-12-10 14:34:02 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 14:40:12 +0100 <[Leary]> Ashkan: I definitely wouldn't bother writing `Search` if it's doing exactly the same thing as ExceptT. At most, I'd consider renaming/wrapping some of the ExceptT interface for clarity.
2023-12-10 14:40:20 +0100 <ski> Ashkan : "I was thinking `ExceptT IO found state` and model \"success\" (in `found`) as left and \"contiunue with the search\" (in `state`) as right. But I'm not sure if this is idiomatic ..." -- sounds fine, to me
2023-12-10 14:40:25 +0100 <ski> @unmtl ExceptT b (StateT s IO) a
2023-12-10 14:40:25 +0100 <lambdabot> s -> IO (Either b a, s)
2023-12-10 14:40:29 +0100 <ski> f :: Device -> ExceptT b (StateT s IO) ()
2023-12-10 14:40:41 +0100 <ski> so you can use `traverse_ f'
2023-12-10 14:41:13 +0100mechap(~mechap@user/mechap)
2023-12-10 14:41:48 +0100 <ski> ah, i see [Leary] was on this track already
2023-12-10 14:42:49 +0100 <ski> or, if you don't want a result `s' in case you find a matching `b', use `StateT s (ExceptT e IO)' instead
2023-12-10 14:43:23 +0100 <ski> (i was thinking you wanted the last `s', regardless, but perhaps you don't)
2023-12-10 14:44:04 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 276 seconds)
2023-12-10 14:45:44 +0100drdo(~drdo@bl14-14-49.dsl.telepac.pt)
2023-12-10 14:46:02 +0100 <ski> (er, s/ExceptT e/ExceptT b/)
2023-12-10 14:47:41 +0100 <Ashkan> ski hmm ... nice.
2023-12-10 14:49:46 +0100 <Ashkan> I want to the first `s` that matches a predicate. The `s` changes while I'm running over the list of devices. So you are saying instead of seeing it as a fold over elements, see it has a state running on them via traverse ? novel +|1
2023-12-10 14:49:55 +0100 <Ashkan> didn't think of it that way
2023-12-10 14:50:41 +0100 <Ashkan> (yeah, I want the "last" s, correct)
2023-12-10 14:52:12 +0100 <[Leary]> @src traverse_
2023-12-10 14:52:13 +0100 <lambdabot> traverse_ h xs = foldr (\fx fxs -> h fx *> fxs) (pure ())
2023-12-10 14:52:13 +0100 <lambdabot> --OR
2023-12-10 14:52:13 +0100 <lambdabot> traverse_ h xs = traverse h xs *> pure ()
2023-12-10 14:52:24 +0100 <[Leary]> `traverse_` /is/ a fold.
2023-12-10 14:54:42 +0100machinedgod(~machinedg@93-136-52-133.adsl.net.t-com.hr) (Ping timeout: 252 seconds)
2023-12-10 14:55:54 +0100Aworks(~Aworks@2a09:bac2:c63:3cd::61:26e) (Ping timeout: 250 seconds)
2023-12-10 14:58:10 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 14:59:35 +0100acidjnk_new(~acidjnk@p200300d6e72b93299103c78233b0ca81.dip0.t-ipconnect.de) (Ping timeout: 268 seconds)
2023-12-10 15:00:28 +0100finn_elija(~finn_elij@user/finn-elija/x-0085643)
2023-12-10 15:00:28 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
2023-12-10 15:00:28 +0100finn_elijaFinnElija
2023-12-10 15:02:40 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 268 seconds)
2023-12-10 15:11:50 +0100 <ski> Ashkan : yea, but do you want the last `s', in case you find a matching `b' ?
2023-12-10 15:13:12 +0100jtomas(~jtomas@90.162.208.36) (Quit: Leaving)
2023-12-10 15:14:10 +0100rosco(~rosco@175.136.152.56) (Quit: Lost terminal)
2023-12-10 15:14:34 +0100 <ski> @type traverse_ -- see `Foldable', not `Traversable'
2023-12-10 15:14:34 +0100 <lambdabot> (Foldable t, Applicative f) => (a -> f b) -> t a -> f ()
2023-12-10 15:15:42 +0100billchenchina(~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe) (Remote host closed the connection)
2023-12-10 15:16:14 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 15:16:25 +0100euleritian(~euleritia@dynamic-046-114-204-242.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
2023-12-10 15:16:33 +0100billchenchina(~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe)
2023-12-10 15:16:42 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-10 15:16:42 +0100alexherbo2(~alexherbo@54.149.22.93.rev.sfr.net) (Ping timeout: 250 seconds)
2023-12-10 15:17:21 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
2023-12-10 15:18:11 +0100euleritian(~euleritia@77.22.252.56)
2023-12-10 15:18:59 +0100 <ski> @type mapAccumL
2023-12-10 15:18:59 +0100euleritian(~euleritia@77.22.252.56) (Read error: Connection reset by peer)
2023-12-10 15:19:00 +0100 <lambdabot> Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c)
2023-12-10 15:19:07 +0100 <ski> @type ((state . (swap .)) .) . flip . mapAccumL . flip . (((swap .) . runState) .) :: Traversable t => (a -> State s b) -> (t a -> State s (t b))
2023-12-10 15:19:08 +0100 <lambdabot> Traversable t => (a -> State s b) -> t a -> State s (t b)
2023-12-10 15:19:13 +0100 <ski> @type mapM :: Traversable t => (a -> State s b) -> (t a -> State s (t b))
2023-12-10 15:19:14 +0100 <lambdabot> Traversable t => (a -> State s b) -> t a -> State s (t b)
2023-12-10 15:19:40 +0100 <ski> @type traverse :: Traversable t => (a -> State s b) -> (t a -> State s (t b))
2023-12-10 15:19:41 +0100 <lambdabot> Traversable t => (a -> State s b) -> t a -> State s (t b)
2023-12-10 15:19:43 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-10 15:20:53 +0100 <ski> Ashkan : note that these do the same thing. doing a `foldl'-like operation (like `foldM' does), with an accumulator state `s', corresponds to doing a `traverse'/`mapM' on `StateT s'
2023-12-10 15:21:06 +0100 <Joao003> @type StateT
2023-12-10 15:21:07 +0100 <lambdabot> (s -> m (a, s)) -> StateT s m a
2023-12-10 15:21:21 +0100 <ski> @type runStateT
2023-12-10 15:21:22 +0100 <lambdabot> StateT s m a -> s -> m (a, s)
2023-12-10 15:21:42 +0100 <ski> @type state :: (s -> (a,s)) -> State s a
2023-12-10 15:21:43 +0100 <lambdabot> (s -> (a, s)) -> State s a
2023-12-10 15:21:48 +0100 <ski> @type runState
2023-12-10 15:21:49 +0100 <lambdabot> State s a -> s -> (a, s)
2023-12-10 15:22:04 +0100 <Joao003> @type State
2023-12-10 15:22:05 +0100 <lambdabot> error:
2023-12-10 15:22:05 +0100 <lambdabot> • Data constructor not in scope: State
2023-12-10 15:22:05 +0100 <lambdabot> • Perhaps you meant one of these:
2023-12-10 15:22:09 +0100 <Joao003> ...
2023-12-10 15:22:19 +0100nek0(~nek0@2a01:4f8:222:2b41::12) (Quit: The Lounge - https://thelounge.chat)
2023-12-10 15:22:20 +0100 <Joao003> @type State s a
2023-12-10 15:22:21 +0100 <lambdabot> error:
2023-12-10 15:22:21 +0100 <lambdabot> • Data constructor not in scope: State :: Expr -> Expr -> t
2023-12-10 15:22:21 +0100 <lambdabot> • Perhaps you meant one of these:
2023-12-10 15:22:26 +0100 <Joao003> wth
2023-12-10 15:22:29 +0100 <ski> Ashkan : in your case, you didn't want any new structure, with the elements replaced. so `traverse_'/`mapM_' instead
2023-12-10 15:22:43 +0100 <ski> @kind State
2023-12-10 15:22:44 +0100 <lambdabot> * -> * -> *
2023-12-10 15:23:07 +0100 <ski> @src State
2023-12-10 15:23:07 +0100 <lambdabot> type State s = StateT s Identity
2023-12-10 15:23:07 +0100 <lambdabot> --OR
2023-12-10 15:23:07 +0100 <lambdabot> data State s a = State { runState :: s -> (a, s) }
2023-12-10 15:23:19 +0100 <ski> the first one is what's in the library
2023-12-10 15:23:26 +0100 <ski> @src StateT
2023-12-10 15:23:26 +0100 <lambdabot> Source not found. Listen, broccoli brains, I don't have time to listen to this trash.
2023-12-10 15:23:29 +0100 <ski> ok
2023-12-10 15:23:50 +0100 <ski> newtype StateT s m a = StateT {runState :: s -> m (a,s)}
2023-12-10 15:23:56 +0100 <Joao003> @kind StateT
2023-12-10 15:23:57 +0100 <lambdabot> * -> (* -> *) -> * -> *
2023-12-10 15:28:33 +0100Joao003(~Joao003@190.108.99.32) (Quit: Bye!)
2023-12-10 15:29:01 +0100vgtw(~vgtw@user/vgtw) (Ping timeout: 246 seconds)
2023-12-10 15:29:29 +0100billchenchina(~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe) (Ping timeout: 268 seconds)
2023-12-10 15:33:43 +0100qqq(~qqq@92.43.167.61) (Ping timeout: 256 seconds)
2023-12-10 15:40:37 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 276 seconds)
2023-12-10 15:43:15 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 15:43:47 +0100vgtw(~vgtw@user/vgtw)
2023-12-10 15:47:28 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-10 15:50:40 +0100qqq(~qqq@92.43.167.61)
2023-12-10 15:51:20 +0100Square(~Square@user/square)
2023-12-10 15:53:32 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 268 seconds)
2023-12-10 15:54:00 +0100nek0(~nek0@2a01:4f8:222:2b41::12)
2023-12-10 15:57:15 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 16:11:26 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-10 16:16:21 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 268 seconds)
2023-12-10 16:17:04 +0100zetef(~quassel@82.76.107.234)
2023-12-10 16:17:17 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 268 seconds)
2023-12-10 16:19:04 +0100acidjnk_new(~acidjnk@p200300d6e72b93299103c78233b0ca81.dip0.t-ipconnect.de)
2023-12-10 16:23:15 +0100zetef(~quassel@82.76.107.234) (Remote host closed the connection)
2023-12-10 16:27:28 +0100Tlsx(rscastilho@189.61.140.215)
2023-12-10 16:28:27 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470)
2023-12-10 16:35:13 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 276 seconds)
2023-12-10 16:37:44 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 16:43:13 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 255 seconds)
2023-12-10 16:43:45 +0100Ashkan(~Ashkan@147.161.173.72) (Quit: Client closed)
2023-12-10 16:43:55 +0100euleritian(~euleritia@77.22.252.56)
2023-12-10 16:45:43 +0100azimut(~azimut@gateway/tor-sasl/azimut) (Ping timeout: 240 seconds)
2023-12-10 16:45:58 +0100son0p(~ff@181.136.122.143) (Remote host closed the connection)
2023-12-10 16:47:16 +0100vgtw(~vgtw@user/vgtw) (Ping timeout: 256 seconds)
2023-12-10 16:49:43 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 16:52:17 +0100wootehfoot(~wootehfoo@user/wootehfoot)
2023-12-10 16:54:33 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
2023-12-10 16:54:34 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643)
2023-12-10 16:55:04 +0100vgtw(~vgtw@user/vgtw)
2023-12-10 16:58:01 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 256 seconds)
2023-12-10 16:58:11 +0100target_i(~target_i@217.175.14.39)
2023-12-10 16:59:50 +0100son0p(~ff@181.136.122.143)
2023-12-10 17:00:39 +0100aruns(~aruns@user/aruns) (Ping timeout: 252 seconds)
2023-12-10 17:03:13 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-10 17:11:15 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 17:14:00 +0100smalltalkman(uid545680@id-545680.hampstead.irccloud.com)
2023-12-10 17:19:07 +0100azimut(~azimut@gateway/tor-sasl/azimut)
2023-12-10 17:22:54 +0100lg1882lg188
2023-12-10 17:26:31 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-10 17:28:44 +0100danza(~danza@151.43.234.184)
2023-12-10 17:30:20 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 252 seconds)
2023-12-10 17:30:54 +0100waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 252 seconds)
2023-12-10 17:36:50 +0100danza(~danza@151.43.234.184) (Ping timeout: 268 seconds)
2023-12-10 17:39:18 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 17:45:08 +0100gdown(~gavin@h69-11-149-109.kndrid.broadband.dynamic.tds.net)
2023-12-10 17:48:20 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-10 17:48:31 +0100justsomeguy(~justsomeg@user/justsomeguy)
2023-12-10 17:50:05 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470) (Read error: Connection reset by peer)
2023-12-10 17:50:17 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470)
2023-12-10 17:53:03 +0100DerDummNemetzkii(~John_Ivan@user/john-ivan/x-1515935)
2023-12-10 17:56:39 +0100[_](~itchyjunk@user/itchyjunk/x-7353470)
2023-12-10 17:57:31 +0100vgtw(~vgtw@user/vgtw) (Ping timeout: 256 seconds)
2023-12-10 17:59:27 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 260 seconds)
2023-12-10 17:59:56 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 245 seconds)
2023-12-10 18:01:46 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-10 18:02:40 +0100tremon(~tremon@83.80.159.219)
2023-12-10 18:02:42 +0100mikess(~sam@user/mikess)
2023-12-10 18:09:49 +0100AlexZenon(~alzenon@178.34.162.199) (Ping timeout: 268 seconds)
2023-12-10 18:11:36 +0100Xe(~cadey@perl/impostor/xe) (Ping timeout: 245 seconds)
2023-12-10 18:13:41 +0100Xe(~cadey@perl/impostor/xe)
2023-12-10 18:13:42 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 18:13:53 +0100AlexZenon(~alzenon@178.34.162.199)
2023-12-10 18:17:43 +0100dhil(~dhil@2001:8e0:2014:3100:bf6:da90:7ddf:392e)
2023-12-10 18:22:20 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net)
2023-12-10 18:25:50 +0100laxmik(~laxmik@2a01:c23:9597:b700:707f:bbe3:5986:73cb)
2023-12-10 18:26:57 +0100arkoinad(~abhinav@c-67-169-139-16.hsd1.ca.comcast.net)
2023-12-10 18:27:50 +0100kimiamania464(~65804703@user/kimiamania)
2023-12-10 18:27:53 +0100laxmikmichals
2023-12-10 18:30:51 +0100kimiamania46(~65804703@user/kimiamania) (Ping timeout: 252 seconds)
2023-12-10 18:30:51 +0100kimiamania464kimiamania46
2023-12-10 18:40:02 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 268 seconds)
2023-12-10 18:41:40 +0100michals(~laxmik@2a01:c23:9597:b700:707f:bbe3:5986:73cb) (Ping timeout: 250 seconds)
2023-12-10 18:41:55 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 18:44:31 +0100aruns(~aruns@user/aruns)
2023-12-10 18:48:15 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:d128:ce35:54e1:65e2) (Remote host closed the connection)
2023-12-10 18:48:30 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:d128:ce35:54e1:65e2)
2023-12-10 18:57:07 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-10 19:01:50 +0100 <haskellbridge> 12<C​elestial> How do I do cross-thread communication? Specifically I have a single parallel thread which basically dispenses ticks in a fixed time interval into a bounded channel. I want to control this tick delay time, but I'm not sure how to pass this information along to the other thread. I think there's something called an `MVar` which seems like it's kind of what I want? I'm not
2023-12-10 19:01:50 +0100 <haskellbridge> sure how to use this for…
2023-12-10 19:01:50 +0100 <haskellbridge> 12<C​elestial>  my specific use-case though
2023-12-10 19:02:59 +0100 <geekosaur> MVar or TVar, Chan or TChan, etc.
2023-12-10 19:03:15 +0100 <geekosaur> the T variants use STM
2023-12-10 19:03:44 +0100 <haskellbridge> 12<C​elestial> another thing I know nothing about haha
2023-12-10 19:03:53 +0100 <haskellbridge> 12<C​elestial> Is that this sort-of-escapable IO-ish thing?
2023-12-10 19:04:02 +0100 <geekosaur> no
2023-12-10 19:04:15 +0100 <geekosaur> it's software transactional memory
2023-12-10 19:04:47 +0100 <geekosaur> it won't let you commit a transaction unless every indivisual action can complete successfully; otherwise it retries
2023-12-10 19:04:57 +0100 <geekosaur> the ultimate result is an IO action
2023-12-10 19:05:11 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470)
2023-12-10 19:05:31 +0100 <haskellbridge> 12<C​elestial> ah
2023-12-10 19:05:31 +0100 <geekosaur> https://www.microsoft.com/en-us/research/publication/composable-memory-transactions/
2023-12-10 19:05:54 +0100waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
2023-12-10 19:05:58 +0100 <haskellbridge> 12<C​elestial> I think I was thinking of the ST monad?
2023-12-10 19:06:10 +0100 <geekosaur> yes
2023-12-10 19:06:15 +0100 <haskellbridge> 12<C​elestial> thank you
2023-12-10 19:06:15 +0100 <geekosaur> ST is unrelated to STM
2023-12-10 19:06:36 +0100tzh(~tzh@c-71-193-181-0.hsd1.or.comcast.net)
2023-12-10 19:07:35 +0100justsomeguy(~justsomeg@user/justsomeguy) (Read error: Connection reset by peer)
2023-12-10 19:08:41 +0100[_](~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 245 seconds)
2023-12-10 19:08:48 +0100 <hexology> is there a way to define a general-purpose alias for an existing type? i wanted to create my own `Array2d i e` type as a shorthand for `Ix i => Array i (Array i e)`
2023-12-10 19:08:59 +0100 <hexology> that wouldn't work with newtype because it has more than one parameter, right?
2023-12-10 19:09:08 +0100 <geekosaur> `type`?
2023-12-10 19:09:40 +0100 <hexology> thank you!
2023-12-10 19:09:43 +0100 <hexology> https://en.wikibooks.org/wiki/Haskell/Type_declarations#type_for_making_type_synonyms
2023-12-10 19:09:58 +0100 <geekosaur> `newtype` is for when you want to either hide a type or override one or more typeclass instances
2023-12-10 19:10:29 +0100 <hexology> ah, i was wondering
2023-12-10 19:10:39 +0100pavonia(~user@user/siracusa) (Quit: Bye!)
2023-12-10 19:10:51 +0100 <hexology> and let's say i wanted to do that for something with more than one type parameter or constructor
2023-12-10 19:10:54 +0100 <hexology> how would i do that?
2023-12-10 19:11:01 +0100 <geekosaur> either way you're making a new distinct type from an existing one
2023-12-10 19:11:47 +0100 <hexology> oh, i can do that with `type` as well? so i can define my own typeclass instance for my `Array2d i e` and that would behave differently from `Array i (Array i e)`?
2023-12-10 19:12:16 +0100 <haskellbridge> 12<C​elestial> you can put (almost) anything that is a valid type as `type Foo = <type>` and then you can use it as if it was that exact type
2023-12-10 19:12:32 +0100 <haskellbridge> 12<C​elestial> you can't have instances with type
2023-12-10 19:12:43 +0100 <hexology> so what if i want to change how e.g. Foldable works on Array2d, what would i do then?
2023-12-10 19:12:46 +0100 <haskellbridge> 12<C​elestial> `type` creates a synonym / alias
2023-12-10 19:12:59 +0100 <geekosaur> all this said I'm not sure why you aren't using `type Array2d i e = Ix i => Array (i,i) e`
2023-12-10 19:13:04 +0100 <haskellbridge> 12<C​elestial> you'd need to wrap it in a `newtype`
2023-12-10 19:13:12 +0100 <geekosaur> Arays can be multidimensional
2023-12-10 19:13:25 +0100 <hexology> geekosaur: because i didn't realize i could do that!
2023-12-10 19:13:52 +0100 <hexology> i see, it's right here in the docs: (Ix a, Ix b) => Ix (a, b)
2023-12-10 19:13:57 +0100 <hexology> that's handy
2023-12-10 19:14:53 +0100 <haskellbridge> 12<C​elestial> you can even index by `Void`
2023-12-10 19:14:55 +0100 <hexology> but to answer the question above, if i want to customize the behavior of a `type` that differs from the underlying type, i'd need to create a newtype for it?
2023-12-10 19:14:57 +0100 <haskellbridge> 12<C​elestial> for that nice 0 dimensional array
2023-12-10 19:15:02 +0100 <geekosaur> yes
2023-12-10 19:15:18 +0100 <hexology> thanks a lot
2023-12-10 19:15:25 +0100 <geekosaur> `type` just creates aliases, changing behavior requires `newtype` or `data`
2023-12-10 19:15:46 +0100cimento(CO2@gateway/vpn/protonvpn/cimento) (Quit: WeeChat 4.1.2)
2023-12-10 19:15:49 +0100 <hexology> how does constructing an array with tuple indexes work?
2023-12-10 19:16:13 +0100cimento(CO2@gateway/vpn/protonvpn/cimento)
2023-12-10 19:16:47 +0100 <hexology> i've been using listArray, should i use something like `fill` instead?
2023-12-10 19:16:47 +0100 <geekosaur> the Ix instance lays them out in order (x0,y0),(x0,y1),…,(x1,y0),…
2023-12-10 19:17:17 +0100 <hexology> oh hang on i see. yeah i can pass the raw association data to `array` itself
2023-12-10 19:17:27 +0100 <hexology> ahh okay that helps too
2023-12-10 19:18:01 +0100 <hexology> so let's say i wanted a "column-major" array instead, i'd have to make a newtype for (i,j) and implement its Ix instance accordingly?
2023-12-10 19:18:20 +0100 <geekosaur> yes
2023-12-10 19:18:38 +0100 <hexology> where are you seeing that ordering for the Ix instance?
2023-12-10 19:19:10 +0100 <hexology> that is, how it corresponds to the underlying flat array order
2023-12-10 19:19:19 +0100 <hexology> still learning how to navigate these docs
2023-12-10 19:20:25 +0100 <hexology> or am i thinking about this the wrong way? where the underlying storage order is opaque/irrelevant
2023-12-10 19:20:42 +0100 <geekosaur> the top of https://downloads.haskell.org/ghc/9.2.5/docs/html/libraries/base-4.16.4.0/Data-Ix.html
2023-12-10 19:20:52 +0100 <geekosaur> "`Ix` uses row-major order:
2023-12-10 19:21:33 +0100 <hexology> right, but i guess i don't see how that's encoded in the definition or type signature
2023-12-10 19:22:02 +0100 <hexology> maybe that's in the implementation of `index`, `range`, etcD?
2023-12-10 19:22:13 +0100 <geekosaur> yes
2023-12-10 19:22:34 +0100wootehfoot(~wootehfoo@user/wootehfoot) (Quit: Leaving)
2023-12-10 19:22:52 +0100 <hexology> got it, i see now
2023-12-10 19:22:52 +0100 <hexology> thanks agin
2023-12-10 19:29:55 +0100DerDummNemetzkii(~John_Ivan@user/john-ivan/x-1515935) (Remote host closed the connection)
2023-12-10 19:30:16 +0100DerDummNemetzkii(~John_Ivan@user/john-ivan/x-1515935)
2023-12-10 19:31:10 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-10 19:32:52 +0100duncan(~duncan@user/duncan) (Quit: ZNC 1.8.2 - https://znc.in)
2023-12-10 19:33:11 +0100laxmik(~laxmik@2a01:c23:9597:b700:707f:bbe3:5986:73cb)
2023-12-10 19:33:47 +0100laxmik(~laxmik@2a01:c23:9597:b700:707f:bbe3:5986:73cb) (Client Quit)
2023-12-10 19:34:04 +0100duncan(~duncan@user/duncan)
2023-12-10 19:34:43 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) (Quit: Reconnecting)
2023-12-10 19:34:56 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 19:36:04 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net) ()
2023-12-10 19:36:18 +0100tri(~tri@ool-18bc2e74.dyn.optonline.net)
2023-12-10 19:36:18 +0100 <haskellbridge> 12<C​elestial> I'm now stuck with a "thread blocked indefinitely in an MVar operation" lol
2023-12-10 19:40:05 +0100 <hexology> `foreach = flip map` this is saving my life right now... making really easy to translate the imperative algorithms in my head for a first draft, then i can refactor once it's all written out
2023-12-10 19:40:10 +0100duncan(~duncan@user/duncan) (Quit: ZNC 1.8.2 - https://znc.in)
2023-12-10 19:42:10 +0100 <Hecate> 👍
2023-12-10 19:43:13 +0100 <yushyin> :t for
2023-12-10 19:43:14 +0100 <lambdabot> (Traversable t, Applicative f) => t a -> (a -> f b) -> f (t b)
2023-12-10 19:43:17 +0100 <yushyin> :t forM
2023-12-10 19:43:18 +0100 <lambdabot> (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b)
2023-12-10 19:44:04 +0100 <hexology> is there an Identity applicative?
2023-12-10 19:44:28 +0100 <Rembane> The Identity monad should have an applicative instance.
2023-12-10 19:44:37 +0100 <hexology> thanks
2023-12-10 19:44:51 +0100 <hexology> is there any particular reason that's better than `flip map`?
2023-12-10 19:44:58 +0100 <hexology> (but good to know about for sure)
2023-12-10 19:46:00 +0100 <Rembane> You get all the fun from Functor, Applicative and Monad. :D
2023-12-10 19:47:17 +0100 <haskellbridge> 12<C​elestial> not really useful in this case, but you'll also get used to the order that `map` is the mapping function first :P
2023-12-10 19:47:48 +0100 <haskellbridge> 12<C​elestial> it also makes sense in the higher order context because you can write somehing like `double = map (*2)`
2023-12-10 19:48:08 +0100 <haskellbridge> 12<C​elestial> you can also use `<$>` infix if you like!
2023-12-10 19:48:13 +0100 <hexology> yeah to be clear, i'm used to it and i understand why it's like that. but when i'm writing out a nest of 3 map's with lambdas, putting the thing i'm iterating over before the (\ x ->) makes it easier to read
2023-12-10 19:48:23 +0100duncan(~duncan@user/duncan)
2023-12-10 19:48:28 +0100 <haskellbridge> 12<C​elestial> `length <$> ["Hello", "World"]`
2023-12-10 19:48:53 +0100 <hexology> hah true. but again that has the same issue, it doesn't look and feel like the for loop that's in my head
2023-12-10 19:49:05 +0100 <haskellbridge> 12<C​elestial> this sounds like you want to write some "smaller" functions and compose them upstream ;)
2023-12-10 19:49:26 +0100 <hexology> indeed. but i tend to think "top-down" so i don't know what those smaller functions will look like until the algorithm is all written out
2023-12-10 19:50:05 +0100 <hexology> i believe the ancient masters used tools called "pen & paper" for this, but i'm unfamiliar with such mysterious arts
2023-12-10 19:50:52 +0100 <hexology> (my penmanship has degraded badly over the years and i need to get back in the habit of writing stuff down)
2023-12-10 19:51:15 +0100 <hexology> actually maybe this is good motivation. use a notepad instead of `flip map`
2023-12-10 19:51:38 +0100 <haskellbridge> 12<C​elestial> I do that too, but I usually just build functions up as I need them - basically I write `f = foo . bar . baz` and then let HLS generate each of the signatures
2023-12-10 19:51:52 +0100 <haskellbridge> 12<C​elestial> then I implement those with "unknown" functions as needed and implement those
2023-12-10 19:51:56 +0100 <hexology> HLS can generate signatures? is that a code action?
2023-12-10 19:52:48 +0100 <haskellbridge> 12<C​elestial> https://matrix-client.matrix.org//26caf53b/image.png
2023-12-10 19:52:57 +0100 <haskellbridge> 12<C​elestial> oh wait you can't see that on the irc side
2023-12-10 19:52:58 +0100 <haskellbridge> 12<C​elestial> yes
2023-12-10 19:53:11 +0100 <hexology> i can hop on matrix too
2023-12-10 19:53:26 +0100duncan(~duncan@user/duncan) (Quit: ZNC 1.8.2 - https://znc.in)
2023-12-10 19:53:31 +0100 <haskellbridge> 12<C​elestial> or rather it defines the function with a hole implementation and a signature
2023-12-10 19:53:43 +0100 <haskellbridge> 12<C​elestial> hexology: not worth it for that image :)
2023-12-10 19:53:58 +0100 <hexology> it's maybe easier anyway for code formatting etc. plus i can tag you there
2023-12-10 19:54:23 +0100 <hexology> what room is this bridged to? https://matrix.to/#/#haskell:matrix.org looks like a completely different conversation happening
2023-12-10 19:54:36 +0100 <hexology> oh i see there's a space
2023-12-10 19:54:40 +0100duncan(~duncan@user/duncan)
2023-12-10 19:54:40 +0100 <hexology> and an irc-bridged room
2023-12-10 19:54:46 +0100 <hexology> kind of you to idle in here for us lost souls on irc
2023-12-10 19:57:22 +0100euleritian(~euleritia@77.22.252.56) (Ping timeout: 276 seconds)
2023-12-10 19:57:34 +0100euleritian(~euleritia@dynamic-046-114-200-254.46.114.pool.telefonica.de)
2023-12-10 19:57:53 +0100 <hexology> maybe they can add a link to the main haskell-space room in the topic here? it's not that easy to find unless you know what you're doing with matrix
2023-12-10 19:58:54 +0100vgtw(~vgtw@user/vgtw)
2023-12-10 19:59:13 +0100 <haskellbridge> 12<C​elestial> I think this room specifically is targetted towards IRC
2023-12-10 20:00:13 +0100euleritian(~euleritia@dynamic-046-114-200-254.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
2023-12-10 20:00:31 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-10 20:01:56 +0100 <Rembane> hexology: There's a list of community resources here, e.g. this channel and Matrix: https://www.haskell.org/community/
2023-12-10 20:02:22 +0100 <Rembane> So that's something.
2023-12-10 20:05:18 +0100 <geekosaur> IRC came first by several decades by the way, and there's a bunch of folks in here who don't use Matrix
2023-12-10 20:05:52 +0100dhil(~dhil@2001:8e0:2014:3100:bf6:da90:7ddf:392e) (Ping timeout: 246 seconds)
2023-12-10 20:12:58 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-10 20:13:42 +0100duncan(~duncan@user/duncan) (Quit: ZNC 1.8.2 - https://znc.in)
2023-12-10 20:14:27 +0100 <hexology> geekosaur: indeed, but in this case it would have been useful to know which matrix room this was bridged to
2023-12-10 20:14:34 +0100 <hexology> Rembane: those are helpful
2023-12-10 20:14:49 +0100 <Rembane> hexology: Sweet! :)
2023-12-10 20:15:31 +0100 <geekosaur> if you /whois the bridge bot, it includes a link showing all the bridged channels and their matrix rooms
2023-12-10 20:15:50 +0100 <geekosaur> there's a limit to how big topics can get
2023-12-10 20:16:25 +0100 <hexology> that's the "matterbridge" link?
2023-12-10 20:16:32 +0100duncan(~duncan@user/duncan)
2023-12-10 20:16:41 +0100 <hexology> looks like it. thanks
2023-12-10 20:17:16 +0100testing500(~user@host-92-11-94-158.as13285.net)
2023-12-10 20:17:41 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 240 seconds)
2023-12-10 20:17:55 +0100duncan(~duncan@user/duncan) (Client Quit)
2023-12-10 20:19:53 +0100 <tomsmeding> lol, that goes to a paste
2023-12-10 20:19:57 +0100 <tomsmeding> I guess that works :)
2023-12-10 20:20:23 +0100 <tomsmeding> geekosaur: feel free to link to https://paste.tomsmeding.com/syOTuo6O/raw if you want
2023-12-10 20:20:48 +0100 <hexology> it looks like that's in there, but with a shortened url
2023-12-10 20:21:12 +0100 <tomsmeding> yes I was just surprised that it just went to a paste instead of a dedicated page :)
2023-12-10 20:21:20 +0100 <tomsmeding> fist the hacker spirit though
2023-12-10 20:26:15 +0100 <EvanR> still not exactly sure what [the] matrix is
2023-12-10 20:26:25 +0100 <EvanR> should I follow the white rabbit?
2023-12-10 20:27:13 +0100duncan(~duncan@user/duncan)
2023-12-10 20:27:21 +0100duncan(~duncan@user/duncan) (Remote host closed the connection)
2023-12-10 20:27:31 +0100 <EvanR> 💊
2023-12-10 20:32:25 +0100testing500(~user@host-92-11-94-158.as13285.net) (Remote host closed the connection)
2023-12-10 20:43:05 +0100pagnol(~user@2a02:a210:a3c:b00:87aa:b531:d3b2:73fa)
2023-12-10 20:46:08 +0100jargon(~jargon@32.sub-174-238-226.myvzw.com)
2023-12-10 20:48:33 +0100 <monochrom> Someone should create a competitor to Matrix and call it Wave. >:)
2023-12-10 20:50:14 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com)
2023-12-10 20:58:31 +0100trev(~trev@user/trev) (Quit: trev)
2023-12-10 21:10:04 +0100Tlsx(rscastilho@189.61.140.215) (Remote host closed the connection)
2023-12-10 21:10:10 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 276 seconds)
2023-12-10 21:11:29 +0100glider(~glider@user/glider) (Quit: ZNC - https://znc.in)
2023-12-10 21:17:21 +0100 <cheater> let's say i have data Foo a b = Error | Bar a b | Quux a b. How can I write a case so that both a and b get captured whether it's Bar or Quux?
2023-12-10 21:18:10 +0100 <cheater> i'm thinking of something like case myFoo of { Error -> ...; Bar x y, Quux x y -> runFunc x y }
2023-12-10 21:19:53 +0100 <dminuoso_> cheater: Write them as separate branches.
2023-12-10 21:20:28 +0100 <cheater> don't really want separate branches (instead of runFunc x y i have a pretty large block)
2023-12-10 21:20:29 +0100 <tromp> Haskell doesn't support that. although there is this proposal https://wiki.haskell.org/MultiCase
2023-12-10 21:20:32 +0100 <dminuoso_> There's some ongoing GHC proposals to accomplish part of this, but I dont follow them because they lack the one thing to make them useful.
2023-12-10 21:20:41 +0100 <cheater> i guess i could extract that block and put it in a function, or something.
2023-12-10 21:20:56 +0100 <cheater> "the one thing"?
2023-12-10 21:22:37 +0100 <dminuoso_> https://github.com/ghc-proposals/ghc-proposals/pull/585
2023-12-10 21:22:43 +0100 <dminuoso_> https://github.com/ghc-proposals/ghc-proposals/pull/609
2023-12-10 21:24:14 +0100 <cheater> what is "the one thing"?
2023-12-10 21:24:22 +0100 <dminuoso_> Oh. Binding variables.
2023-12-10 21:24:55 +0100td_(~td@i53870907.versanet.de) (Ping timeout: 256 seconds)
2023-12-10 21:24:59 +0100 <hexology> if i write `let inputLines = lines inputText in n = length inputLines` is GHC "smart enough" to compile that to a single loop over the data, or would i have to reimplement `lines` myself to get that kind of performance?
2023-12-10 21:26:01 +0100 <hexology> or similarly if i write `zip [0..] (lines inputText)`
2023-12-10 21:26:59 +0100 <Rembane> hexology: IIRC It should be evaluated only once.
2023-12-10 21:27:04 +0100 <dminuoso_> cheater: It roughly degrades the proposal to case-of on numbers, literals or nullary constructors.
2023-12-10 21:27:19 +0100 <dminuoso_> For anything else, you (probably) still have to write out each branch by hand.
2023-12-10 21:27:22 +0100 <cheater> ugh
2023-12-10 21:27:38 +0100alp_(~alp@2001:861:e3d6:8f80:7092:9744:337:b98c)
2023-12-10 21:27:50 +0100 <hexology> Rembane: thanks. do you know of any resources for understanding performance in cases like this? not sure what the tooling landscape looks like for things like profiling
2023-12-10 21:28:14 +0100 <EvanR> monochrom, took me a minute but I got the reference
2023-12-10 21:29:59 +0100 <Rembane> hexology: The trick is generally to see if the thunks get evaluated. I would just ignore them until they bite you.
2023-12-10 21:30:19 +0100Unicorn_Princess(~Unicorn_P@user/Unicorn-Princess/x-3540542)
2023-12-10 21:30:30 +0100 <hexology> this is more of out interest/curiosity than any particular need
2023-12-10 21:34:00 +0100 <EvanR> let inputLines = lines inputText; n = length inputLines in ...
2023-12-10 21:34:06 +0100 <EvanR> perhaps
2023-12-10 21:34:27 +0100anderson(~anderson@user/anderson)
2023-12-10 21:35:15 +0100 <hexology> i'm not sure about all the semicolon rules yet, so i used 2 `let`s instead
2023-12-10 21:35:17 +0100 <EvanR> if ... only uses n, then you only loop over inputText at most once
2023-12-10 21:35:26 +0100 <EvanR> your only had 1 let
2023-12-10 21:35:32 +0100 <hexology> oh
2023-12-10 21:35:37 +0100 <hexology> i meant to have 2
2023-12-10 21:35:37 +0100 <APic> lol
2023-12-10 21:35:47 +0100 <hexology> s/in n/in let in/
2023-12-10 21:35:50 +0100 <hexology> letn
2023-12-10 21:35:55 +0100 <EvanR> ok makes more sense now
2023-12-10 21:35:56 +0100 <hexology> i give up, you know what i mean :)
2023-12-10 21:36:57 +0100 <hexology> maybe this is another XY problem. i'm doing AoC day 3 (trying to catch up) and i wanted to read the input into a 2D array of Chars
2023-12-10 21:36:58 +0100 <EvanR> but if inputText appears in several places in ..., you might not only loop over it multiple times but it will be fully materialized in heap memory
2023-12-10 21:37:17 +0100__monty__(~toonn@user/toonn)
2023-12-10 21:37:55 +0100 <hexology> right, that's what i wasn't sure of
2023-12-10 21:39:09 +0100 <EvanR> so if you wanted to accomplish multiple things during a traversal of inputText, I think you would do it with 1 fold or write your own recursion
2023-12-10 21:39:41 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com)
2023-12-10 21:39:58 +0100 <EvanR> or do like me, and reload the file each time xD
2023-12-10 21:40:12 +0100 <hexology> got it. in this case i was hoping to go from `inputText :: String` to `inputData :: Array (Int, Int) Char`, but maybe it's impossible to do that in a single pass without an intermediate list of lines, because you need the length of each line and the number of lines
2023-12-10 21:40:31 +0100 <hexology> so i was hoping to at least get the number of lines and the intermediate list of lines in a single shot
2023-12-10 21:41:11 +0100 <hexology> of course none of this matters for aoc day3 specifically, but again i'm taking this as a learning and exploration opportunity
2023-12-10 21:41:34 +0100 <EvanR> you can't get the number of lines until after all the lines have been identified
2023-12-10 21:41:49 +0100 <EvanR> it basically last
2023-12-10 21:42:35 +0100 <EvanR> if you want to use Array dunno if there's a way around it
2023-12-10 21:42:52 +0100 <hexology> right, that much i know. but you can also get the lines and the number thereof in a single pass, if you reimplement `lines` yourself
2023-12-10 21:43:01 +0100 <hexology> at least i'm pretty sure that should be possible
2023-12-10 21:43:12 +0100 <probie> What does "a single pass" mean?
2023-12-10 21:43:17 +0100 <EvanR> when you get lines you can start using the lines before you're finished reading the input
2023-12-10 21:43:28 +0100 <EvanR> unlike the integer number of total lines, which must wait until the end
2023-12-10 21:44:00 +0100 <EvanR> implementing lines yourself won't help there
2023-12-10 21:44:18 +0100 <hexology> probie: i mean `for (line in lines) { ... }` -- not doing that more times than necessary
2023-12-10 21:44:36 +0100 <probie> Is `map ((*2) . (+1))` a single pass, or two passes?
2023-12-10 21:44:44 +0100 <dminuoso_> Yes.
2023-12-10 21:44:53 +0100 <hexology> probie: that's up to GHC but i would hope that it's one
2023-12-10 21:45:08 +0100 <c_wraith> I don't know how you could implement map that would make it two passes
2023-12-10 21:45:22 +0100 <probie> If I go `head . map ((*2) . (+1))` how many times have I passed over the list?
2023-12-10 21:45:33 +0100 <dminuoso_> c_wraith: Still, it depends a bit on how you interpret "pass"
2023-12-10 21:45:34 +0100 <c_wraith> the important question is whether `map (*2) . map (+1)` is one pass or two
2023-12-10 21:45:44 +0100 <hexology> c_wraith: precisely, that's the essence of what i'm asking here
2023-12-10 21:45:45 +0100 <dminuoso_> So my answer remains: yes.
2023-12-10 21:45:46 +0100 <EvanR> or zero
2023-12-10 21:45:56 +0100 <EvanR> any haskell code could be doing zero passes
2023-12-10 21:46:00 +0100 <EvanR> depending
2023-12-10 21:46:25 +0100 <c_wraith> probie: by my counting zero passes when you have head. It only ever evaluates the first (:) constructor and its first argument
2023-12-10 21:47:05 +0100 <hexology> EvanR: i was envisioning exactly two passes here: 1) to split the string into lines and accumulate a length counter, then 2) to pull all the strings into the array
2023-12-10 21:47:34 +0100 <hexology> was i was wondering (again, mostly academic) is whether calling `length` on `lines inputText` is equivalent to (1), or if that ends up being compiled to a 3rd loop
2023-12-10 21:48:08 +0100 <hexology> or if internally GHC internally tracks the sizes of known-finite lists and it doesn't matter
2023-12-10 21:48:12 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-10 21:48:15 +0100 <hexology> (tracks at runtime*)
2023-12-10 21:48:26 +0100 <dminuoso_> probie: A more interesting question is whether `map (*2) . map (+1)` will map twice or not.
2023-12-10 21:48:31 +0100 <EvanR> it'll probably loop over the list of lines to get the length
2023-12-10 21:49:15 +0100 <dminuoso_> Which in principle would map twice, but GHC has a bunch of RULES that will - if they fire - do short cut fusion here.
2023-12-10 21:49:45 +0100 <EvanR> and writing a function to return a length and the list of lines in a tuple by itself won't help you with making the array, because the array builder will evaluate the length first
2023-12-10 21:49:46 +0100 <dminuoso_> probie: As a point of interest: for guaranteed short cut fusion in the general fmap case (i.e. repeated fmap applications) use Yoneda.
2023-12-10 21:49:53 +0100 <dminuoso_> Or even in the list case.
2023-12-10 21:50:01 +0100 <dminuoso_> If you rely on this happening, use Yoneda.
2023-12-10 21:50:09 +0100 <hexology> EvanR: right. to be clear, i was talking about getting the list of lines and the length in one pass, not building the array
2023-12-10 21:50:39 +0100 <hexology> (unless haskell has resizeable arrays where you can pre-allocate a bunch of lines, like what cpython does internally for lists)
2023-12-10 21:50:41 +0100 <EvanR> hexology, yes but... getting a list of lines is lazy and an Int isn't
2023-12-10 21:51:09 +0100 <EvanR> when you make a Vector from a list, it does resize as it discovers the list is bigger and bigger, iirc
2023-12-10 21:51:30 +0100 <EvanR> in which case you don't need the length ahead of time. But there is another builder function which allows you to inform the known length if you have it
2023-12-10 21:51:43 +0100 <hexology> i haven't tried using Vector yet, only Array
2023-12-10 21:52:00 +0100 <hexology> good to know something like that exists
2023-12-10 21:52:12 +0100 <hexology> but i think your point about lines of being lazy is clarifying
2023-12-10 21:53:26 +0100 <hexology> `lines inputText` doesn't immediately create a list, it builds up some kind of graph of thunks, right?
2023-12-10 21:53:54 +0100 <EvanR> at best it doesn't do anything, if you don't use it for anything. Second best is it creates one thunk ready to start producing lines
2023-12-10 21:54:26 +0100 <EvanR> near the worst cases, yes there will be a bunch of thunks for some reason
2023-12-10 21:54:32 +0100 <EvanR> that's usually a mistake
2023-12-10 21:54:50 +0100 <probie> > take 0 $ lines (error "Oh no")
2023-12-10 21:54:51 +0100 <lambdabot> []
2023-12-10 21:57:28 +0100 <hexology> got it
2023-12-10 21:58:27 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5)
2023-12-10 21:58:56 +0100 <EvanR> and since you're using String = [Char], each line is itself lazy (ideally)
2023-12-10 21:59:00 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655)
2023-12-10 21:59:23 +0100 <hexology> it's from `inputText <- getContents` in this case
2023-12-10 22:00:11 +0100 <hexology> so i would hope that it's doing something like buffering stdin, iterating over bytes until `\n` is encountered, adding those bytes to the list it's building up, and incrementing the length counter i requested with `length`
2023-12-10 22:00:39 +0100 <EvanR> that sounds like some other language xD
2023-12-10 22:01:05 +0100 <EvanR> when you based the computation on getContents, it only reads a Char from stdin if it's needed
2023-12-10 22:01:24 +0100 <EvanR> so if you process the lines char by char, and line by line, in order, then it only needs 1 Char lookahead
2023-12-10 22:01:54 +0100alexherbo2(~alexherbo@2a02-8440-3140-cd78-808d-cfaa-bb42-954e.rev.sfr.net)
2023-12-10 22:03:10 +0100 <EvanR> but using the length of a line or total number of lines will potentially mess that up
2023-12-10 22:03:17 +0100 <hexology> https://bpa.st/EPDA this is basically what i'm doing
2023-12-10 22:03:39 +0100 <hexology> err, not show, print
2023-12-10 22:03:54 +0100 <hexology> but that's the general idea
2023-12-10 22:04:04 +0100 <EvanR> right
2023-12-10 22:04:05 +0100 <monochrom> With "inputText <- getContents" if you add "let foo = lines inputText" then foo is the list of lines.
2023-12-10 22:05:18 +0100 <EvanR> if somethingUseful accesses the array at all, then all the lines will be processed first to get the lengths
2023-12-10 22:06:36 +0100 <EvanR> so that's where your "buffering" would come from, it's not a given
2023-12-10 22:07:04 +0100 <hexology> makes sense
2023-12-10 22:07:14 +0100 <hexology> wait, GHC doesn't do any of its own i/o buffering?
2023-12-10 22:07:22 +0100 <hexology> i know usually the OS does, but still
2023-12-10 22:07:32 +0100 <EvanR> yeah but that has no bearing here
2023-12-10 22:07:51 +0100 <hexology> sure. just following the thread, so to speak
2023-12-10 22:07:56 +0100alexherbo2(~alexherbo@2a02-8440-3140-cd78-808d-cfaa-bb42-954e.rev.sfr.net) (Ping timeout: 250 seconds)
2023-12-10 22:07:58 +0100 <EvanR> whether there's buffering in the backend you can still work with 1 char at a time
2023-12-10 22:08:02 +0100 <hexology> right
2023-12-10 22:08:28 +0100 <EvanR> whether you build up a bunch of chars in the process depends on how you do it
2023-12-10 22:08:36 +0100 <hexology> presumably in a real application with nontrivial performance requirements, i'd be able to use the GHC profiling tools to understand what's going on?
2023-12-10 22:08:40 +0100 <hexology> https://downloads.haskell.org/ghc/latest/docs/users_guide/profiling.html#
2023-12-10 22:08:49 +0100 <monochrom> Here is the simplest way to see the phenomenon. "sum [1..n]" takes O(1) space. "length [1..n]" also takes O(1) space. But "let xs = [1..n] in sum xs / length xs" takes linear space. You have to understand lazy evaluation to see why.
2023-12-10 22:09:06 +0100duncan(~duncan@user/duncan)
2023-12-10 22:09:16 +0100duncan(~duncan@user/duncan) (Client Quit)
2023-12-10 22:09:19 +0100 <probie> hexology: In a real application with nontrivial performance requirements, you would neither be using `getContents` nor the `String` type :p
2023-12-10 22:09:29 +0100 <EvanR> profiling is an easy way to identify big use of heap space when you didn't think you needed it
2023-12-10 22:09:45 +0100 <hexology> what would you use for text data intead? https://hackage.haskell.org/package/text-1.2.4.1/docs/Data-Text.html this?
2023-12-10 22:09:47 +0100 <EvanR> and yeah list of Char is bad for performance
2023-12-10 22:10:16 +0100 <monochrom> And I refuse the current ambiguous wording "buffering". You are conflating I/O buffers with keeping the whole string in memory.
2023-12-10 22:10:22 +0100 <EvanR> advent of code only uses ASCII text input so ByteString would also work
2023-12-10 22:11:27 +0100 <hexology> monochrom: you're right, i should have been clearer. when i said "buffer" i meant an I/O buffer
2023-12-10 22:12:17 +0100 <hexology> and that example above does help clarify
2023-12-10 22:12:21 +0100 <EvanR> if you use ByteString then you will be working with an array of bytes, mapping more closely to what you were "hoping" for
2023-12-10 22:12:27 +0100 <monochrom> Of course GHC does I/O buffers by default. But all languages do O(1)-space I/O buffers. 4KB or 64KB or something.
2023-12-10 22:13:15 +0100 <EvanR> list nodes and Char itself take up quite a bit more space and time than array of bytes
2023-12-10 22:13:50 +0100 <EvanR> because lisp machines didn't win!
2023-12-10 22:14:17 +0100 <hexology> i got interested in languages' I/O buffering when i wrote a cli tool that looped over lines of input in python, and it smoked every other non-compiled language in performance when i benchmarked an idiomatic but non-optimized implementation, including luajit, sbcl, chez scheme, and nodejs. i was pretty surprised at this, and the best i could gather after some digging around is that cpython uses a much bigger stdin buffer than the others
2023-12-10 22:14:25 +0100 <monochrom> But even in C I wouldn't use this algorithm "read the whole file in memory" unless the file is known to be small.
2023-12-10 22:15:02 +0100_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Remote host closed the connection)
2023-12-10 22:15:07 +0100 <hexology> also a good point monochrom
2023-12-10 22:15:10 +0100 <EvanR> where "small" has been steadily increasing in size over time xD
2023-12-10 22:15:27 +0100 <monochrom> If I need to create an array whose size depends on the number of lines, I would create a growable array instead.
2023-12-10 22:15:29 +0100 <EvanR> it's only a 1 meg file? load it all into memory for some reason xD
2023-12-10 22:15:30 +0100 <dminuoso_> I was always under the assumption that "buffering" isnt as much ambiguous, as it is just plainly misused.
2023-12-10 22:15:57 +0100 <dminuoso_> Buffers are a tool for matching two I/O that may, potentially, operate at different speeds.
2023-12-10 22:16:13 +0100 <monochrom> Either that, or pre-scan the file (but don't store) for number of lines, then rewind and read for real.
2023-12-10 22:16:15 +0100 <dminuoso_> It's not a means for "streaming", its rather a solution to avoid data loss.
2023-12-10 22:19:29 +0100 <monochrom> Unpopular opinion but I first ask the question "is your algorithm even O(1)-space in theory?" instead of the popular knee-jerk "Text takes 1/4 of the space taken up by [Char]".
2023-12-10 22:19:35 +0100duncan(~duncan@user/duncan)
2023-12-10 22:19:56 +0100foul_owl(~kerry@174-21-66-189.tukw.qwest.net) (Ping timeout: 245 seconds)
2023-12-10 22:20:29 +0100 <hexology> monochrom: i would hope that's not unpopular!
2023-12-10 22:20:36 +0100 <monochrom> The assumption of the latter is that at the professional level you already have a O(1)-space algorithm but its constant multiplier is terrible so now you look for 4x efficiency boosts.
2023-12-10 22:20:50 +0100 <EvanR> yeah the main point of this discussion would apply to String, Text, and ByteString
2023-12-10 22:21:09 +0100 <EvanR> laziness in the face of needing the know the lengths
2023-12-10 22:21:15 +0100 <monochrom> But the assumption is blatantly broken. 99.9% of askers are absolute beginners, their algorithms begin with expoenential time already, a 4x boost doesn't solve anything.
2023-12-10 22:21:24 +0100 <monochrom> And in fact becomes completely distracting.
2023-12-10 22:25:47 +0100duncan(~duncan@user/duncan) (Quit: ZNC 1.8.2 - https://znc.in)
2023-12-10 22:26:57 +0100duncan(~duncan@user/duncan)
2023-12-10 22:27:41 +0100 <hc> Exponential time? Not just quadratic?
2023-12-10 22:28:18 +0100 <hc> I'd expect many naive string handling algorithms to be polynomial, but not exponential
2023-12-10 22:29:48 +0100target_i(~target_i@217.175.14.39) (Quit: leaving)
2023-12-10 22:31:36 +0100emmanuelux_(~emmanuelu@user/emmanuelux) (Read error: Connection reset by peer)
2023-12-10 22:32:31 +0100 <dminuoso_> monochrom: On the basis that the observable universe is finite in size and energy, there exists a finite amount of memory I could theoretically ever use. So all practial algorithms are O(1)-space with.. well.. a huge constant factor.
2023-12-10 22:32:40 +0100emmanuelux_(~emmanuelu@user/emmanuelux)
2023-12-10 22:33:14 +0100foul_owl(~kerry@157.97.134.168)
2023-12-10 22:34:14 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-10 22:34:28 +0100emmanuelux_(~emmanuelu@user/emmanuelux) (Max SendQ exceeded)
2023-12-10 22:35:30 +0100emmanuelux_(~emmanuelu@user/emmanuelux)
2023-12-10 22:36:02 +0100not_reserved(~not_reser@45.88.222.248)
2023-12-10 22:38:05 +0100 <newsham> you could claim that all your programs run on a finite state machine, but it wouldnt be very useful or insightful.
2023-12-10 22:40:12 +0100 <haskellbridge> 12<C​elestial> Is there an `MVar`-ish type that always has a value, or should I just write my own newtype wrapper around `MVar` that doesn't neither has the empty smart constructor nor the take operation but only a swap?
2023-12-10 22:40:13 +0100 <haskellbridge> 12<C​elestial> Is that "safe", as swap still needs to take and put again, leaving a short window where it's empty?
2023-12-10 22:40:31 +0100 <haskellbridge> 12<C​elestial> I suppose the later isn't a concern if you only allow the blocking operations that wait
2023-12-10 22:40:56 +0100 <haskellbridge> 12<C​elestial> s/doesn't neither/neither
2023-12-10 22:41:04 +0100 <monochrom> I would consider STM and its TVar instead.
2023-12-10 22:41:43 +0100 <monochrom> But if you stick to readMVar and writeMVar you get the always-non-empty semantics.
2023-12-10 22:42:50 +0100 <haskellbridge> 12<C​elestial> hm I see I think I do want the TVar instead
2023-12-10 22:42:59 +0100 <haskellbridge> 12<C​elestial> I need to read up on the STM monad
2023-12-10 22:43:02 +0100 <EvanR> IORef xD
2023-12-10 22:43:10 +0100 <EvanR> atomicModifyIORef'
2023-12-10 22:43:35 +0100 <monochrom> Yeah I actually use that :)
2023-12-10 22:43:49 +0100 <EvanR> TVars are good when you actually want transactions
2023-12-10 22:43:58 +0100 <EvanR> more complicated than just changing the value
2023-12-10 22:44:11 +0100 <haskellbridge> 12<C​elestial> how does one interact with STM? For IO you have the entry point `main` but there doesn't seem to be the same with stm?
2023-12-10 22:44:18 +0100 <EvanR> atomically
2023-12-10 22:44:37 +0100 <monochrom> If it is not "two or more variables entangled by an invariant" then atomicModifyIORef' suffices.
2023-12-10 22:44:43 +0100alexherbo2(~alexherbo@2a02-8440-3140-cd78-e0d9-a0e2-1a64-1fd2.rev.sfr.net)
2023-12-10 22:45:25 +0100fendor(~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c) (Remote host closed the connection)
2023-12-10 22:46:52 +0100pavonia(~user@user/siracusa)
2023-12-10 22:47:34 +0100aruns(~aruns@user/aruns) (Ping timeout: 246 seconds)
2023-12-10 22:48:12 +0100duncan(~duncan@user/duncan) (Read error: Connection reset by peer)
2023-12-10 22:49:00 +0100duncan(~duncan@user/duncan)
2023-12-10 22:52:11 +0100anderson(~anderson@user/anderson) (Quit: bye)
2023-12-10 22:53:59 +0100anderson(~anderson@user/anderson)
2023-12-10 22:54:11 +0100duncan(~duncan@user/duncan) (Quit: ZNC 1.8.2 - https://znc.in)
2023-12-10 22:57:51 +0100takuan(~takuan@178-116-218-225.access.telenet.be) (Ping timeout: 256 seconds)
2023-12-10 22:59:42 +0100 <EvanR> *do you guys just put "quantum" in front of everything*
2023-12-10 22:59:48 +0100machinedgod(~machinedg@93-136-52-133.adsl.net.t-com.hr)
2023-12-10 23:00:19 +0100duncan(~duncan@user/duncan)
2023-12-10 23:04:35 +0100 <ski> Celestial : `Array () e' would be a zero-dimensional array (having a single element of type `e'). if `Array (Either i j) e' was allowed, it would amount to two arrays, side-by side. `Array Void e' corresponds to zero arrays (so no elements of type `e')
2023-12-10 23:04:39 +0100 <ski> hexology : sometimes i define `pam = flip map'
2023-12-10 23:04:43 +0100 <ski> cheater : "i'm thinking of something like case myFoo of { Error -> ...; Bar x y, Quux x y -> runFunc x y }" -- you're asking for disjunctive / "or"- patterns
2023-12-10 23:05:22 +0100 <jackdk> > :t Data.Functor.(<&>)
2023-12-10 23:05:23 +0100 <lambdabot> <hint>:1:1: error: parse error on input ‘:’
2023-12-10 23:05:32 +0100 <jackdk> % :t Data.Functor.(<&>)
2023-12-10 23:05:32 +0100 <yahb2> *** Parser [source]: ; !!! Parser [source]: finished in 0.11 milliseconds, allocated 0.035 megabytes ; ; <interactive>:1:1: error: ; Not in scope: data constructor ‘Data.Functor’ ; No modu...
2023-12-10 23:05:35 +0100 <ski> Celestial : and yea, `IORef', if you don't particularly care about transactions, you only care about swapping out single `IORef's at a time
2023-12-10 23:05:52 +0100 <ski> % :t (Data.Functor.<&>)
2023-12-10 23:05:52 +0100 <yahb2> *** Parser [source]: ; !!! Parser [source]: finished in 0.08 milliseconds, allocated 0.030 megabytes ; (Data.Functor.<&>) :: Functor f => f a -> (a -> b) -> f b
2023-12-10 23:05:57 +0100 <jackdk> anyway : (<&>) :: Functor f => f a -> (a -> b) -> f b
2023-12-10 23:06:07 +0100 <ski> % :q
2023-12-10 23:06:07 +0100 <yahb2> <bye>
2023-12-10 23:06:09 +0100 <ski> % :t (Data.Functor.<&>)
2023-12-10 23:06:09 +0100 <yahb2> (Data.Functor.<&>) :: Functor f => f a -> (a -> b) -> f b
2023-12-10 23:06:23 +0100 <haskellbridge> 12<C​elestial> ski: Thank you!
2023-12-10 23:06:35 +0100 <ski> Celestial : see what EvanR and monochrom said
2023-12-10 23:09:39 +0100 <haskellbridge> 12<C​elestial> Okay I think I understand
2023-12-10 23:09:50 +0100 <haskellbridge> 12<C​elestial> still new to concurrency with haskell
2023-12-10 23:09:58 +0100 <haskellbridge> 12<C​elestial> so thank you for the help everyone+
2023-12-10 23:12:44 +0100 <ski> Celestial : btw, `Array (Either i j) e' is not allowed, because `Ix' allows you to use subranges (intervals) of the index type. for `Int', such an interval `{i | lo =< i =< hi}' is expressed by the bounds `(lo,hi)'
2023-12-10 23:12:51 +0100 <ski> for `(Int,Int)', an interval `{(i0,i1) | (lo0,lo1) =< (i0,i1) =< (hi0,hi1)}', iow `{(i0,i1) | lo0 =< i0 =< hi0,lo1 =< i1 =< hi1}' (note this is not the usual lexcographic (total) ordering you get with `Ord (Int,Int)', rather `Ix (Int,Int)' is the product partial ordering. `range' enumerates the interval lexicographically, though)
2023-12-10 23:19:11 +0100 <EvanR> =< ?
2023-12-10 23:19:15 +0100 <EvanR> :t (=<)
2023-12-10 23:19:16 +0100 <lambdabot> error:
2023-12-10 23:19:16 +0100 <lambdabot> • Variable not in scope: =<
2023-12-10 23:19:16 +0100 <lambdabot> • Perhaps you meant one of these:
2023-12-10 23:19:21 +0100 <ski> such an interval is expressed by the bounds `((lo0,lo1),(hi0,hi1))' (this is a generalized kind of interval, as defined in order theory. in this case, it's a "rectangle")
2023-12-10 23:19:57 +0100 <ski> (for math, i prefer `<',`=<',`>=',`>' (as Prolog and Erlang does it), preferring `<=' as leftwards implication)
2023-12-10 23:20:20 +0100 <ski> @let data Word2 = W0 | W1 | W2 | W3 deriving (Read,Show,Eq,Ord,Enum,Bounded,Ix)
2023-12-10 23:20:21 +0100 <lambdabot> Defined.
2023-12-10 23:20:24 +0100 <ski> > [i | i <- [minBound .. maxBound],W1 <= i,i <= W2]
2023-12-10 23:20:26 +0100 <lambdabot> [W1,W2]
2023-12-10 23:20:31 +0100 <ski> > [i | i <- [minBound .. maxBound],inRange (W1,W2) i]
2023-12-10 23:20:32 +0100 <lambdabot> [W1,W2]
2023-12-10 23:20:37 +0100 <ski> > [i | i <- range (W1,W2)]
2023-12-10 23:20:41 +0100 <lambdabot> [W1,W2]
2023-12-10 23:20:46 +0100 <ski> > [(i,j) | [i,j] <- replicateM 2 [minBound .. maxBound],(W1,W1) <= (i,j),(i,j) <= (W2,W2)]
2023-12-10 23:20:47 +0100 <lambdabot> [(W1,W1),(W1,W2),(W1,W3),(W2,W0),(W2,W1),(W2,W2)]
2023-12-10 23:20:55 +0100 <ski> > [(i,j) | [i,j] <- replicateM 2 [minBound .. maxBound],inRange ((W1,W1),(W2,W2)) (i,j)]
2023-12-10 23:20:57 +0100 <lambdabot> [(W1,W1),(W1,W2),(W2,W1),(W2,W2)]
2023-12-10 23:21:01 +0100Sgeo(~Sgeo@user/sgeo)
2023-12-10 23:21:02 +0100 <ski> > [(i,j) | (i,j) <- range ((W1,W1),(W2,W2))]
2023-12-10 23:21:03 +0100 <lambdabot> [(W1,W1),(W1,W2),(W2,W1),(W2,W2)]
2023-12-10 23:21:50 +0100 <ski> notice how these last two express the "middle square" (an interval), bounded by `(W1,W1)' and `(W2,W2)', not containing any `W0's or `W3's
2023-12-10 23:23:05 +0100 <ski> while the one before those two, using the ordinary lexicographical order (`Ord (Integer,Integer)'), does "bleed over" into the remainder of the first row, and the start of the second row, before reaching the endpoint, so includes `W0's and `W3's
2023-12-10 23:23:56 +0100puke(~puke@user/puke) (Quit: puke)
2023-12-10 23:26:57 +0100 <ski> so .. for `Ix (Either i j)', we'd arguably need both a lower&upper bound for the `i'-indexed part of the array, and a lower&upper bound for the `j'-indexed part of the array (since `Array (Either i j) e' presumably then ought to correspond to `(Array i e,Array j e)', one array part indexed by `i', and another by `j'). so the bounds type would probably be `((i,j),(i,j))', then
2023-12-10 23:26:57 +0100 <cheater> ski: yes
2023-12-10 23:27:06 +0100 <cheater> ski: do they exist?
2023-12-10 23:27:21 +0100 <ski> but what the types give us is `(Either i j,Either i j)', either a lower bound for `i' or one for `j', and likewise for upper bound
2023-12-10 23:29:40 +0100 <ski> (one could argue that `Array (Either i i) e' ought to be equivalent to `Array (Bool,i) e', which would then use the partial ordering `Ix (Bool,i)' to express either an interval within the first `i'-indexed array, or either one within the second, or two "parallel" ones, with the same `i' bounds, within both. but for `Array (Either i j) e', `i' and `j' are not known to be related, so one can't expect such
2023-12-10 23:29:46 +0100 <ski> "synchronized" indexing for both parts there)
2023-12-10 23:29:50 +0100__monty__(~toonn@user/toonn) (Quit: leaving)
2023-12-10 23:30:08 +0100[_](~itchyjunk@user/itchyjunk/x-7353470)
2023-12-10 23:31:11 +0100Volt_(~Volt_@c-73-47-181-152.hsd1.ma.comcast.net)
2023-12-10 23:32:49 +0100puke(~puke@user/puke)
2023-12-10 23:33:16 +0100waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 245 seconds)
2023-12-10 23:33:41 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 245 seconds)
2023-12-10 23:39:23 +0100newsham(~newsham@2603-800c-2c01-6825-857b-69b9-29f4-97e6.res6.spectrum.com) (Quit: Client closed)
2023-12-10 23:40:24 +0100waleee(~waleee@176.10.144.38)
2023-12-10 23:43:13 +0100 <ski> cheater : they exist in OCaml <https://v2.ocaml.org/manual/patterns.html#sss:pat-or>, in SML/NJ <https://www.smlnj.org/doc/features.html>. <http://rosettacode.org/wiki/Pattern_matching#OCaml> has an example of their use, in OCaml (balancing red-black trees)
2023-12-10 23:43:23 +0100 <cheater> thanks
2023-12-10 23:44:29 +0100 <ski> as mentioned above by tromp,dminuoso_, it's also been considered for GHC
2023-12-10 23:46:02 +0100 <ski> (i think i wrote that OCaml (and Prolog) example, on that RosettaCode page, years ago)
2023-12-10 23:47:52 +0100EvanR(~EvanR@user/evanr) (Quit: Leaving)
2023-12-10 23:49:04 +0100 <Hecate> if there are people who ever shipped static ".a" archives with their haskell libraries, I'd love some insights: https://github.com/haskell/cabal/issues/9509
2023-12-10 23:49:11 +0100EvanR(~EvanR@user/evanr)