Logs on 2023-12-10 (liberachat/#haskell)
| 00:02:59 | × | peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 264 seconds) |
| 00:05:13 | × | tommy___ quits (~tommy@2601:681:5a00:a260:2216:9438:8afd:c460) (Ping timeout: 246 seconds) |
| 00:08:47 | × | Tuplanolla quits (~Tuplanoll@91-159-68-236.elisa-laajakaista.fi) (Quit: Leaving.) |
| 00:10:07 | × | waleee quits (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 256 seconds) |
| 00:14:42 | × | idgaen quits (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1) |
| 00:18:55 | × | mhatta quits (~mhatta@www21123ui.sakura.ne.jp) (Quit: ZNC 1.8.2+deb3.1 - https://znc.in) |
| 00:23:16 | × | lane quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Ping timeout: 276 seconds) |
| 00:25:53 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 00:26:59 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Client Quit) |
| 00:29:40 | → | mhatta joins (~mhatta@www21123ui.sakura.ne.jp) |
| 00:36:28 | → | lane joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) |
| 00:36:31 | → | juri____ joins (~juri@79.140.117.56) |
| 00:39:37 | × | juri_ quits (~juri@79.140.117.90) (Ping timeout: 255 seconds) |
| 00:57:00 | × | cimento quits (CO2@gateway/vpn/protonvpn/cimento) (Quit: WeeChat 4.1.2) |
| 01:02:14 | × | califax quits (~califax@user/califx) (Remote host closed the connection) |
| 01:03:43 | × | machinedgod quits (~machinedg@93-136-130-2.adsl.net.t-com.hr) (Ping timeout: 260 seconds) |
| 01:08:37 | → | newsham joins (~newsham@2603-800c-2c01-6825-857b-69b9-29f4-97e6.res6.spectrum.com) |
| 01:10:12 | <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? |
| 01:12:41 | × | sawilagar quits (~sawilagar@user/sawilagar) (Remote host closed the connection) |
| 01:12:52 | <int-e> | :t arr |
| 01:12:53 | <lambdabot> | Arrow a => (b -> c) -> a b c |
| 01:13:06 | → | sawilagar joins (~sawilagar@user/sawilagar) |
| 01:13:13 | → | califax joins (~califax@user/califx) |
| 01:13:59 | <newsham> | ahh yah |
| 01:18:29 | → | emmanuelux_ joins (~emmanuelu@user/emmanuelux) |
| 01:19:32 | <[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)`. |
| 01:19:39 | <int-e> | newsham: You can embed Prod (a -> b) (c -> d) into Either a c -> Either b d. |
| 01:20:06 | <int-e> | (But the latter has more arrows than the former) |
| 01:20:08 | <shachaf> | Oh man, does Haskell's Category support kinds other than * now? I thought you had to use wacky alternative classes. |
| 01:20:23 | × | emmanuelux quits (~emmanuelu@user/emmanuelux) (Ping timeout: 264 seconds) |
| 01:31:16 | → | cimento joins (CO2@gateway/vpn/protonvpn/cimento) |
| 01:35:46 | × | mhatta quits (~mhatta@www21123ui.sakura.ne.jp) (Quit: ZNC 1.8.2+deb3.1 - https://znc.in) |
| 01:36:19 | × | tomboy64 quits (~tomboy64@user/tomboy64) (Ping timeout: 255 seconds) |
| 01:38:14 | → | mhatta joins (~mhatta@www21123ui.sakura.ne.jp) |
| 01:40:21 | <ski> | @kind Category |
| 01:40:22 | <lambdabot> | (k -> k -> *) -> Constraint |
| 01:41:11 | ski | 's use numbering, rather than primes |
| 01:41:19 | → | tomboy64 joins (~tomboy64@user/tomboy64) |
| 01:42:21 | <shachaf> | I am behind the times. |
| 01:42:42 | <geekosaur> | how much of that is just the PolyKinds extension? |
| 01:46:45 | <shachaf> | Presumably most of it? |
| 01:46:49 | × | cimento quits (CO2@gateway/vpn/protonvpn/cimento) (Quit: WeeChat 4.1.2) |
| 01:46:49 | × | andreabedini quits (~andreabed@159.196.202.200) (Quit: andreabedini) |
| 01:47:00 | <shachaf> | @kind Functor |
| 01:47:01 | <lambdabot> | (* -> *) -> Constraint |
| 01:47:26 | <shachaf> | I guess you'll still need all sorts of fancy things to define the diagonal functor and so on. |
| 01:48:58 | × | sawilagar quits (~sawilagar@user/sawilagar) (Remote host closed the connection) |
| 01:49:19 | → | cimento joins (CO2@gateway/vpn/protonvpn/cimento) |
| 01:49:22 | → | sawilagar joins (~sawilagar@user/sawilagar) |
| 01:52:55 | <newsham> | I want to say something like "if k1 is a morphism, and k2 is a morphism, then (Prod k1 k2) is a morphism". |
| 01:53:11 | <newsham> | but failing to get there with the syntax i am trying to use |
| 01:53:30 | <EvanR> | that description seems to be missing the source and target of the morphism |
| 01:53:46 | <EvanR> | unless there's only 1 object |
| 01:54:02 | <newsham> | was trying to go with: |
| 01:54:02 | <newsham> | class Morph k where |
| 01:54:03 | <newsham> | apply :: (a `k` b) -> a -> b |
| 01:54:14 | <shachaf> | newsham: Hmm, doesn't that work with the thing [Leary] was suggesting? |
| 01:54:34 | <newsham> | i was trying to use heavy gadtery here if possible. but perhaps thats misguided |
| 01:54:45 | <newsham> | trying to avoid |
| 01:55:32 | <ski> | that `Morph' doesn't seem to make much sense, to me |
| 01:55:50 | <newsham> | yah probably that too :) |
| 01:56:08 | <jackdk> | newsham: https://hackage.haskell.org/package/categories-1.0.7/docs/Control-Category-Cartesian-Closed.html ? |
| 01:56:18 | <shachaf> | Yes, I'm not sure what that Morph is trying to be. |
| 01:56:55 | <ski> | i guess it's expressing `k' is (the morphism type of a) concrete category |
| 01:56:59 | <newsham> | jackdk: thank you. i'm trying to build this as an exercise. |
| 01:57:30 | <ski> | (being a category with an underlying/forgetful functor to `Set', which we approximate with `Hask' here) |
| 01:58:37 | <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. |
| 01:59:04 | <ski> | i don't think it would help with that |
| 01:59:54 | <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. |
| 02:01:19 | <newsham> | with this https://github.com/timnewsham/hask-cats/blob/main/src/Alg.hs |
| 02:02:43 | × | wice quits (~wice@176.254.244.83) (Ping timeout: 276 seconds) |
| 02:06:39 | <ski> | (g . f) x = g (f x) |
| 02:08:27 | <haskellbridge> | 13<dxtr> How is "a `foo` b `bar` c" evaluated? |
| 02:08:28 | <ski> | [Leary]'s suggestion sounds relevant |
| 02:08:48 | <haskellbridge> | 13<dxtr> How is ```a `foo` b `bar` c``` evaluated? |
| 02:09:10 | × | sawilagar quits (~sawilagar@user/sawilagar) (Ping timeout: 255 seconds) |
| 02:10:20 | <ski> | > let a `foo` b = (a,b); a `bar` b = (a,b) in 0 `foo` 1 `bar` 2 |
| 02:10:21 | <lambdabot> | ((0,1),2) |
| 02:12:10 | <EvanR> | > let foo = (,); bar = (,) in a `foo` b `bar` c |
| 02:12:11 | <lambdabot> | ((a,b),c) |
| 02:12:50 | × | Unicorn_Princess quits (~Unicorn_P@user/Unicorn-Princess/x-3540542) (Remote host closed the connection) |
| 02:13:16 | <EvanR> | but this depends on the defined precedence of foo and bar right |
| 02:13:34 | <EvanR> | and fixity |
| 02:16:29 | <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)." |
| 02:16:35 | <ski> | <https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-240003.2> |
| 02:16:51 | <ski> | this means that, without a fixity declaration for `foo' and `bar', you'll effectively get |
| 02:16:59 | <ski> | infixl 9 `foo`,`bar` |
| 02:17:12 | <ski> | dxtr ^ |
| 02:18:21 | <haskellbridge> | 13<dxtr> Alright |
| 02:18:51 | <newsham> | where does the bridge comm with? |
| 02:19:38 | <ski> | newsham : you may even be able to use `Prod' at kind level, and `:*' at type level, for the product category, with `DataKinds' |
| 02:20:16 | <newsham> | you mean to make the product types more readable? |
| 02:21:52 | <ski> | more like reusing your `Prod' definition |
| 02:23:09 | <geekosaur> | newsham, #haskell-irc:matrix.org |
| 02:23:24 | <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. |
| 02:23:29 | <ski> | (replacing the '(i0,i1) with i0 :* i1 that is) |
| 02:25:51 | <ski> | so that [Leary]'s `ProdCat' (i'd call it `ProdMor', probably), gets kind `(k -> k -> *) -> (k -> l -> *) -> Prod k l -> Prod k l -> *' |
| 02:25:58 | → | lane1 joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) |
| 02:26:31 | <[Leary]> | Blame `class Category`. |
| 02:26:54 | <geekosaur> | newsham, /whois haskellbridge gives more information, in particular a link to what channels it bridges to what Matrix rooms |
| 02:28:54 | <newsham> | guh is it possible to turn off emojis in libera's web chat? |
| 02:28:55 | × | lane quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Ping timeout: 268 seconds) |
| 02:29:40 | <geekosaur> | I don't think so |
| 02:29:52 | <newsham> | found it. upper left gear. |
| 02:30:01 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 02:30:49 | <newsham> | and yet i still see the emojis for messages above. test :* this. |
| 02:31:09 | <newsham> | i guess its not retroactive on prev msgs |
| 02:31:21 | <geekosaur> | you might prefer checking the log (see the /topic) |
| 02:33:07 | → | sagax joins (~sagax_nb@user/sagax) |
| 02:34:47 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 264 seconds) |
| 02:36:50 | <ski> | newsham : it turns off auto-replacing smileys with emoji, i think, but doesn't affect incoming messages |
| 02:37:30 | <ski> | (hm, or maybe it was the emoji selection button it disabled .. some times since i was on Kiwi) |
| 02:38:20 | → | jmdaemon joins (~jmdaemon@user/jmdaemon) |
| 02:44:53 | × | td_ quits (~td@i5387091B.versanet.de) (Ping timeout: 240 seconds) |
| 02:47:34 | × | mechap quits (~mechap@user/mechap) (Ping timeout: 276 seconds) |
| 02:53:15 | → | nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
| 02:57:01 | <newsham> | in the category constructed by coproducts, are the morphisms also constructed as coproducts? |
| 02:58:31 | × | nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 268 seconds) |
| 03:02:05 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 03:04:47 | → | igemnace joins (~ian@user/igemnace) |
| 03:07:56 | → | igemnace_ joins (~ian@user/igemnace) |
| 03:09:12 | → | igemnace1 joins (~ian@user/igemnace) |
| 03:10:11 | × | igemnace1 quits (~ian@user/igemnace) (Remote host closed the connection) |
| 03:10:14 | × | igemnace quits (~ian@user/igemnace) (Ping timeout: 268 seconds) |
| 03:10:54 | → | igemnace joins (~ian@user/igemnace) |
| 03:11:26 | → | td_ joins (~td@i5387091B.versanet.de) |
| 03:12:10 | × | igemnace_ quits (~ian@user/igemnace) (Ping timeout: 255 seconds) |
| 03:12:21 | → | igemnace_ joins (~ian@user/igemnace) |
| 03:12:52 | → | thegeekinside joins (~thegeekin@177.245.195.141) |
| 03:14:52 | × | Square quits (~Square@user/square) (Ping timeout: 276 seconds) |
| 03:15:25 | × | igemnace quits (~ian@user/igemnace) (Ping timeout: 256 seconds) |
| 03:20:25 | → | lottaquestions joins (~nick@2607:fa49:503d:b200:8455:7551:a8b5:adb1) |
| 03:29:53 | × | lane1 quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Quit: WeeChat 4.1.2) |
| 03:35:38 | <ski> | newsham : hm, which category ? |
| 03:36:03 | <ski> | the one int-e sketched ? |
| 03:41:39 | <int-e> | :t id +++ id |
| 03:41:40 | <lambdabot> | Either b b' -> Either b b' |
| 03:41:44 | × | tremon quits (~tremon@83.80.159.219) (Quit: getting boxed in) |
| 03:42:14 | <int-e> | :t either Right Left -- something extra |
| 03:42:15 | <lambdabot> | Either b a -> Either a b |
| 03:42:37 | × | td_ quits (~td@i5387091B.versanet.de) (Ping timeout: 256 seconds) |
| 03:42:44 | <newsham> | how does Either (a' -> a'') (b' -> b'') compose with (Either (a -> a') (b -> b') ? |
| 03:43:10 | <newsham> | given that you might have Left (g :: a -> a'') and Right (f :: b -> b') |
| 03:43:19 | <int-e> | newsham: It doesn't |
| 03:43:35 | <newsham> | so what is the proper type for composition? do the left and right have to be more compat? |
| 03:44:02 | <int-e> | @djinn Either (a -> b) (a' -> b') -> Either (b -> c) (b' -> c') -> Either (a -> c) (a' -> c') |
| 03:44:02 | <lambdabot> | -- f cannot be realized. |
| 03:44:05 | → | td_ joins (~td@i53870907.versanet.de) |
| 03:44:22 | <ski> | newsham : is that supposed to be ordinary `Either' in Haskell ? |
| 03:44:45 | <ski> | (or some data constructor for a datakind, maybe ?) |
| 03:44:47 | <int-e> | "You can embed Prod (a -> b) (c -> d) into Either a c -> Either b d." |
| 03:45:15 | <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. |
| 03:45:28 | <int-e> | So it's really just an embedding. |
| 03:45:55 | <int-e> | But it would work with the existing `Category` class. |
| 03:47:09 | <int-e> | :t (+++) |
| 03:47:10 | <lambdabot> | ArrowChoice a => a b c -> a b' c' -> a (Either b b') (Either c c') |
| 03:47:12 | <ski> | (note that the `Prod' in `Prod (a -> b) (c -> d)' doesn't really have to do with product categories) |
| 03:47:16 | → | nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
| 03:47:25 | <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. |
| 03:47:47 | <int-e> | ski: yeah good point |
| 03:47:51 | <ski> | the coproduct category is more involved, iirc |
| 03:48:17 | <newsham> | ok, maybe i should wait till later in the series to try to figure this out then. |
| 03:48:51 | <int-e> | (a -> b, c -> d) captures fewer functions than (a,c) -> (b,d). |
| 03:48:53 | <int-e> | :t (***) |
| 03:48:54 | <ski> | i like the search/optimization analogy that Bartosz uses for limits and colimits |
| 03:48:55 | <lambdabot> | Arrow a => a b c -> a b' c' -> a (b, b') (c, c') |
| 03:49:09 | <int-e> | (another embedding) |
| 03:49:44 | <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 |
| 03:51:09 | <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 |
| 03:53:14 | → | finn_elija joins (~finn_elij@user/finn-elija/x-0085643) |
| 03:53:14 | × | FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija))) |
| 03:53:14 | finn_elija | is now known as FinnElija |
| 03:57:19 | × | mosul quits (~mosul@user/mosul) (Read error: Connection reset by peer) |
| 04:02:35 | → | mosul joins (~mosul@user/mosul) |
| 04:03:01 | × | drdo quits (~drdo@bl14-14-49.dsl.telepac.pt) (Ping timeout: 255 seconds) |
| 04:13:04 | → | szkl joins (uid110435@id-110435.uxbridge.irccloud.com) |
| 04:19:40 | × | jargon quits (~jargon@32.sub-174-238-226.myvzw.com) (Remote host closed the connection) |
| 04:24:55 | <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." |
| 04:25:04 | <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⌝ |
| 04:26:45 | → | araujo joins (~araujo@45.131.194.89) |
| 04:26:50 | <araujo> | howdy :) |
| 04:28:01 | <ski> | oy |
| 04:28:34 | × | pretty_dumm_guy quits (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5) |
| 04:31:43 | × | araujo quits (~araujo@45.131.194.89) (Remote host closed the connection) |
| 04:32:36 | → | araujo joins (~araujo@45.131.194.89) |
| 04:36:00 | <araujo> | :) |
| 04:41:04 | → | aforemny joins (~aforemny@2001:9e8:6cf6:8a00:1295:f852:5f8f:52b5) |
| 04:42:35 | × | aforemny_ quits (~aforemny@i59F516ED.versanet.de) (Ping timeout: 264 seconds) |
| 04:44:42 | × | igemnace_ quits (~ian@user/igemnace) (Quit: WeeChat 4.1.2) |
| 04:45:15 | × | thegeekinside quits (~thegeekin@177.245.195.141) (Ping timeout: 252 seconds) |
| 04:45:18 | → | lane joins (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) |
| 04:45:34 | × | sagax quits (~sagax_nb@user/sagax) (Remote host closed the connection) |
| 04:46:07 | × | lane quits (~lane@pool-98-113-180-17.nycmny.fios.verizon.net) (Remote host closed the connection) |
| 04:46:31 | → | igemnace joins (~ian@user/igemnace) |
| 04:47:54 | × | araujo quits (~araujo@45.131.194.89) (Quit: Leaving) |
| 04:48:30 | → | araujo joins (~araujo@45.131.194.89) |
| 04:48:47 | × | nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 256 seconds) |
| 04:51:52 | × | araujo quits (~araujo@45.131.194.89) (Client Quit) |
| 04:52:15 | → | araujo joins (~araujo@45.131.194.89) |
| 05:00:37 | × | DerDummNemetzkii quits (~John_Ivan@user/john-ivan/x-1515935) (Ping timeout: 255 seconds) |
| 05:09:12 | × | hgolden_ quits (~hgolden@2603-8000-9d00-3ed1-dd4f-298a-9c49-a0ed.res6.spectrum.com) (Remote host closed the connection) |
| 05:09:58 | → | trev joins (~trev@user/trev) |
| 05:10:39 | × | trev quits (~trev@user/trev) (Read error: Connection reset by peer) |
| 05:11:20 | → | hgolden joins (~hgolden@2603-8000-9d00-3ed1-dd4f-298a-9c49-a0ed.res6.spectrum.com) |
| 05:11:57 | → | trev joins (~trev@user/trev) |
| 05:22:45 | × | azimut quits (~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection) |
| 05:25:58 | → | azimut joins (~azimut@gateway/tor-sasl/azimut) |
| 05:27:52 | × | azimut quits (~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection) |
| 05:28:11 | → | azimut joins (~azimut@gateway/tor-sasl/azimut) |
| 05:32:08 | → | takuan joins (~takuan@178-116-218-225.access.telenet.be) |
| 05:33:05 | → | Pozyomka_ joins (~pyon@user/pyon) |
| 05:33:07 | × | Pozyomka quits (~pyon@user/pyon) (Ping timeout: 256 seconds) |
| 05:35:25 | × | igemnace quits (~ian@user/igemnace) (Remote host closed the connection) |
| 05:36:10 | → | igemnace joins (~ian@user/igemnace) |
| 05:45:52 | × | igemnace quits (~ian@user/igemnace) (Remote host closed the connection) |
| 05:46:36 | → | igemnace joins (~ian@user/igemnace) |
| 05:52:24 | → | peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com) |
| 06:04:29 | × | araujo quits (~araujo@45.131.194.89) (Quit: Leaving) |
| 06:06:48 | → | araujo joins (~araujo@216.73.163.11) |
| 06:08:42 | × | ec quits (~ec@gateway/tor-sasl/ec) (Remote host closed the connection) |
| 07:06:53 | → | sagax joins (~sagax_nb@user/sagax) |
| 07:20:13 | × | notzmv quits (~zmv@user/notzmv) (Ping timeout: 256 seconds) |
| 07:22:05 | → | skyres joins (~skyres@176.254.244.83) |
| 07:22:45 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 07:23:16 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 255 seconds) |
| 07:29:01 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 07:32:51 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 07:33:10 | × | smalltalkman quits (uid545680@id-545680.hampstead.irccloud.com) (Quit: Connection closed for inactivity) |
| 07:36:36 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 245 seconds) |
| 07:43:26 | → | cwdar^ joins (~cd@c-98-242-74-66.hsd1.ga.comcast.net) |
| 07:44:14 | → | acidjnk_new joins (~acidjnk@p200300d6e72b93299103c78233b0ca81.dip0.t-ipconnect.de) |
| 07:45:54 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 07:46:33 | × | igemnace quits (~ian@user/igemnace) (Quit: WeeChat 4.1.2) |
| 07:48:45 | × | m1dnight quits (~christoph@78-22-4-67.access.telenet.be) (Quit: WeeChat 4.1.1) |
| 07:50:46 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 260 seconds) |
| 07:51:41 | × | peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 252 seconds) |
| 08:04:18 | × | bilegeek quits (~bilegeek@2600:1008:b065:6c8a:2877:790c:5cda:9f45) (Quit: Leaving) |
| 08:05:17 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 08:06:00 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 08:23:29 | → | m1dnight joins (~christoph@78-22-4-67.access.telenet.be) |
| 08:25:52 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 256 seconds) |
| 08:39:52 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 08:44:20 | → | fendor joins (~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c) |
| 08:45:42 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 268 seconds) |
| 08:46:11 | → | nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
| 08:48:07 | × | phma quits (~phma@2001:5b0:2143:b148:7b24:e989:5355:982f) (Read error: Connection reset by peer) |
| 08:51:15 | × | nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 268 seconds) |
| 08:56:02 | → | waleee joins (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) |
| 08:57:52 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 09:00:14 | → | phma joins (phma@2001:5b0:215d:95d8:ddad:50d4:4c93:5f61) |
| 09:01:20 | → | Tuplanolla joins (~Tuplanoll@91-159-68-236.elisa-laajakaista.fi) |
| 09:02:08 | × | arkoinad quits (~abhinav@c-67-169-139-16.hsd1.ca.comcast.net) (Ping timeout: 256 seconds) |
| 09:02:10 | × | tzh quits (~tzh@c-71-193-181-0.hsd1.or.comcast.net) (Quit: zzz) |
| 09:03:53 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 268 seconds) |
| 09:06:28 | → | idgaen joins (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) |
| 09:12:05 | × | sagax quits (~sagax_nb@user/sagax) (Excess Flood) |
| 09:15:57 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 09:16:10 | → | _ht joins (~Thunderbi@28-52-174-82.ftth.glasoperator.nl) |
| 09:19:45 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:1fe:ac5a:8c23:9cce) (Remote host closed the connection) |
| 09:24:06 | × | jmdaemon quits (~jmdaemon@user/jmdaemon) (Ping timeout: 260 seconds) |
| 09:26:37 | × | phma quits (phma@2001:5b0:215d:95d8:ddad:50d4:4c93:5f61) (Read error: Connection reset by peer) |
| 09:30:52 | → | phma joins (~phma@2001:5b0:211c:d608:d6b3:ddaf:3415:a75) |
| 09:30:58 | → | notzmv joins (~zmv@user/notzmv) |
| 09:35:02 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Read error: Connection reset by peer) |
| 09:38:59 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 264 seconds) |
| 09:43:21 | → | rosco joins (~rosco@175.136.152.56) |
| 09:43:37 | → | coot joins (~coot@89-69-206-216.dynamic.chello.pl) |
| 09:48:20 | → | gmg joins (~user@user/gehmehgeh) |
| 09:50:41 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 09:54:48 | × | econo_ quits (uid147250@id-147250.tinside.irccloud.com) (Quit: Connection closed for inactivity) |
| 09:56:23 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 264 seconds) |
| 09:58:45 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:d128:ce35:54e1:65e2) |
| 10:09:58 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 10:18:28 | → | Lord_of_Life_ joins (~Lord@user/lord-of-life/x-2819915) |
| 10:19:10 | × | Lord_of_Life quits (~Lord@user/lord-of-life/x-2819915) (Ping timeout: 260 seconds) |
| 10:21:24 | Lord_of_Life_ | is now known as Lord_of_Life |
| 10:22:06 | → | pretty_dumm_guy joins (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) |
| 10:29:58 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 256 seconds) |
| 10:32:58 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 10:33:38 | → | target_i joins (~target_i@217.175.14.39) |
| 10:38:39 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 260 seconds) |
| 10:49:15 | × | Sgeo quits (~Sgeo@user/sgeo) (Read error: Connection reset by peer) |
| 10:51:47 | → | sawilagar joins (~sawilagar@user/sawilagar) |
| 10:52:14 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 10:57:02 | × | mikess quits (~sam@user/mikess) (Ping timeout: 252 seconds) |
| 11:05:25 | → | Katty joins (~osboxes@185.98.164.21) |
| 11:07:56 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 256 seconds) |
| 11:09:57 | → | nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
| 11:10:14 | × | xff0x quits (~xff0x@ai085147.d.east.v6connect.net) (Ping timeout: 252 seconds) |
| 11:12:05 | → | xff0x joins (~xff0x@178.255.149.135) |
| 11:14:53 | × | nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 240 seconds) |
| 11:16:23 | × | Katty quits (~osboxes@185.98.164.21) (Quit: Konversation terminated!) |
| 11:20:09 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 11:21:17 | → | billchenchina joins (~billchenc@103.152.35.21) |
| 11:22:23 | → | machinedgod joins (~machinedg@93-136-52-133.adsl.net.t-com.hr) |
| 11:22:27 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer) |
| 11:23:04 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 11:30:10 | × | rosco quits (~rosco@175.136.152.56) (Ping timeout: 276 seconds) |
| 11:32:16 | → | Joao003 joins (~Joao003@190.108.99.32) |
| 11:36:49 | × | xff0x quits (~xff0x@178.255.149.135) (Ping timeout: 268 seconds) |
| 11:38:44 | → | xff0x joins (~xff0x@ai085147.d.east.v6connect.net) |
| 11:39:17 | → | rosco joins (~rosco@175.136.152.56) |
| 11:40:22 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 260 seconds) |
| 11:53:40 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 11:55:09 | → | alexherbo2 joins (~alexherbo@2a02-8440-3141-30c9-9c1f-1fa2-2dd0-8b5b.rev.sfr.net) |
| 11:56:04 | → | [itchyjunk] joins (~itchyjunk@user/itchyjunk/x-7353470) |
| 12:00:04 | × | [_] quits (~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 276 seconds) |
| 12:01:11 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 245 seconds) |
| 12:01:45 | × | mrmr15533 quits (~mrmr@user/mrmr) (Quit: Bye, See ya later!) |
| 12:05:05 | × | [itchyjunk] quits (~itchyjunk@user/itchyjunk/x-7353470) (Remote host closed the connection) |
| 12:06:54 | → | mrmr15533 joins (~mrmr@user/mrmr) |
| 12:09:25 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 12:10:19 | mniip_ | is now known as mniip |
| 12:14:19 | × | vgtw quits (~vgtw@user/vgtw) (Ping timeout: 256 seconds) |
| 12:15:35 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 12:34:19 | × | target_i quits (~target_i@217.175.14.39) (Quit: leaving) |
| 12:34:46 | × | billchenchina quits (~billchenc@103.152.35.21) (Remote host closed the connection) |
| 12:34:57 | → | billchenchina joins (~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe) |
| 12:37:39 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 260 seconds) |
| 12:37:51 | × | not_reserved quits (~not_reser@185.216.201.100) (Quit: Client closed) |
| 12:41:42 | → | Ashkan joins (~Ashkan@147.161.173.72) |
| 12:42:03 | → | jtomas joins (~jtomas@90.162.208.36) |
| 12:46:13 | × | foul_owl quits (~kerry@157.97.134.165) (Ping timeout: 276 seconds) |
| 12:47:00 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 12:47:42 | <Joao003> | me waiting for someone to ask something: |
| 12:48:10 | <Ashkan> | Hi folks. Got a question regarding a datatype + possibly a monad to model a search across a Foldable. |
| 12:48:11 | <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 |
| 12:50:11 | <[Leary]> | :t find |
| 12:50:12 | <lambdabot> | Foldable t => (a -> Bool) -> t a -> Maybe a |
| 12:50:14 | <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 |
| 12:50:54 | <Rembane> | :t First -- along with foldMap could perhaps also help you, if you want a Monoid solution to this problem. |
| 12:50:55 | <lambdabot> | Maybe a -> First a |
| 12:51:08 | <Rembane> | Hm... wrong First. |
| 12:51:29 | <Ashkan> | so far I think closest is `foldlM` |
| 12:51:32 | <Ashkan> | :t foldlM |
| 12:51:33 | <lambdabot> | (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b |
| 12:51:56 | <Rembane> | Ashkan: But I think [Leary]'s solution is the simplest one. |
| 12:52:03 | <Joao003> | yeah |
| 12:52:57 | → | Aworks joins (~Aworks@2a09:bac2:c63:3cd::61:26e) |
| 12:53:04 | <Joao003> | but the tricky thing is extracting the result from the `Maybe a' that `find' produces |
| 12:53:10 | <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 |
| 12:53:34 | <Joao003> | oh ok |
| 12:54:20 | <Joao003> | you could use something like a `Maybe' for `m' |
| 12:55:11 | <Aworks> | upi |
| 12:55:34 | <Aworks> | Buddies have build an full Windows with husk |
| 12:55:49 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 255 seconds) |
| 12:56:10 | <Ashkan> | Okay let me put this way then: |
| 12:56:10 | <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`. |
| 12:57:09 | <Joao003> | OK, I understand. |
| 12:59:02 | <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? |
| 12:59:12 | <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 |
| 12:59:12 | <Ashkan> | idiomatic ... |
| 12:59:55 | → | foul_owl joins (~kerry@174-21-66-189.tukw.qwest.net) |
| 13:00:03 | → | aruns joins (~aruns@user/aruns) |
| 13:00:09 | <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 |
| 13:00:21 | <Joao003> | Oh. |
| 13:00:48 | <Ashkan> | Also I don't want the device itself, I want the output of `Device -> IO b` (the `b`) |
| 13:00:54 | <Joao003> | I KNOW. |
| 13:01:26 | <Joao003> | So you want a function kinda like a fold and `find', right? |
| 13:02:15 | <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`" |
| 13:02:37 | <Joao003> | Ok. |
| 13:04:02 | <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` |
| 13:04:35 | <Joao003> | So a `foldl' which after each function application checks the result for something and prematurely stops if it finds the right one? |
| 13:06:13 | <Joao003> | BTW, what is an `ExceptT'? |
| 13:06:56 | × | alexherbo2 quits (~alexherbo@2a02-8440-3141-30c9-9c1f-1fa2-2dd0-8b5b.rev.sfr.net) (Ping timeout: 250 seconds) |
| 13:07:18 | <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 |
| 13:07:24 | <Ashkan> | :t ExceptT |
| 13:07:25 | <lambdabot> | m (Either e a) -> ExceptT e m a |
| 13:07:40 | <Ashkan> | It's the new EitherT |
| 13:07:43 | <Ashkan> | :t EitherT |
| 13:07:44 | <lambdabot> | error: |
| 13:07:44 | <lambdabot> | • Data constructor not in scope: EitherT |
| 13:07:44 | <lambdabot> | • Perhaps you meant variable ‘either’ (imported from Data.Either) |
| 13:07:55 | <Ashkan> | They just removed the EitherT I guess |
| 13:08:27 | <[Leary]> | :t \p -> traverse_ (when <$> p <*> throwE) |
| 13:08:28 | <lambdabot> | (Foldable t, Monad m) => (a -> Bool) -> t a -> ExceptT a m () |
| 13:08:36 | <Joao003> | :t Either |
| 13:08:37 | <lambdabot> | error: |
| 13:08:37 | <lambdabot> | • Data constructor not in scope: Either |
| 13:08:37 | <lambdabot> | • Perhaps you meant variable ‘either’ (imported from Data.Either) |
| 13:08:45 | <Ashkan> | `ExceptT b IO s` = can model two states: continue with `s` or exit with `b` |
| 13:08:48 | <[Leary]> | :t \f p -> traverse_ (when <$> p <*> throwE <=< lift . f) |
| 13:08:48 | <lambdabot> | (Foldable t, Monad m) => (a -> m b) -> (b -> Bool) -> t a -> ExceptT b m () |
| 13:08:57 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 13:09:28 | <[Leary]> | :t \f p -> fmap (either Just (const Nothing)) . runExceptT . traverse_ (when <$> p <*> throwE <=< lift . f) |
| 13:09:29 | <lambdabot> | (Foldable t, Monad f) => (a -> f b) -> (b -> Bool) -> t a -> f (Maybe b) |
| 13:09:31 | <Ashkan> | This is very close actually. Let me see ... |
| 13:09:38 | <[Leary]> | Looks about right. |
| 13:09:43 | <Joao003> | So basically `ExceptT b IO s' is `IO (Either b s)', right? |
| 13:10:26 | <Ashkan> | Joao003 yes. Not sure what call it `ExceptT` and confuse the hell out of everyone. But yes. Basically an `EitherT` |
| 13:11:02 | <Joao003> | Yeah, Haskell naming is pretty confusing. Like, who named `return'/`pure'? |
| 13:12:05 | → | alexherbo2 joins (~alexherbo@2a02-8440-3140-ec03-d472-b551-beb0-2cfa.rev.sfr.net) |
| 13:12:37 | <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* |
| 13:12:56 | <Joao003> | Hmm. |
| 13:13:09 | <Ashkan> | actually that point is the key here |
| 13:13:20 | <Ashkan> | Think about it. Maybe I'm woring. |
| 13:14:33 | <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. |
| 13:14:54 | <Joao003> | This is kinda off-topic, but GHC quotes with `' instead of ``. |
| 13:15:08 | <Ashkan> | and I'm using a `fold*` variant to model the "search" |
| 13:16:18 | <Joao003> | Can you explain why the `ExceptT' is important? |
| 13:17:58 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Read error: Connection reset by peer) |
| 13:18:03 | <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` |
| 13:18:57 | <Joao003> | Ok. |
| 13:19:11 | <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. |
| 13:20:06 | <Joao003> | What do you mean by "exit"? |
| 13:20:17 | <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 |
| 13:21:06 | <[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. |
| 13:21:12 | <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 |
| 13:21:55 | <Ashkan> | Joao003 The essence of monad is when it continues with the flatMap and when it short-circuts |
| 13:22:24 | × | szkl quits (uid110435@id-110435.uxbridge.irccloud.com) (Quit: Connection closed for inactivity) |
| 13:22:37 | <Joao003> | I think the monads conflict what you want |
| 13:23:22 | <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 ... |
| 13:24:34 | × | cwdar^ quits (~cd@c-98-242-74-66.hsd1.ga.comcast.net) (Remote host closed the connection) |
| 13:25:33 | → | vgtw joins (~vgtw@user/vgtw) |
| 13:25:51 | <Ashkan> | wdyt of introducing my own monad like `data Search m b s = m Found b | m Continue s` with the proper `>>=` ? too much ? |
| 13:26:22 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 246 seconds) |
| 13:26:31 | <Joao003> | @hoogle ContT |
| 13:26:31 | <lambdabot> | Control.Monad.Trans.Cont newtype ContT r m a |
| 13:26:31 | <lambdabot> | Control.Monad.Trans.Cont ContT :: ((a -> m r) -> m r) -> ContT r m a |
| 13:26:31 | <lambdabot> | Control.Monad.Cont newtype ContT (r :: k) (m :: k -> *) a |
| 13:26:32 | → | euleritian joins (~euleritia@dynamic-046-114-204-242.46.114.pool.telefonica.de) |
| 13:26:32 | <Ashkan> | Joao003 Could be. Why do you say ? |
| 13:27:39 | × | alexherbo2 quits (~alexherbo@2a02-8440-3140-ec03-d472-b551-beb0-2cfa.rev.sfr.net) (Remote host closed the connection) |
| 13:27:54 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 256 seconds) |
| 13:28:00 | <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." |
| 13:28:52 | → | alexherbo2 joins (~alexherbo@54.149.22.93.rev.sfr.net) |
| 13:29:05 | <Joao003> | Ashkan: I think you can make a monad on your own for this. |
| 13:34:02 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 13:40:12 | <[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. |
| 13:40:20 | <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 |
| 13:40:25 | <ski> | @unmtl ExceptT b (StateT s IO) a |
| 13:40:25 | <lambdabot> | s -> IO (Either b a, s) |
| 13:40:29 | <ski> | f :: Device -> ExceptT b (StateT s IO) () |
| 13:40:41 | <ski> | so you can use `traverse_ f' |
| 13:41:13 | → | mechap joins (~mechap@user/mechap) |
| 13:41:48 | <ski> | ah, i see [Leary] was on this track already |
| 13:42:49 | <ski> | or, if you don't want a result `s' in case you find a matching `b', use `StateT s (ExceptT e IO)' instead |
| 13:43:23 | <ski> | (i was thinking you wanted the last `s', regardless, but perhaps you don't) |
| 13:44:04 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 276 seconds) |
| 13:45:44 | → | drdo joins (~drdo@bl14-14-49.dsl.telepac.pt) |
| 13:46:02 | <ski> | (er, s/ExceptT e/ExceptT b/) |
| 13:47:41 | <Ashkan> | ski hmm ... nice. |
| 13:49:46 | <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 |
| 13:49:55 | <Ashkan> | didn't think of it that way |
| 13:50:41 | <Ashkan> | (yeah, I want the "last" s, correct) |
| 13:52:12 | <[Leary]> | @src traverse_ |
| 13:52:13 | <lambdabot> | traverse_ h xs = foldr (\fx fxs -> h fx *> fxs) (pure ()) |
| 13:52:13 | <lambdabot> | --OR |
| 13:52:13 | <lambdabot> | traverse_ h xs = traverse h xs *> pure () |
| 13:52:24 | <[Leary]> | `traverse_` /is/ a fold. |
| 13:54:42 | × | machinedgod quits (~machinedg@93-136-52-133.adsl.net.t-com.hr) (Ping timeout: 252 seconds) |
| 13:55:54 | × | Aworks quits (~Aworks@2a09:bac2:c63:3cd::61:26e) (Ping timeout: 250 seconds) |
| 13:58:10 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 13:59:35 | × | acidjnk_new quits (~acidjnk@p200300d6e72b93299103c78233b0ca81.dip0.t-ipconnect.de) (Ping timeout: 268 seconds) |
| 14:00:28 | → | finn_elija joins (~finn_elij@user/finn-elija/x-0085643) |
| 14:00:28 | × | FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija))) |
| 14:00:28 | finn_elija | is now known as FinnElija |
| 14:02:40 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 268 seconds) |
| 14:11:50 | <ski> | Ashkan : yea, but do you want the last `s', in case you find a matching `b' ? |
| 14:13:12 | × | jtomas quits (~jtomas@90.162.208.36) (Quit: Leaving) |
| 14:14:10 | × | rosco quits (~rosco@175.136.152.56) (Quit: Lost terminal) |
| 14:14:34 | <ski> | @type traverse_ -- see `Foldable', not `Traversable' |
| 14:14:34 | <lambdabot> | (Foldable t, Applicative f) => (a -> f b) -> t a -> f () |
| 14:15:42 | × | billchenchina quits (~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe) (Remote host closed the connection) |
| 14:16:14 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 14:16:25 | × | euleritian quits (~euleritia@dynamic-046-114-204-242.46.114.pool.telefonica.de) (Read error: Connection reset by peer) |
| 14:16:33 | → | billchenchina joins (~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe) |
| 14:16:42 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 14:16:42 | × | alexherbo2 quits (~alexherbo@54.149.22.93.rev.sfr.net) (Ping timeout: 250 seconds) |
| 14:17:21 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer) |
| 14:18:11 | → | euleritian joins (~euleritia@77.22.252.56) |
| 14:18:59 | <ski> | @type mapAccumL |
| 14:18:59 | × | euleritian quits (~euleritia@77.22.252.56) (Read error: Connection reset by peer) |
| 14:19:00 | <lambdabot> | Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c) |
| 14:19:07 | <ski> | @type ((state . (swap .)) .) . flip . mapAccumL . flip . (((swap .) . runState) .) :: Traversable t => (a -> State s b) -> (t a -> State s (t b)) |
| 14:19:08 | <lambdabot> | Traversable t => (a -> State s b) -> t a -> State s (t b) |
| 14:19:13 | <ski> | @type mapM :: Traversable t => (a -> State s b) -> (t a -> State s (t b)) |
| 14:19:14 | <lambdabot> | Traversable t => (a -> State s b) -> t a -> State s (t b) |
| 14:19:40 | <ski> | @type traverse :: Traversable t => (a -> State s b) -> (t a -> State s (t b)) |
| 14:19:41 | <lambdabot> | Traversable t => (a -> State s b) -> t a -> State s (t b) |
| 14:19:43 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 14:20:53 | <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' |
| 14:21:06 | <Joao003> | @type StateT |
| 14:21:07 | <lambdabot> | (s -> m (a, s)) -> StateT s m a |
| 14:21:21 | <ski> | @type runStateT |
| 14:21:22 | <lambdabot> | StateT s m a -> s -> m (a, s) |
| 14:21:42 | <ski> | @type state :: (s -> (a,s)) -> State s a |
| 14:21:43 | <lambdabot> | (s -> (a, s)) -> State s a |
| 14:21:48 | <ski> | @type runState |
| 14:21:49 | <lambdabot> | State s a -> s -> (a, s) |
| 14:22:04 | <Joao003> | @type State |
| 14:22:05 | <lambdabot> | error: |
| 14:22:05 | <lambdabot> | • Data constructor not in scope: State |
| 14:22:05 | <lambdabot> | • Perhaps you meant one of these: |
| 14:22:09 | <Joao003> | ... |
| 14:22:19 | × | nek0 quits (~nek0@2a01:4f8:222:2b41::12) (Quit: The Lounge - https://thelounge.chat) |
| 14:22:20 | <Joao003> | @type State s a |
| 14:22:21 | <lambdabot> | error: |
| 14:22:21 | <lambdabot> | • Data constructor not in scope: State :: Expr -> Expr -> t |
| 14:22:21 | <lambdabot> | • Perhaps you meant one of these: |
| 14:22:26 | <Joao003> | wth |
| 14:22:29 | <ski> | Ashkan : in your case, you didn't want any new structure, with the elements replaced. so `traverse_'/`mapM_' instead |
| 14:22:43 | <ski> | @kind State |
| 14:22:44 | <lambdabot> | * -> * -> * |
| 14:23:07 | <ski> | @src State |
| 14:23:07 | <lambdabot> | type State s = StateT s Identity |
| 14:23:07 | <lambdabot> | --OR |
| 14:23:07 | <lambdabot> | data State s a = State { runState :: s -> (a, s) } |
| 14:23:19 | <ski> | the first one is what's in the library |
| 14:23:26 | <ski> | @src StateT |
| 14:23:26 | <lambdabot> | Source not found. Listen, broccoli brains, I don't have time to listen to this trash. |
| 14:23:29 | <ski> | ok |
| 14:23:50 | <ski> | newtype StateT s m a = StateT {runState :: s -> m (a,s)} |
| 14:23:56 | <Joao003> | @kind StateT |
| 14:23:57 | <lambdabot> | * -> (* -> *) -> * -> * |
| 14:28:33 | × | Joao003 quits (~Joao003@190.108.99.32) (Quit: Bye!) |
| 14:29:01 | × | vgtw quits (~vgtw@user/vgtw) (Ping timeout: 246 seconds) |
| 14:29:29 | × | billchenchina quits (~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe) (Ping timeout: 268 seconds) |
| 14:33:43 | × | qqq quits (~qqq@92.43.167.61) (Ping timeout: 256 seconds) |
| 14:40:37 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 276 seconds) |
| 14:43:15 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 14:43:47 | → | vgtw joins (~vgtw@user/vgtw) |
| 14:47:28 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 14:50:40 | → | qqq joins (~qqq@92.43.167.61) |
| 14:51:20 | → | Square joins (~Square@user/square) |
| 14:53:32 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 268 seconds) |
| 14:54:00 | → | nek0 joins (~nek0@2a01:4f8:222:2b41::12) |
| 14:57:15 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 15:11:26 | → | nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
| 15:16:21 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 268 seconds) |
| 15:17:04 | → | zetef joins (~quassel@82.76.107.234) |
| 15:17:17 | × | nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 268 seconds) |
| 15:19:04 | → | acidjnk_new joins (~acidjnk@p200300d6e72b93299103c78233b0ca81.dip0.t-ipconnect.de) |
| 15:23:15 | × | zetef quits (~quassel@82.76.107.234) (Remote host closed the connection) |
| 15:27:28 | → | Tlsx joins (rscastilho@189.61.140.215) |
| 15:28:27 | → | [itchyjunk] joins (~itchyjunk@user/itchyjunk/x-7353470) |
| 15:35:13 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 276 seconds) |
| 15:37:44 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 15:43:13 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 255 seconds) |
| 15:43:45 | × | Ashkan quits (~Ashkan@147.161.173.72) (Quit: Client closed) |
| 15:43:55 | → | euleritian joins (~euleritia@77.22.252.56) |
| 15:45:43 | × | azimut quits (~azimut@gateway/tor-sasl/azimut) (Ping timeout: 240 seconds) |
| 15:45:58 | × | son0p quits (~ff@181.136.122.143) (Remote host closed the connection) |
| 15:47:16 | × | vgtw quits (~vgtw@user/vgtw) (Ping timeout: 256 seconds) |
| 15:49:43 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 15:52:17 | → | wootehfoot joins (~wootehfoo@user/wootehfoot) |
| 15:54:33 | × | FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija))) |
| 15:54:34 | → | FinnElija joins (~finn_elij@user/finn-elija/x-0085643) |
| 15:55:04 | → | vgtw joins (~vgtw@user/vgtw) |
| 15:58:01 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 256 seconds) |
| 15:58:11 | → | target_i joins (~target_i@217.175.14.39) |
| 15:59:50 | → | son0p joins (~ff@181.136.122.143) |
| 16:00:39 | × | aruns quits (~aruns@user/aruns) (Ping timeout: 252 seconds) |
| 16:03:13 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 16:11:15 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 16:14:00 | → | smalltalkman joins (uid545680@id-545680.hampstead.irccloud.com) |
| 16:19:07 | → | azimut joins (~azimut@gateway/tor-sasl/azimut) |
| 16:22:54 | lg1882 | is now known as lg188 |
| 16:26:31 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 16:28:44 | → | danza joins (~danza@151.43.234.184) |
| 16:30:20 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 252 seconds) |
| 16:30:54 | × | waleee quits (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 252 seconds) |
| 16:36:50 | × | danza quits (~danza@151.43.234.184) (Ping timeout: 268 seconds) |
| 16:39:18 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 16:45:08 | → | gdown joins (~gavin@h69-11-149-109.kndrid.broadband.dynamic.tds.net) |
| 16:48:20 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 16:48:31 | → | justsomeguy joins (~justsomeg@user/justsomeguy) |
| 16:50:05 | × | [itchyjunk] quits (~itchyjunk@user/itchyjunk/x-7353470) (Read error: Connection reset by peer) |
| 16:50:17 | → | [itchyjunk] joins (~itchyjunk@user/itchyjunk/x-7353470) |
| 16:53:03 | → | DerDummNemetzkii joins (~John_Ivan@user/john-ivan/x-1515935) |
| 16:56:39 | → | [_] joins (~itchyjunk@user/itchyjunk/x-7353470) |
| 16:57:31 | × | vgtw quits (~vgtw@user/vgtw) (Ping timeout: 256 seconds) |
| 16:59:27 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 260 seconds) |
| 16:59:56 | × | [itchyjunk] quits (~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 245 seconds) |
| 17:01:46 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 17:02:40 | → | tremon joins (~tremon@83.80.159.219) |
| 17:02:42 | → | mikess joins (~sam@user/mikess) |
| 17:09:49 | × | AlexZenon quits (~alzenon@178.34.162.199) (Ping timeout: 268 seconds) |
| 17:11:36 | × | Xe quits (~cadey@perl/impostor/xe) (Ping timeout: 245 seconds) |
| 17:13:41 | → | Xe joins (~cadey@perl/impostor/xe) |
| 17:13:42 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 17:13:53 | → | AlexZenon joins (~alzenon@178.34.162.199) |
| 17:17:43 | → | dhil joins (~dhil@2001:8e0:2014:3100:bf6:da90:7ddf:392e) |
| 17:22:20 | → | dcoutts joins (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) |
| 17:25:50 | → | laxmik joins (~laxmik@2a01:c23:9597:b700:707f:bbe3:5986:73cb) |
| 17:26:57 | → | arkoinad joins (~abhinav@c-67-169-139-16.hsd1.ca.comcast.net) |
| 17:27:50 | → | kimiamania464 joins (~65804703@user/kimiamania) |
| 17:27:53 | laxmik | is now known as michals |
| 17:30:51 | × | kimiamania46 quits (~65804703@user/kimiamania) (Ping timeout: 252 seconds) |
| 17:30:51 | kimiamania464 | is now known as kimiamania46 |
| 17:40:02 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Ping timeout: 268 seconds) |
| 17:41:40 | × | michals quits (~laxmik@2a01:c23:9597:b700:707f:bbe3:5986:73cb) (Ping timeout: 250 seconds) |
| 17:41:55 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 17:44:31 | → | aruns joins (~aruns@user/aruns) |
| 17:48:15 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:d128:ce35:54e1:65e2) (Remote host closed the connection) |
| 17:48:30 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:d128:ce35:54e1:65e2) |
| 17:57:07 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 18:01:50 | <haskellbridge> | 12<Celestial> 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 |
| 18:01:50 | <haskellbridge> | sure how to use this for… |
| 18:01:50 | <haskellbridge> | 12<Celestial> my specific use-case though |
| 18:02:59 | <geekosaur> | MVar or TVar, Chan or TChan, etc. |
| 18:03:15 | <geekosaur> | the T variants use STM |
| 18:03:44 | <haskellbridge> | 12<Celestial> another thing I know nothing about haha |
| 18:03:53 | <haskellbridge> | 12<Celestial> Is that this sort-of-escapable IO-ish thing? |
| 18:04:02 | <geekosaur> | no |
| 18:04:15 | <geekosaur> | it's software transactional memory |
| 18:04:47 | <geekosaur> | it won't let you commit a transaction unless every indivisual action can complete successfully; otherwise it retries |
| 18:04:57 | <geekosaur> | the ultimate result is an IO action |
| 18:05:11 | → | [itchyjunk] joins (~itchyjunk@user/itchyjunk/x-7353470) |
| 18:05:31 | <haskellbridge> | 12<Celestial> ah |
| 18:05:31 | <geekosaur> | https://www.microsoft.com/en-us/research/publication/composable-memory-transactions/ |
| 18:05:54 | → | waleee joins (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) |
| 18:05:58 | <haskellbridge> | 12<Celestial> I think I was thinking of the ST monad? |
| 18:06:10 | <geekosaur> | yes |
| 18:06:15 | <haskellbridge> | 12<Celestial> thank you |
| 18:06:15 | <geekosaur> | ST is unrelated to STM |
| 18:06:36 | → | tzh joins (~tzh@c-71-193-181-0.hsd1.or.comcast.net) |
| 18:07:35 | × | justsomeguy quits (~justsomeg@user/justsomeguy) (Read error: Connection reset by peer) |
| 18:08:41 | × | [_] quits (~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 245 seconds) |
| 18:08:48 | <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)` |
| 18:08:59 | <hexology> | that wouldn't work with newtype because it has more than one parameter, right? |
| 18:09:08 | <geekosaur> | `type`? |
| 18:09:40 | <hexology> | thank you! |
| 18:09:43 | <hexology> | https://en.wikibooks.org/wiki/Haskell/Type_declarations#type_for_making_type_synonyms |
| 18:09:58 | <geekosaur> | `newtype` is for when you want to either hide a type or override one or more typeclass instances |
| 18:10:29 | <hexology> | ah, i was wondering |
| 18:10:39 | × | pavonia quits (~user@user/siracusa) (Quit: Bye!) |
| 18:10:51 | <hexology> | and let's say i wanted to do that for something with more than one type parameter or constructor |
| 18:10:54 | <hexology> | how would i do that? |
| 18:11:01 | <geekosaur> | either way you're making a new distinct type from an existing one |
| 18:11:47 | <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)`? |
| 18:12:16 | <haskellbridge> | 12<Celestial> 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 |
| 18:12:32 | <haskellbridge> | 12<Celestial> you can't have instances with type |
| 18:12:43 | <hexology> | so what if i want to change how e.g. Foldable works on Array2d, what would i do then? |
| 18:12:46 | <haskellbridge> | 12<Celestial> `type` creates a synonym / alias |
| 18:12:59 | <geekosaur> | all this said I'm not sure why you aren't using `type Array2d i e = Ix i => Array (i,i) e` |
| 18:13:04 | <haskellbridge> | 12<Celestial> you'd need to wrap it in a `newtype` |
| 18:13:12 | <geekosaur> | Arays can be multidimensional |
| 18:13:25 | <hexology> | geekosaur: because i didn't realize i could do that! |
| 18:13:52 | <hexology> | i see, it's right here in the docs: (Ix a, Ix b) => Ix (a, b) |
| 18:13:57 | <hexology> | that's handy |
| 18:14:53 | <haskellbridge> | 12<Celestial> you can even index by `Void` |
| 18:14:55 | <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? |
| 18:14:57 | <haskellbridge> | 12<Celestial> for that nice 0 dimensional array |
| 18:15:02 | <geekosaur> | yes |
| 18:15:18 | <hexology> | thanks a lot |
| 18:15:25 | <geekosaur> | `type` just creates aliases, changing behavior requires `newtype` or `data` |
| 18:15:46 | × | cimento quits (CO2@gateway/vpn/protonvpn/cimento) (Quit: WeeChat 4.1.2) |
| 18:15:49 | <hexology> | how does constructing an array with tuple indexes work? |
| 18:16:13 | → | cimento joins (CO2@gateway/vpn/protonvpn/cimento) |
| 18:16:47 | <hexology> | i've been using listArray, should i use something like `fill` instead? |
| 18:16:47 | <geekosaur> | the Ix instance lays them out in order (x0,y0),(x0,y1),…,(x1,y0),… |
| 18:17:17 | <hexology> | oh hang on i see. yeah i can pass the raw association data to `array` itself |
| 18:17:27 | <hexology> | ahh okay that helps too |
| 18:18:01 | <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? |
| 18:18:20 | <geekosaur> | yes |
| 18:18:38 | <hexology> | where are you seeing that ordering for the Ix instance? |
| 18:19:10 | <hexology> | that is, how it corresponds to the underlying flat array order |
| 18:19:19 | <hexology> | still learning how to navigate these docs |
| 18:20:25 | <hexology> | or am i thinking about this the wrong way? where the underlying storage order is opaque/irrelevant |
| 18:20:42 | <geekosaur> | the top of https://downloads.haskell.org/ghc/9.2.5/docs/html/libraries/base-4.16.4.0/Data-Ix.html |
| 18:20:52 | <geekosaur> | "`Ix` uses row-major order: |
| 18:21:33 | <hexology> | right, but i guess i don't see how that's encoded in the definition or type signature |
| 18:22:02 | <hexology> | maybe that's in the implementation of `index`, `range`, etcD? |
| 18:22:13 | <geekosaur> | yes |
| 18:22:34 | × | wootehfoot quits (~wootehfoo@user/wootehfoot) (Quit: Leaving) |
| 18:22:52 | <hexology> | got it, i see now |
| 18:22:52 | <hexology> | thanks agin |
| 18:29:55 | × | DerDummNemetzkii quits (~John_Ivan@user/john-ivan/x-1515935) (Remote host closed the connection) |
| 18:30:16 | → | DerDummNemetzkii joins (~John_Ivan@user/john-ivan/x-1515935) |
| 18:31:10 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 18:32:52 | × | duncan quits (~duncan@user/duncan) (Quit: ZNC 1.8.2 - https://znc.in) |
| 18:33:11 | → | laxmik joins (~laxmik@2a01:c23:9597:b700:707f:bbe3:5986:73cb) |
| 18:33:47 | × | laxmik quits (~laxmik@2a01:c23:9597:b700:707f:bbe3:5986:73cb) (Client Quit) |
| 18:34:04 | → | duncan joins (~duncan@user/duncan) |
| 18:34:43 | × | tri quits (~tri@ool-18bc2e74.dyn.optonline.net) (Quit: Reconnecting) |
| 18:34:56 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 18:36:04 | ← | tri parts (~tri@ool-18bc2e74.dyn.optonline.net) () |
| 18:36:18 | → | tri joins (~tri@ool-18bc2e74.dyn.optonline.net) |
| 18:36:18 | <haskellbridge> | 12<Celestial> I'm now stuck with a "thread blocked indefinitely in an MVar operation" lol |
| 18:40:05 | <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 |
| 18:40:10 | × | duncan quits (~duncan@user/duncan) (Quit: ZNC 1.8.2 - https://znc.in) |
| 18:42:10 | <Hecate> | 👍 |
| 18:43:13 | <yushyin> | :t for |
| 18:43:14 | <lambdabot> | (Traversable t, Applicative f) => t a -> (a -> f b) -> f (t b) |
| 18:43:17 | <yushyin> | :t forM |
| 18:43:18 | <lambdabot> | (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b) |
| 18:44:04 | <hexology> | is there an Identity applicative? |
| 18:44:28 | <Rembane> | The Identity monad should have an applicative instance. |
| 18:44:37 | <hexology> | thanks |
| 18:44:51 | <hexology> | is there any particular reason that's better than `flip map`? |
| 18:44:58 | <hexology> | (but good to know about for sure) |
| 18:46:00 | <Rembane> | You get all the fun from Functor, Applicative and Monad. :D |
| 18:47:17 | <haskellbridge> | 12<Celestial> not really useful in this case, but you'll also get used to the order that `map` is the mapping function first :P |
| 18:47:48 | <haskellbridge> | 12<Celestial> it also makes sense in the higher order context because you can write somehing like `double = map (*2)` |
| 18:48:08 | <haskellbridge> | 12<Celestial> you can also use `<$>` infix if you like! |
| 18:48:13 | <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 |
| 18:48:23 | → | duncan joins (~duncan@user/duncan) |
| 18:48:28 | <haskellbridge> | 12<Celestial> `length <$> ["Hello", "World"]` |
| 18:48:53 | <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 |
| 18:49:05 | <haskellbridge> | 12<Celestial> this sounds like you want to write some "smaller" functions and compose them upstream ;) |
| 18:49:26 | <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 |
| 18:50:05 | <hexology> | i believe the ancient masters used tools called "pen & paper" for this, but i'm unfamiliar with such mysterious arts |
| 18:50:52 | <hexology> | (my penmanship has degraded badly over the years and i need to get back in the habit of writing stuff down) |
| 18:51:15 | <hexology> | actually maybe this is good motivation. use a notepad instead of `flip map` |
| 18:51:38 | <haskellbridge> | 12<Celestial> 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 |
| 18:51:52 | <haskellbridge> | 12<Celestial> then I implement those with "unknown" functions as needed and implement those |
| 18:51:56 | <hexology> | HLS can generate signatures? is that a code action? |
| 18:52:48 | <haskellbridge> | 12<Celestial> https://matrix-client.matrix.org//26caf53b/image.png |
| 18:52:57 | <haskellbridge> | 12<Celestial> oh wait you can't see that on the irc side |
| 18:52:58 | <haskellbridge> | 12<Celestial> yes |
| 18:53:11 | <hexology> | i can hop on matrix too |
| 18:53:26 | × | duncan quits (~duncan@user/duncan) (Quit: ZNC 1.8.2 - https://znc.in) |
| 18:53:31 | <haskellbridge> | 12<Celestial> or rather it defines the function with a hole implementation and a signature |
| 18:53:43 | <haskellbridge> | 12<Celestial> hexology: not worth it for that image :) |
| 18:53:58 | <hexology> | it's maybe easier anyway for code formatting etc. plus i can tag you there |
| 18:54:23 | <hexology> | what room is this bridged to? https://matrix.to/#/#haskell:matrix.org looks like a completely different conversation happening |
| 18:54:36 | <hexology> | oh i see there's a space |
| 18:54:40 | → | duncan joins (~duncan@user/duncan) |
| 18:54:40 | <hexology> | and an irc-bridged room |
| 18:54:46 | <hexology> | kind of you to idle in here for us lost souls on irc |
| 18:57:22 | × | euleritian quits (~euleritia@77.22.252.56) (Ping timeout: 276 seconds) |
| 18:57:34 | → | euleritian joins (~euleritia@dynamic-046-114-200-254.46.114.pool.telefonica.de) |
| 18:57:53 | <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 |
| 18:58:54 | → | vgtw joins (~vgtw@user/vgtw) |
| 18:59:13 | <haskellbridge> | 12<Celestial> I think this room specifically is targetted towards IRC |
| 19:00:13 | × | euleritian quits (~euleritia@dynamic-046-114-200-254.46.114.pool.telefonica.de) (Read error: Connection reset by peer) |
| 19:00:31 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 19:01:56 | <Rembane> | hexology: There's a list of community resources here, e.g. this channel and Matrix: https://www.haskell.org/community/ |
| 19:02:22 | <Rembane> | So that's something. |
| 19:05:18 | <geekosaur> | IRC came first by several decades by the way, and there's a bunch of folks in here who don't use Matrix |
| 19:05:52 | × | dhil quits (~dhil@2001:8e0:2014:3100:bf6:da90:7ddf:392e) (Ping timeout: 246 seconds) |
| 19:12:58 | → | nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
| 19:13:42 | × | duncan quits (~duncan@user/duncan) (Quit: ZNC 1.8.2 - https://znc.in) |
| 19:14:27 | <hexology> | geekosaur: indeed, but in this case it would have been useful to know which matrix room this was bridged to |
| 19:14:34 | <hexology> | Rembane: those are helpful |
| 19:14:49 | <Rembane> | hexology: Sweet! :) |
| 19:15:31 | <geekosaur> | if you /whois the bridge bot, it includes a link showing all the bridged channels and their matrix rooms |
| 19:15:50 | <geekosaur> | there's a limit to how big topics can get |
| 19:16:25 | <hexology> | that's the "matterbridge" link? |
| 19:16:32 | → | duncan joins (~duncan@user/duncan) |
| 19:16:41 | <hexology> | looks like it. thanks |
| 19:17:16 | → | testing500 joins (~user@host-92-11-94-158.as13285.net) |
| 19:17:41 | × | nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 240 seconds) |
| 19:17:55 | × | duncan quits (~duncan@user/duncan) (Client Quit) |
| 19:19:53 | <tomsmeding> | lol, that goes to a paste |
| 19:19:57 | <tomsmeding> | I guess that works :) |
| 19:20:23 | <tomsmeding> | geekosaur: feel free to link to https://paste.tomsmeding.com/syOTuo6O/raw if you want |
| 19:20:48 | <hexology> | it looks like that's in there, but with a shortened url |
| 19:21:12 | <tomsmeding> | yes I was just surprised that it just went to a paste instead of a dedicated page :) |
| 19:21:20 | <tomsmeding> | fist the hacker spirit though |
| 19:26:15 | <EvanR> | still not exactly sure what [the] matrix is |
| 19:26:25 | <EvanR> | should I follow the white rabbit? |
| 19:27:13 | → | duncan joins (~duncan@user/duncan) |
| 19:27:21 | × | duncan quits (~duncan@user/duncan) (Remote host closed the connection) |
| 19:27:31 | <EvanR> | 💊 |
| 19:32:25 | × | testing500 quits (~user@host-92-11-94-158.as13285.net) (Remote host closed the connection) |
| 19:43:05 | → | pagnol joins (~user@2a02:a210:a3c:b00:87aa:b531:d3b2:73fa) |
| 19:46:08 | → | jargon joins (~jargon@32.sub-174-238-226.myvzw.com) |
| 19:48:33 | <monochrom> | Someone should create a competitor to Matrix and call it Wave. >:) |
| 19:50:14 | → | peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com) |
| 19:58:31 | × | trev quits (~trev@user/trev) (Quit: trev) |
| 20:10:04 | × | Tlsx quits (rscastilho@189.61.140.215) (Remote host closed the connection) |
| 20:10:10 | × | peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 276 seconds) |
| 20:11:29 | × | glider quits (~glider@user/glider) (Quit: ZNC - https://znc.in) |
| 20:17:21 | <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? |
| 20:18:10 | <cheater> | i'm thinking of something like case myFoo of { Error -> ...; Bar x y, Quux x y -> runFunc x y } |
| 20:19:53 | <dminuoso_> | cheater: Write them as separate branches. |
| 20:20:28 | <cheater> | don't really want separate branches (instead of runFunc x y i have a pretty large block) |
| 20:20:29 | <tromp> | Haskell doesn't support that. although there is this proposal https://wiki.haskell.org/MultiCase |
| 20:20:32 | <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. |
| 20:20:41 | <cheater> | i guess i could extract that block and put it in a function, or something. |
| 20:20:56 | <cheater> | "the one thing"? |
| 20:22:37 | <dminuoso_> | https://github.com/ghc-proposals/ghc-proposals/pull/585 |
| 20:22:43 | <dminuoso_> | https://github.com/ghc-proposals/ghc-proposals/pull/609 |
| 20:24:14 | <cheater> | what is "the one thing"? |
| 20:24:22 | <dminuoso_> | Oh. Binding variables. |
| 20:24:55 | × | td_ quits (~td@i53870907.versanet.de) (Ping timeout: 256 seconds) |
| 20:24:59 | <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? |
| 20:26:01 | <hexology> | or similarly if i write `zip [0..] (lines inputText)` |
| 20:26:59 | <Rembane> | hexology: IIRC It should be evaluated only once. |
| 20:27:04 | <dminuoso_> | cheater: It roughly degrades the proposal to case-of on numbers, literals or nullary constructors. |
| 20:27:19 | <dminuoso_> | For anything else, you (probably) still have to write out each branch by hand. |
| 20:27:22 | <cheater> | ugh |
| 20:27:38 | → | alp_ joins (~alp@2001:861:e3d6:8f80:7092:9744:337:b98c) |
| 20:27:50 | <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 |
| 20:28:14 | <EvanR> | monochrom, took me a minute but I got the reference |
| 20:29:59 | <Rembane> | hexology: The trick is generally to see if the thunks get evaluated. I would just ignore them until they bite you. |
| 20:30:19 | → | Unicorn_Princess joins (~Unicorn_P@user/Unicorn-Princess/x-3540542) |
| 20:30:30 | <hexology> | this is more of out interest/curiosity than any particular need |
| 20:34:00 | <EvanR> | let inputLines = lines inputText; n = length inputLines in ... |
| 20:34:06 | <EvanR> | perhaps |
| 20:34:27 | → | anderson joins (~anderson@user/anderson) |
| 20:35:15 | <hexology> | i'm not sure about all the semicolon rules yet, so i used 2 `let`s instead |
| 20:35:17 | <EvanR> | if ... only uses n, then you only loop over inputText at most once |
| 20:35:26 | <EvanR> | your only had 1 let |
| 20:35:32 | <hexology> | oh |
| 20:35:37 | <hexology> | i meant to have 2 |
| 20:35:37 | <APic> | lol |
| 20:35:47 | <hexology> | s/in n/in let in/ |
| 20:35:50 | <hexology> | letn |
| 20:35:55 | <EvanR> | ok makes more sense now |
| 20:35:56 | <hexology> | i give up, you know what i mean :) |
| 20:36:57 | <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 |
| 20:36:58 | <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 |
| 20:37:17 | → | __monty__ joins (~toonn@user/toonn) |
| 20:37:55 | <hexology> | right, that's what i wasn't sure of |
| 20:39:09 | <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 |
| 20:39:41 | → | peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com) |
| 20:39:58 | <EvanR> | or do like me, and reload the file each time xD |
| 20:40:12 | <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 |
| 20:40:31 | <hexology> | so i was hoping to at least get the number of lines and the intermediate list of lines in a single shot |
| 20:41:11 | <hexology> | of course none of this matters for aoc day3 specifically, but again i'm taking this as a learning and exploration opportunity |
| 20:41:34 | <EvanR> | you can't get the number of lines until after all the lines have been identified |
| 20:41:49 | <EvanR> | it basically last |
| 20:42:35 | <EvanR> | if you want to use Array dunno if there's a way around it |
| 20:42:52 | <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 |
| 20:43:01 | <hexology> | at least i'm pretty sure that should be possible |
| 20:43:12 | <probie> | What does "a single pass" mean? |
| 20:43:17 | <EvanR> | when you get lines you can start using the lines before you're finished reading the input |
| 20:43:28 | <EvanR> | unlike the integer number of total lines, which must wait until the end |
| 20:44:00 | <EvanR> | implementing lines yourself won't help there |
| 20:44:18 | <hexology> | probie: i mean `for (line in lines) { ... }` -- not doing that more times than necessary |
| 20:44:36 | <probie> | Is `map ((*2) . (+1))` a single pass, or two passes? |
| 20:44:44 | <dminuoso_> | Yes. |
| 20:44:53 | <hexology> | probie: that's up to GHC but i would hope that it's one |
| 20:45:08 | <c_wraith> | I don't know how you could implement map that would make it two passes |
| 20:45:22 | <probie> | If I go `head . map ((*2) . (+1))` how many times have I passed over the list? |
| 20:45:33 | <dminuoso_> | c_wraith: Still, it depends a bit on how you interpret "pass" |
| 20:45:34 | <c_wraith> | the important question is whether `map (*2) . map (+1)` is one pass or two |
| 20:45:44 | <hexology> | c_wraith: precisely, that's the essence of what i'm asking here |
| 20:45:45 | <dminuoso_> | So my answer remains: yes. |
| 20:45:46 | <EvanR> | or zero |
| 20:45:56 | <EvanR> | any haskell code could be doing zero passes |
| 20:46:00 | <EvanR> | depending |
| 20:46:25 | <c_wraith> | probie: by my counting zero passes when you have head. It only ever evaluates the first (:) constructor and its first argument |
| 20:47:05 | <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 |
| 20:47:34 | <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 |
| 20:48:08 | <hexology> | or if internally GHC internally tracks the sizes of known-finite lists and it doesn't matter |
| 20:48:12 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 20:48:15 | <hexology> | (tracks at runtime*) |
| 20:48:26 | <dminuoso_> | probie: A more interesting question is whether `map (*2) . map (+1)` will map twice or not. |
| 20:48:31 | <EvanR> | it'll probably loop over the list of lines to get the length |
| 20:49:15 | <dminuoso_> | Which in principle would map twice, but GHC has a bunch of RULES that will - if they fire - do short cut fusion here. |
| 20:49:45 | <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 |
| 20:49:46 | <dminuoso_> | probie: As a point of interest: for guaranteed short cut fusion in the general fmap case (i.e. repeated fmap applications) use Yoneda. |
| 20:49:53 | <dminuoso_> | Or even in the list case. |
| 20:50:01 | <dminuoso_> | If you rely on this happening, use Yoneda. |
| 20:50:09 | <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 |
| 20:50:39 | <hexology> | (unless haskell has resizeable arrays where you can pre-allocate a bunch of lines, like what cpython does internally for lists) |
| 20:50:41 | <EvanR> | hexology, yes but... getting a list of lines is lazy and an Int isn't |
| 20:51:09 | <EvanR> | when you make a Vector from a list, it does resize as it discovers the list is bigger and bigger, iirc |
| 20:51:30 | <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 |
| 20:51:43 | <hexology> | i haven't tried using Vector yet, only Array |
| 20:52:00 | <hexology> | good to know something like that exists |
| 20:52:12 | <hexology> | but i think your point about lines of being lazy is clarifying |
| 20:53:26 | <hexology> | `lines inputText` doesn't immediately create a list, it builds up some kind of graph of thunks, right? |
| 20:53:54 | <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 |
| 20:54:26 | <EvanR> | near the worst cases, yes there will be a bunch of thunks for some reason |
| 20:54:32 | <EvanR> | that's usually a mistake |
| 20:54:50 | <probie> | > take 0 $ lines (error "Oh no") |
| 20:54:51 | <lambdabot> | [] |
| 20:57:28 | <hexology> | got it |
| 20:58:27 | × | pretty_dumm_guy quits (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5) |
| 20:58:56 | <EvanR> | and since you're using String = [Char], each line is itself lazy (ideally) |
| 20:59:00 | → | pretty_dumm_guy joins (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) |
| 20:59:23 | <hexology> | it's from `inputText <- getContents` in this case |
| 21:00:11 | <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` |
| 21:00:39 | <EvanR> | that sounds like some other language xD |
| 21:01:05 | <EvanR> | when you based the computation on getContents, it only reads a Char from stdin if it's needed |
| 21:01:24 | <EvanR> | so if you process the lines char by char, and line by line, in order, then it only needs 1 Char lookahead |
| 21:01:54 | → | alexherbo2 joins (~alexherbo@2a02-8440-3140-cd78-808d-cfaa-bb42-954e.rev.sfr.net) |
| 21:03:10 | <EvanR> | but using the length of a line or total number of lines will potentially mess that up |
| 21:03:17 | <hexology> | https://bpa.st/EPDA this is basically what i'm doing |
| 21:03:39 | <hexology> | err, not show, print |
| 21:03:54 | <hexology> | but that's the general idea |
| 21:04:04 | <EvanR> | right |
| 21:04:05 | <monochrom> | With "inputText <- getContents" if you add "let foo = lines inputText" then foo is the list of lines. |
| 21:05:18 | <EvanR> | if somethingUseful accesses the array at all, then all the lines will be processed first to get the lengths |
| 21:06:36 | <EvanR> | so that's where your "buffering" would come from, it's not a given |
| 21:07:04 | <hexology> | makes sense |
| 21:07:14 | <hexology> | wait, GHC doesn't do any of its own i/o buffering? |
| 21:07:22 | <hexology> | i know usually the OS does, but still |
| 21:07:32 | <EvanR> | yeah but that has no bearing here |
| 21:07:51 | <hexology> | sure. just following the thread, so to speak |
| 21:07:56 | × | alexherbo2 quits (~alexherbo@2a02-8440-3140-cd78-808d-cfaa-bb42-954e.rev.sfr.net) (Ping timeout: 250 seconds) |
| 21:07:58 | <EvanR> | whether there's buffering in the backend you can still work with 1 char at a time |
| 21:08:02 | <hexology> | right |
| 21:08:28 | <EvanR> | whether you build up a bunch of chars in the process depends on how you do it |
| 21:08:36 | <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? |
| 21:08:40 | <hexology> | https://downloads.haskell.org/ghc/latest/docs/users_guide/profiling.html# |
| 21:08:49 | <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. |
| 21:09:06 | → | duncan joins (~duncan@user/duncan) |
| 21:09:16 | × | duncan quits (~duncan@user/duncan) (Client Quit) |
| 21:09:19 | <probie> | hexology: In a real application with nontrivial performance requirements, you would neither be using `getContents` nor the `String` type :p |
| 21:09:29 | <EvanR> | profiling is an easy way to identify big use of heap space when you didn't think you needed it |
| 21:09:45 | <hexology> | what would you use for text data intead? https://hackage.haskell.org/package/text-1.2.4.1/docs/Data-Text.html this? |
| 21:09:47 | <EvanR> | and yeah list of Char is bad for performance |
| 21:10:16 | <monochrom> | And I refuse the current ambiguous wording "buffering". You are conflating I/O buffers with keeping the whole string in memory. |
| 21:10:22 | <EvanR> | advent of code only uses ASCII text input so ByteString would also work |
| 21:11:27 | <hexology> | monochrom: you're right, i should have been clearer. when i said "buffer" i meant an I/O buffer |
| 21:12:17 | <hexology> | and that example above does help clarify |
| 21:12:21 | <EvanR> | if you use ByteString then you will be working with an array of bytes, mapping more closely to what you were "hoping" for |
| 21:12:27 | <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. |
| 21:13:15 | <EvanR> | list nodes and Char itself take up quite a bit more space and time than array of bytes |
| 21:13:50 | <EvanR> | because lisp machines didn't win! |
| 21:14:17 | <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 |
| 21:14:25 | <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. |
| 21:15:02 | × | _ht quits (~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Remote host closed the connection) |
| 21:15:07 | <hexology> | also a good point monochrom |
| 21:15:10 | <EvanR> | where "small" has been steadily increasing in size over time xD |
| 21:15:27 | <monochrom> | If I need to create an array whose size depends on the number of lines, I would create a growable array instead. |
| 21:15:29 | <EvanR> | it's only a 1 meg file? load it all into memory for some reason xD |
| 21:15:30 | <dminuoso_> | I was always under the assumption that "buffering" isnt as much ambiguous, as it is just plainly misused. |
| 21:15:57 | <dminuoso_> | Buffers are a tool for matching two I/O that may, potentially, operate at different speeds. |
| 21:16:13 | <monochrom> | Either that, or pre-scan the file (but don't store) for number of lines, then rewind and read for real. |
| 21:16:15 | <dminuoso_> | It's not a means for "streaming", its rather a solution to avoid data loss. |
| 21:19:29 | <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]". |
| 21:19:35 | → | duncan joins (~duncan@user/duncan) |
| 21:19:56 | × | foul_owl quits (~kerry@174-21-66-189.tukw.qwest.net) (Ping timeout: 245 seconds) |
| 21:20:29 | <hexology> | monochrom: i would hope that's not unpopular! |
| 21:20:36 | <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. |
| 21:20:50 | <EvanR> | yeah the main point of this discussion would apply to String, Text, and ByteString |
| 21:21:09 | <EvanR> | laziness in the face of needing the know the lengths |
| 21:21:15 | <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. |
| 21:21:24 | <monochrom> | And in fact becomes completely distracting. |
| 21:25:47 | × | duncan quits (~duncan@user/duncan) (Quit: ZNC 1.8.2 - https://znc.in) |
| 21:26:57 | → | duncan joins (~duncan@user/duncan) |
| 21:27:41 | <hc> | Exponential time? Not just quadratic? |
| 21:28:18 | <hc> | I'd expect many naive string handling algorithms to be polynomial, but not exponential |
| 21:29:48 | × | target_i quits (~target_i@217.175.14.39) (Quit: leaving) |
| 21:31:36 | × | emmanuelux_ quits (~emmanuelu@user/emmanuelux) (Read error: Connection reset by peer) |
| 21:32:31 | <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. |
| 21:32:40 | → | emmanuelux_ joins (~emmanuelu@user/emmanuelux) |
| 21:33:14 | → | foul_owl joins (~kerry@157.97.134.168) |
| 21:34:14 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 21:34:28 | × | emmanuelux_ quits (~emmanuelu@user/emmanuelux) (Max SendQ exceeded) |
| 21:35:30 | → | emmanuelux_ joins (~emmanuelu@user/emmanuelux) |
| 21:36:02 | → | not_reserved joins (~not_reser@45.88.222.248) |
| 21:38:05 | <newsham> | you could claim that all your programs run on a finite state machine, but it wouldnt be very useful or insightful. |
| 21:40:12 | <haskellbridge> | 12<Celestial> 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? |
| 21:40:13 | <haskellbridge> | 12<Celestial> Is that "safe", as swap still needs to take and put again, leaving a short window where it's empty? |
| 21:40:31 | <haskellbridge> | 12<Celestial> I suppose the later isn't a concern if you only allow the blocking operations that wait |
| 21:40:56 | <haskellbridge> | 12<Celestial> s/doesn't neither/neither |
| 21:41:04 | <monochrom> | I would consider STM and its TVar instead. |
| 21:41:43 | <monochrom> | But if you stick to readMVar and writeMVar you get the always-non-empty semantics. |
| 21:42:50 | <haskellbridge> | 12<Celestial> hm I see I think I do want the TVar instead |
| 21:42:59 | <haskellbridge> | 12<Celestial> I need to read up on the STM monad |
| 21:43:02 | <EvanR> | IORef xD |
| 21:43:10 | <EvanR> | atomicModifyIORef' |
| 21:43:35 | <monochrom> | Yeah I actually use that :) |
| 21:43:49 | <EvanR> | TVars are good when you actually want transactions |
| 21:43:58 | <EvanR> | more complicated than just changing the value |
| 21:44:11 | <haskellbridge> | 12<Celestial> 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? |
| 21:44:18 | <EvanR> | atomically |
| 21:44:37 | <monochrom> | If it is not "two or more variables entangled by an invariant" then atomicModifyIORef' suffices. |
| 21:44:43 | → | alexherbo2 joins (~alexherbo@2a02-8440-3140-cd78-e0d9-a0e2-1a64-1fd2.rev.sfr.net) |
| 21:45:25 | × | fendor quits (~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c) (Remote host closed the connection) |
| 21:46:52 | → | pavonia joins (~user@user/siracusa) |
| 21:47:34 | × | aruns quits (~aruns@user/aruns) (Ping timeout: 246 seconds) |
| 21:48:12 | × | duncan quits (~duncan@user/duncan) (Read error: Connection reset by peer) |
| 21:49:00 | → | duncan joins (~duncan@user/duncan) |
| 21:52:11 | × | anderson quits (~anderson@user/anderson) (Quit: bye) |
| 21:53:59 | → | anderson joins (~anderson@user/anderson) |
| 21:54:11 | × | duncan quits (~duncan@user/duncan) (Quit: ZNC 1.8.2 - https://znc.in) |
| 21:57:51 | × | takuan quits (~takuan@178-116-218-225.access.telenet.be) (Ping timeout: 256 seconds) |
| 21:59:42 | <EvanR> | *do you guys just put "quantum" in front of everything* |
| 21:59:48 | → | machinedgod joins (~machinedg@93-136-52-133.adsl.net.t-com.hr) |
| 22:00:19 | → | duncan joins (~duncan@user/duncan) |
| 22:04:35 | <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') |
| 22:04:39 | <ski> | hexology : sometimes i define `pam = flip map' |
| 22:04:43 | <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 |
| 22:05:22 | <jackdk> | > :t Data.Functor.(<&>) |
| 22:05:23 | <lambdabot> | <hint>:1:1: error: parse error on input ‘:’ |
| 22:05:32 | <jackdk> | % :t Data.Functor.(<&>) |
| 22:05:32 | <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... |
| 22:05:35 | <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 |
| 22:05:52 | <ski> | % :t (Data.Functor.<&>) |
| 22:05:52 | <yahb2> | *** Parser [source]: ; !!! Parser [source]: finished in 0.08 milliseconds, allocated 0.030 megabytes ; (Data.Functor.<&>) :: Functor f => f a -> (a -> b) -> f b |
| 22:05:57 | <jackdk> | anyway : (<&>) :: Functor f => f a -> (a -> b) -> f b |
| 22:06:07 | <ski> | % :q |
| 22:06:07 | <yahb2> | <bye> |
| 22:06:09 | <ski> | % :t (Data.Functor.<&>) |
| 22:06:09 | <yahb2> | (Data.Functor.<&>) :: Functor f => f a -> (a -> b) -> f b |
| 22:06:23 | <haskellbridge> | 12<Celestial> ski: Thank you! |
| 22:06:35 | <ski> | Celestial : see what EvanR and monochrom said |
| 22:09:39 | <haskellbridge> | 12<Celestial> Okay I think I understand |
| 22:09:50 | <haskellbridge> | 12<Celestial> still new to concurrency with haskell |
| 22:09:58 | <haskellbridge> | 12<Celestial> so thank you for the help everyone+ |
| 22:12:44 | <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)' |
| 22:12:51 | <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) |
| 22:19:11 | <EvanR> | =< ? |
| 22:19:15 | <EvanR> | :t (=<) |
| 22:19:16 | <lambdabot> | error: |
| 22:19:16 | <lambdabot> | • Variable not in scope: =< |
| 22:19:16 | <lambdabot> | • Perhaps you meant one of these: |
| 22:19:21 | <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") |
| 22:19:57 | <ski> | (for math, i prefer `<',`=<',`>=',`>' (as Prolog and Erlang does it), preferring `<=' as leftwards implication) |
| 22:20:20 | <ski> | @let data Word2 = W0 | W1 | W2 | W3 deriving (Read,Show,Eq,Ord,Enum,Bounded,Ix) |
| 22:20:21 | <lambdabot> | Defined. |
| 22:20:24 | <ski> | > [i | i <- [minBound .. maxBound],W1 <= i,i <= W2] |
| 22:20:26 | <lambdabot> | [W1,W2] |
| 22:20:31 | <ski> | > [i | i <- [minBound .. maxBound],inRange (W1,W2) i] |
| 22:20:32 | <lambdabot> | [W1,W2] |
| 22:20:37 | <ski> | > [i | i <- range (W1,W2)] |
| 22:20:41 | <lambdabot> | [W1,W2] |
| 22:20:46 | <ski> | > [(i,j) | [i,j] <- replicateM 2 [minBound .. maxBound],(W1,W1) <= (i,j),(i,j) <= (W2,W2)] |
| 22:20:47 | <lambdabot> | [(W1,W1),(W1,W2),(W1,W3),(W2,W0),(W2,W1),(W2,W2)] |
| 22:20:55 | <ski> | > [(i,j) | [i,j] <- replicateM 2 [minBound .. maxBound],inRange ((W1,W1),(W2,W2)) (i,j)] |
| 22:20:57 | <lambdabot> | [(W1,W1),(W1,W2),(W2,W1),(W2,W2)] |
| 22:21:01 | → | Sgeo joins (~Sgeo@user/sgeo) |
| 22:21:02 | <ski> | > [(i,j) | (i,j) <- range ((W1,W1),(W2,W2))] |
| 22:21:03 | <lambdabot> | [(W1,W1),(W1,W2),(W2,W1),(W2,W2)] |
| 22:21:50 | <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 |
| 22:23:05 | <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 |
| 22:23:56 | × | puke quits (~puke@user/puke) (Quit: puke) |
| 22:26:57 | <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 |
| 22:26:57 | <cheater> | ski: yes |
| 22:27:06 | <cheater> | ski: do they exist? |
| 22:27:21 | <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 |
| 22:29:40 | <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 |
| 22:29:46 | <ski> | "synchronized" indexing for both parts there) |
| 22:29:50 | × | __monty__ quits (~toonn@user/toonn) (Quit: leaving) |
| 22:30:08 | → | [_] joins (~itchyjunk@user/itchyjunk/x-7353470) |
| 22:31:11 | → | Volt_ joins (~Volt_@c-73-47-181-152.hsd1.ma.comcast.net) |
| 22:32:49 | → | puke joins (~puke@user/puke) |
| 22:33:16 | × | waleee quits (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 245 seconds) |
| 22:33:41 | × | [itchyjunk] quits (~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 245 seconds) |
| 22:39:23 | × | newsham quits (~newsham@2603-800c-2c01-6825-857b-69b9-29f4-97e6.res6.spectrum.com) (Quit: Client closed) |
| 22:40:24 | → | waleee joins (~waleee@176.10.144.38) |
| 22:43:13 | <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) |
| 22:43:23 | <cheater> | thanks |
| 22:44:29 | <ski> | as mentioned above by tromp,dminuoso_, it's also been considered for GHC |
| 22:46:02 | <ski> | (i think i wrote that OCaml (and Prolog) example, on that RosettaCode page, years ago) |
| 22:47:52 | × | EvanR quits (~EvanR@user/evanr) (Quit: Leaving) |
| 22:49:04 | <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 |
| 22:49:11 | → | EvanR joins (~EvanR@user/evanr) |
| 23:04:01 | <jackdk> | I don't know about cabal but I believe that the linker must be invoked with all the necessary `-l` arguments. So I would expect a tool like cabal to have to propagate them to whatever ends up actually calling the linker |
| 23:04:17 | × | urdh quits (~urdh@user/urdh) (Ping timeout: 256 seconds) |
| 23:05:55 | → | aztex joins (~aztex@178.197.239.241) |
| 23:06:28 | <aztex> | Hey I have a Haskell project and I would like to trace the function calls that are made |
| 23:06:45 | <aztex> | could you point me to some documentation on this |
| 23:07:01 | <EvanR> | you can use Debug.Trace pretty easily to trace what expressions are evaluated |
| 23:07:22 | <aztex> | I am thinking about runtime tracing |
| 23:07:25 | <EvanR> | me too |
| 23:07:28 | <idgaen> | Hecate: debian shipped their haskell libraries with .a (and not .so) |
| 23:07:40 | <aztex> | where the programmer doesn't need to manually call "trace" |
| 23:08:05 | <aztex> | I think with Debug.Trace the programmer has to annotate the information that they are tracing |
| 23:08:23 | <EvanR> | yes it prints something out what a selected expression is evaluated |
| 23:08:24 | <aztex> | what I am wondering is whether the RTS has some information on the function calls being made |
| 23:08:27 | <EvanR> | when* |
| 23:08:40 | <aztex> | like some kind of profiling |
| 23:09:13 | <monochrom> | Well then you read the GHC User's Guide for its debugger. |
| 23:09:47 | × | gmg quits (~user@user/gehmehgeh) (Quit: Leaving) |
| 23:09:52 | <haskellbridge> | 12<Celestial> how is trace implemented? Is it just an `unsafePerformIO . putStrLn`? |
| 23:10:22 | <monochrom> | Yeah. In fact it calls a C function, so as not to disturb RTS's stdout and stderr. :) |
| 23:10:48 | <aztex> | https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Debug.Trace.html#trace |
| 23:10:58 | <EvanR> | unsafePerformIO . debugBelch xD |
| 23:13:23 | × | aztex quits (~aztex@178.197.239.241) (Quit: Client closed) |
| 23:14:27 | → | nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
| 23:16:16 | <idgaen> | Oh! I'm wrong, in debian there is also .so files. |
| 23:17:59 | → | bitdex joins (~bitdex@gateway/tor-sasl/bitdex) |
| 23:18:22 | × | acidjnk_new quits (~acidjnk@p200300d6e72b93299103c78233b0ca81.dip0.t-ipconnect.de) (Ping timeout: 256 seconds) |
| 23:19:28 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 23:19:58 | × | nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 255 seconds) |
| 23:21:09 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:d128:ce35:54e1:65e2) (Remote host closed the connection) |
| 23:24:54 | × | peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Quit: peterbecich) |
| 23:25:12 | × | idgaen quits (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1) |
| 23:25:34 | → | peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com) |
| 23:27:34 | <tri> | hi folks, * -> * is considered a higher-kinded type right? And iirc, it's called first-order type |
| 23:27:53 | <dibblego> | it's the notation of the type of a higher-kinded type |
| 23:29:08 | <tri> | so Person a = Person a is a higher kinded type |
| 23:29:40 | <tri> | so then, F# and C# do have HKT with generic, just that they stop at the first-order type |
| 23:30:22 | <dibblego> | No. |
| 23:30:30 | <dibblego> | the type of Person is * -> * |
| 23:30:41 | <dibblego> | also called "the kind of Person" |
| 23:30:54 | <dibblego> | the kind of Maybe is * -> * |
| 23:31:02 | <dibblego> | you could find this out in ghci with :kind Maybe |
| 23:31:28 | <tri> | right, but didn't you just said it's the notation of the type of a HKT? |
| 23:31:30 | <geekosaur> | a higher-kinded type is something like `data Foo f = Foo (f Int)`, which means `f` has kind * -> * |
| 23:31:49 | <dibblego> | yes, * -> * will be the result, it is notating the kind of Maybe back to you |
| 23:32:22 | <dibblego> | here is another example: https://i.imgur.com/I0XFRWf.png |
| 23:33:37 | <tri> | dibblego: i understand the kind of Maybe and Person is * -> * |
| 23:33:47 | <tri> | but isn't * -> * HKT? |
| 23:34:33 | <dibblego> | not exactly, since I could say, write the Maybe type in C#, and it would have that kind, but that is not to say C# permits HKT |
| 23:34:37 | <tri> | geekosaur: sorry that just went over my head |
| 23:35:01 | <dibblego> | @type \a b -> const a <$> b |
| 23:35:02 | <lambdabot> | Functor f => b1 -> f b2 -> f b1 |
| 23:35:10 | <tri> | geekosaur: i understand your example, but at the same time kinda confused as i have never seen it before |
| 23:35:10 | <dibblego> | I cannot write the type of this function in C# |
| 23:35:10 | → | [itchyjunk] joins (~itchyjunk@user/itchyjunk/x-7353470) |
| 23:35:14 | <dibblego> | it does not have HKT |
| 23:37:26 | × | peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 245 seconds) |
| 23:38:13 | <tri> | dibblego: yea that example just went over my head. I know const drop the second argument and return the first one. But you applied 3 args there, and the fact that you used fmap as a second arg just blew my mind |
| 23:38:34 | <tri> | welp, i will just re-read HKT again |
| 23:38:46 | × | [_] quits (~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 256 seconds) |
| 23:38:52 | <dibblego> | I don't have a C# compiler handy, but what is the type of this expression? (a, b) => from _ <- b; select a; |
| 23:39:10 | × | alexherbo2 quits (~alexherbo@2a02-8440-3140-cd78-e0d9-a0e2-1a64-1fd2.rev.sfr.net) (Ping timeout: 250 seconds) |
| 23:39:45 | <tri> | i dont think from _ <-b is a valid c# syntax, what are you trying to do there? |
| 23:39:55 | <dibblego> | yeah it is |
| 23:40:06 | <dibblego> | (a, b) => b.Select(_ => a); |
| 23:40:07 | <tri> | is that linq? i never use linq sql like that |
| 23:40:09 | <dibblego> | same thing ^^ |
| 23:40:09 | <tri> | oh ok |
| 23:40:21 | <dibblego> | what is its type? |
| 23:40:23 | <tri> | yea sorry never write linq that way in my life, ok let me read that again |
| 23:40:45 | <tri> | so b must be an IEnumerable |
| 23:40:50 | <dibblego> | must it? |
| 23:40:55 | <tri> | cuz of Select |
| 23:41:05 | <tri> | and a could be anythign |
| 23:41:08 | <dibblego> | what about the other things that have Select, but are not IEnumerable? |
| 23:41:25 | <tri> | hm idk off the top of my head |
| 23:41:36 | <dibblego> | well, is it the type of those things as well? |
| 23:41:37 | <tri> | oh |
| 23:41:48 | <dibblego> | I know quite a few things that have Select, but are not IEnumerable |
| 23:41:51 | <tri> | IQueryable |
| 23:41:54 | <dibblego> | can it be those as well? |
| 23:42:30 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:d128:ce35:54e1:65e2) |
| 23:42:31 | <tri> | ok so your point is, b and a could be many things |
| 23:42:38 | <dibblego> | yes, but not just anything |
| 23:42:48 | <tri> | b is limited to interfaces/classes that have select |
| 23:42:50 | <dibblego> | more specifically, "b can be anything that as Select" |
| 23:42:53 | <dibblego> | right |
| 23:42:55 | <tri> | while a could be anything |
| 23:42:56 | <dibblego> | now write that interface |
| 23:43:02 | <dibblego> | you will need HKT to do this |
| 23:43:16 | <dibblego> | did you do it with C# ? |
| 23:43:22 | × | Tuplanolla quits (~Tuplanoll@91-159-68-236.elisa-laajakaista.fi) (Ping timeout: 255 seconds) |
| 23:43:43 | <tri> | no i didn't but i guess it would not let me |
| 23:43:56 | <tri> | but if i were to write it in Haskell |
| 23:44:01 | <tri> | that could probably look like |
| 23:44:02 | <dibblego> | it might, if C# had HKT |
| 23:44:09 | <dibblego> | we could try... |
| 23:44:34 | <tri> | Selectable b => a -> b -> a |
| 23:44:46 | <dibblego> | that's not quite right is it |
| 23:44:51 | <dibblego> | also, you need to write Selectable |
| 23:45:08 | <tri> | yea the return is not right, since b is of a "collection" tyope |
| 23:45:21 | <dibblego> | here is an invented of C#, with a slight change |
| 23:45:39 | <dibblego> | Selectable<F<_>> => a -> F<b> -> F<a> |
| 23:45:55 | <dibblego> | this is not real syntax of course |
| 23:46:05 | <dibblego> | it's maybe what it might look like, if C# had HKT |
| 23:46:18 | <dibblego> | Selectable exists in Haskell, because Haskell has HKT |
| 23:46:21 | × | coot quits (~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot) |
| 23:46:22 | <dibblego> | its name is different though |
| 23:46:26 | <dibblego> | it's called Functor instead |
| 23:46:34 | <dibblego> | @type \a b -> const a <$> b |
| 23:46:35 | <lambdabot> | Functor f => b1 -> f b2 -> f b1 |
| 23:46:54 | <tri> | oh i remember someone said that * -> * -> * is like generics of T<A,B>, which .NET can support |
| 23:47:10 | <dibblego> | * -> * -> * is notation for the type of T |
| 23:47:17 | <tri> | but .NET can't support (* -> *) -> * which is T<A<B>>, which is what you just did right |
| 23:47:24 | <tri> | im just parroting what i remember |
| 23:47:28 | <dibblego> | but we cannot use anything with that type, unless it is fully applied, because C# (and F#) do not have HKT |
| 23:47:55 | <dibblego> | "IEnumerable" has a type, and that type is, "given a type, return a type" |
| 23:48:07 | <tri> | yea that's generic, *->* |
| 23:48:09 | <dibblego> | but we cannot use that thing, we cannot express it |
| 23:48:21 | <glguy> | tri: assuming A takes one type parameter, (* -> *) -> * would be like: T<A> where A's types are not provided |
| 23:48:28 | <dibblego> | more practically, we cannot write this type: |
| 23:48:29 | <dibblego> | @type \a b -> const a <$> b |
| 23:48:30 | <lambdabot> | Functor f => b1 -> f b2 -> f b1 |
| 23:49:14 | <glguy> | type T c = (c Int, c Bool) -- like if you wanted to T to be parameterized by a container type and then use that container to contain two different kinds of elements |
| 23:49:40 | <tri> | I still can't wrap my head over const a <$> b. I always think that const only take 2 args. 3 args there throws me off |
| 23:50:20 | <glguy> | <$> isn't an argument to const |
| 23:50:33 | <dibblego> | @type \a b -> fmap (const a) b -- same thing |
| 23:50:34 | <lambdabot> | Functor f => b1 -> f b2 -> f b1 |
| 23:51:01 | <tri> | oh ok, i need some time to read these again |
| 23:52:57 | <tri> | @kind \a b -> const a <$> b |
| 23:52:58 | <lambdabot> | error: parse error on input ‘\’ |
| 23:53:48 | <glguy> | @type \a b -> const a <$> b |
| 23:53:49 | <lambdabot> | Functor f => b1 -> f b2 -> f b1 |
| 23:55:20 | <probie> | > const (*2) (+1) 5 -- Although, `const` can have "3 args", depending on how you count arguments |
| 23:55:21 | <lambdabot> | 10 |
| 23:56:13 | <tri> | ok............ |
| 23:56:23 | <tri> | i gotta re-read HKT |
| 23:56:39 | <tri> | thank you everyone |
| 23:58:33 | <EvanR> | const takes 1 args |
| 23:58:50 | <tri> | btw thanks probie and EvnR |
All times are in UTC on 2023-12-10.