2023/12/02

2023-12-02 00:00:00 +0100mjs2600(~mjs2600@c-174-169-225-239.hsd1.vt.comcast.net)
2023-12-02 00:00:31 +0100coot(~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
2023-12-02 00:00:46 +0100alp_(~alp@2001:861:e3d6:8f80:35c2:e097:c95:5680) (Ping timeout: 276 seconds)
2023-12-02 00:02:50 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-02 00:03:57 +0100Inst(~Inst@120.244.192.187)
2023-12-02 00:06:06 +0100not_reserved(~not_reser@185.205.247.233) (Quit: Client closed)
2023-12-02 00:07:30 +0100iqubic(~avi@2601:602:9502:c70:f5b9:3022:a2d7:d3ca)
2023-12-02 00:08:49 +0100seydar(~seydar@38-73-249-43.starry-inc.net) (Quit: leaving)
2023-12-02 00:11:32 +0100gmg(~user@user/gehmehgeh) (Quit: Leaving)
2023-12-02 00:12:06 +0100wroathe(~wroathe@50.205.197.50)
2023-12-02 00:12:06 +0100wroathe(~wroathe@50.205.197.50) (Changing host)
2023-12-02 00:12:06 +0100wroathe(~wroathe@user/wroathe)
2023-12-02 00:13:12 +0100 <wroathe> Hey guys, have any of you had any success getting useful statistics out of massif with a Haskell program?
2023-12-02 00:13:45 +0100 <wroathe> It seems to just only catch the initial RTS allocation on the main thread and only recognize that for the rest of the program
2023-12-02 00:13:58 +0100 <wroathe> threaded or no
2023-12-02 00:14:01 +0100szkl(uid110435@id-110435.uxbridge.irccloud.com) (Quit: Connection closed for inactivity)
2023-12-02 00:15:38 +0100JeremyB99(~JeremyB99@2607:fb91:17ea:fe4:458d:4dfa:7aa1:135b) (Ping timeout: 268 seconds)
2023-12-02 00:16:57 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 00:17:05 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 00:19:37 +0100nckx(~nckx@libera/staff/owl/nckx) (Ping timeout: 276 seconds)
2023-12-02 00:19:39 +0100 <wroathe> The situation is that I've got a program that attempts to read N directories full of 4 text files in parallel and each async task processing a directory iterates through the characters of the file and attempts to make some corrections to the contents that it builds up in a ByteString Builder, and then I use the `writeFile` function to try and write the new contents back to the original file. Every time I
2023-12-02 00:19:45 +0100 <wroathe> add a new file it seems to increase the total lifetime allocations of my program by like 3GB according to the GHC profiler, but what I really want is to understand how the resident heap size changes over time, and what the peak is
2023-12-02 00:20:03 +0100 <wroathe> The text files themselves range from like 2kb to 40MB, so an increase to 3GB of allocations is insane
2023-12-02 00:22:22 +0100seydar(~seydar@38-73-249-43.starry-inc.net)
2023-12-02 00:22:44 +0100 <seydar> I am so close: `liftM read $ sequence [Just '1', Just '2'] :: Maybe Int`
2023-12-02 00:23:11 +0100 <seydar> oh wait that worked?
2023-12-02 00:23:19 +0100 <seydar> i've been duped by my own lying eyes
2023-12-02 00:23:26 +0100 <EvanR> > liftM read $ sequence [Just '1', Just '2'] :: Maybe Int
2023-12-02 00:23:27 +0100 <lambdabot> Just 12
2023-12-02 00:23:51 +0100 <EvanR> didn't think of that xD
2023-12-02 00:24:06 +0100 <EvanR> also
2023-12-02 00:24:15 +0100 <EvanR> > read <$> sequence [Just '1', Just '2'] :: Maybe Int
2023-12-02 00:24:17 +0100 <lambdabot> Just 12
2023-12-02 00:24:52 +0100 <seydar> I couldn't figure out how to use <$> so instead of googling i chose to cry
2023-12-02 00:25:11 +0100 <ski> > readMaybe =<< sequence [Just '1',Just '2'] :: Maybe Int
2023-12-02 00:25:12 +0100 <lambdabot> Just 12
2023-12-02 00:25:33 +0100 <ski> (better to not use `read', unless you're sure there'll be no parse error)
2023-12-02 00:26:13 +0100 <ski> (and if you're reading many things in succession, you could try using `reads')
2023-12-02 00:26:56 +0100 <monochrom> <$> is infix notation for fmap. Do you know how to use fmap?
2023-12-02 00:27:14 +0100 <seydar> monochrom: last year i did, but it's drifting from memory
2023-12-02 00:27:21 +0100 <EvanR> liftM = fmap, basically
2023-12-02 00:27:24 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 00:27:26 +0100 <lambdabot> [([0,12,345,6789],"")]
2023-12-02 00:27:29 +0100 <ski> > many (StateT (reads :: ReadS Int)) `runStateT` "0 12 345 6789"
2023-12-02 00:27:30 +0100 <lambdabot> [([0,12,345,6789],""),([0,12,345]," 6789"),([0,12]," 345 6789"),([0]," 12 34...
2023-12-02 00:27:31 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 00:28:09 +0100 <EvanR> if you like many ways to do it, liftM = fmap = <$>. If you like there's only one way to do it, there's fmap
2023-12-02 00:28:24 +0100 <ski> (then you could, at top-level, filter away solutions that doesn't have empty rest string)
2023-12-02 00:28:26 +0100shapr(~user@2600:1700:c640:3100:fae0:3c5e:6b1c:b298) (Remote host closed the connection)
2023-12-02 00:28:40 +0100shapr(~user@2600:1700:c640:3100:d14f:9e1a:e23d:bb91)
2023-12-02 00:29:28 +0100 <seydar> thanks!
2023-12-02 00:29:34 +0100seydar(~seydar@38-73-249-43.starry-inc.net) (Quit: leaving)
2023-12-02 00:29:58 +0100 <ski> (you can also use list comprehensions, instead of `fmap'/`liftM'/`(<$>)', or `(=<<)'/`concatMap')
2023-12-02 00:31:57 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470)
2023-12-02 00:35:47 +0100idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1)
2023-12-02 00:37:55 +0100acidjnk(~acidjnk@p200300d6e72b9330102e9afa1ce5f091.dip0.t-ipconnect.de) (Ping timeout: 256 seconds)
2023-12-02 00:44:21 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com)
2023-12-02 00:51:26 +0100caryhartline(~caryhartl@168.182.58.169) (Quit: caryhartline)
2023-12-02 00:51:35 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 264 seconds)
2023-12-02 00:51:47 +0100nckx(~nckx@libera/staff/owl/nckx)
2023-12-02 00:52:07 +0100 <wroathe> cabal install eventlog2html... 2 hours later
2023-12-02 00:54:35 +0100cstml(~cstml@user/cstml) (Ping timeout: 264 seconds)
2023-12-02 00:55:09 +0100 <wroathe> I could kiss mpickering. Finally a heap visualizer that doesn't suck
2023-12-02 00:59:28 +0100wroathe(~wroathe@user/wroathe) (Ping timeout: 255 seconds)
2023-12-02 01:03:59 +0100Tuplanolla(~Tuplanoll@91-159-68-236.elisa-laajakaista.fi) (Ping timeout: 256 seconds)
2023-12-02 01:12:15 +0100Guest69(~Guest69@akh16.neoplus.adsl.tpnet.pl)
2023-12-02 01:13:20 +0100cstml(~cstml@user/cstml)
2023-12-02 01:14:38 +0100johnw(~johnw@69.62.242.138) (Quit: ZNC - http://znc.in)
2023-12-02 01:14:44 +0100zetef(~quassel@2a02:2f00:5201:4b00:7fc8:6fbe:33d9:ba2a) (Remote host closed the connection)
2023-12-02 01:24:16 +0100pandry(~Pandry@93-41-34-64.ip79.fastwebnet.it)
2023-12-02 01:26:20 +0100szkl(uid110435@id-110435.uxbridge.irccloud.com)
2023-12-02 01:30:15 +0100jargon(~jargon@184.101.176.143)
2023-12-02 01:31:47 +0100cstml(~cstml@user/cstml) (Ping timeout: 264 seconds)
2023-12-02 01:33:35 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com)
2023-12-02 01:34:00 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 01:36:49 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com)
2023-12-02 01:36:49 +0100wroathe(~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host)
2023-12-02 01:36:49 +0100wroathe(~wroathe@user/wroathe)
2023-12-02 01:36:51 +0100peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com) (Client Quit)
2023-12-02 01:37:40 +0100notzmv(~zmv@user/notzmv)
2023-12-02 01:37:47 +0100pandry(~Pandry@93-41-34-64.ip79.fastwebnet.it) (Ping timeout: 264 seconds)
2023-12-02 01:39:58 +0100bilegeek(~bilegeek@2600:1008:b056:35d:76c2:a006:21b1:7eff)
2023-12-02 01:42:54 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 01:43:13 +0100bienjensu(~user@user/bienjensu) (Ping timeout: 256 seconds)
2023-12-02 01:50:38 +0100 <hippoid> i'm trying to write a parser for part2 of AOC. https://termbin.com/okik , when I run it with `parseOnly parseLine "onetwo1three" it just never stops. can i get a hint on how to fix it?
2023-12-02 01:52:38 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 02:04:33 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 02:05:40 +0100acidjnk(~acidjnk@p200300d6e72b9330e8b605edba9a1bca.dip0.t-ipconnect.de)
2023-12-02 02:07:13 +0100 <pavonia> hippoid: Think about what happens when you run the parser on an empty string
2023-12-02 02:12:07 +0100iqubic(~avi@2601:602:9502:c70:f5b9:3022:a2d7:d3ca) (Remote host closed the connection)
2023-12-02 02:12:23 +0100iqubic(~avi@2601:602:9502:c70:f5b9:3022:a2d7:d3ca)
2023-12-02 02:16:37 +0100sawilagar(~sawilagar@user/sawilagar) (Ping timeout: 276 seconds)
2023-12-02 02:27:03 +0100 <hippoid> pavonia: improved working version: https://termbin.com/tgbg. your tip and a bunch of unit testing helped me figure it out
2023-12-02 02:35:22 +0100 <pavonia> The getNumbers function is a bit hard to read. Maybe just use catMaybes on the result?
2023-12-02 02:35:31 +0100 <pavonia> :t catMaybes
2023-12-02 02:35:32 +0100 <lambdabot> [Maybe a] -> [a]
2023-12-02 02:36:16 +0100sh1n(~sh1n@2800:21e5:c000:9f1::db48)
2023-12-02 02:38:07 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5)
2023-12-02 02:38:24 +0100mikess(~sam@user/mikess) (Quit: Lost terminal)
2023-12-02 02:39:17 +0100mvk(~mvk@2607:fea8:5c9a:a600::cbc7)
2023-12-02 02:39:31 +0100mvk(~mvk@2607:fea8:5c9a:a600::cbc7) (Client Quit)
2023-12-02 02:39:55 +0100 <glguy> hippoid: instead of <|> string "three"... and then casing on the output at the end
2023-12-02 02:39:55 +0100ridcully(~ridcully@p57b52dae.dip0.t-ipconnect.de) (Ping timeout: 255 seconds)
2023-12-02 02:40:05 +0100 <glguy> hippoid: try this: 3 <$ string "three"
2023-12-02 02:40:28 +0100 <glguy> <$ and <|> mix nicely
2023-12-02 02:41:45 +0100 <glguy> also while it's good to learn how to use attoparsec like this, this ends up not working for part 2 the way you're doing it
2023-12-02 02:42:21 +0100 <hippoid> glguy: yeah, i just submitted my answer for part 2 and was sadface'd at seeing i got the wrong answer
2023-12-02 02:42:34 +0100 <hippoid> havent yet figured out why my approach is wrong
2023-12-02 02:46:12 +0100 <glguy> If you're not already aware, we have a leaderboard code in the channel topic. It can be a good way to find other solutions to compare to when you finish one
2023-12-02 02:47:53 +0100 <glguy> I can give you a hint if you want, or can just let you work on it
2023-12-02 02:49:11 +0100 <EvanR> hippoid, you're not alone (getting part 2 wrong despite your logic being "infallible") xD
2023-12-02 02:49:22 +0100 <hippoid> AoC 43100-84040706 -- is that the leaderboard? what do i do with that?
2023-12-02 02:49:26 +0100 <EvanR> I hope day 2+ keeps this up
2023-12-02 02:49:55 +0100 <hippoid> EvanR: hmmm
2023-12-02 02:49:58 +0100 <glguy> There's a place to put that code if you click on leaderboard private leaderboard
2023-12-02 02:51:46 +0100thegeekinside(~thegeekin@189.141.65.247) (Ping timeout: 260 seconds)
2023-12-02 02:52:23 +0100 <hippoid> glguy: i still dont get it. click on "leaderboard private leaderboard" ... where do i click on that?
2023-12-02 02:52:54 +0100 <glguy> https://adventofcode.com/2023/leaderboard/private
2023-12-02 02:53:01 +0100 <glguy> On the website
2023-12-02 02:53:10 +0100 <hippoid> ahh
2023-12-02 02:58:20 +0100 <EvanR> almost time for day 2 of "write it in haskell real fast then spend the whole next day trying to do the same thing in some other language which may or may not support it"
2023-12-02 02:59:49 +0100ridcully(~ridcully@p508acfd3.dip0.t-ipconnect.de)
2023-12-02 03:03:37 +0100 <iqubic> Is there a good way to check what version of Base I'm using in a given project?
2023-12-02 03:04:12 +0100 <iqubic> Namely, I want to figure out why Cabal is unable to import Data.Foldable1 from base.
2023-12-02 03:04:51 +0100 <geekosaur> the quickest ways are to check in ghcup list / ghcup tui for your ghc version, or `ghc-pkg-version list base`
2023-12-02 03:05:36 +0100 <iqubic> I'm using Nix to manage this, because I'm fancy.
2023-12-02 03:06:37 +0100 <hippoid> ok, if anyone wants to give me a hint for why my logic is i'll take it :>
2023-12-02 03:07:11 +0100 <glguy> msg'd
2023-12-02 03:07:44 +0100 <iqubic> base-4.16.4.0
2023-12-02 03:08:05 +0100 <geekosaur> Data.Foldable1 haddock says Since 4.18.0.0
2023-12-02 03:08:11 +0100 <iqubic> I know that.
2023-12-02 03:08:16 +0100johnw(~johnw@69.62.242.138)
2023-12-02 03:08:40 +0100 <iqubic> Can I specify a later base version in my Cabal file?
2023-12-02 03:09:00 +0100 <geekosaur> (I would have expected you to be able to open a nix-shell and then use `ghc-pkg list base`)
2023-12-02 03:09:21 +0100 <geekosaur> no, you need to specify a newer ghc version somewhere, probably your Nix derivation
2023-12-02 03:09:30 +0100johnw(~johnw@69.62.242.138) (Client Quit)
2023-12-02 03:09:55 +0100 <iqubic> geekosaur: I didn't know that command existed.
2023-12-02 03:10:15 +0100 <geekosaur> uh, I think you need to learn more about nix before messing with it
2023-12-02 03:10:17 +0100 <exarkun> ghc-pkg can't see nix-supplied haskell packages, though.
2023-12-02 03:10:24 +0100 <geekosaur> I know about that and I barely know nix
2023-12-02 03:10:42 +0100 <exarkun> iqubic: there are other ghc versions beneath pkgs.haskell.packages
2023-12-02 03:10:50 +0100 <exarkun> iqubic: with names like "ghc943"
2023-12-02 03:11:00 +0100 <iqubic> good to know
2023-12-02 03:15:33 +0100 <monochrom> For a newer base, select a newer GHC.
2023-12-02 03:16:27 +0100 <iqubic> Got it.
2023-12-02 03:17:17 +0100 <monochrom> As usual, you should also specify correct version bounds in *.cabal files. This will not cause automatic installation of GHC, but it blocks trying to build with wrong versions.
2023-12-02 03:18:08 +0100shapr(~user@2600:1700:c640:3100:d14f:9e1a:e23d:bb91) (Remote host closed the connection)
2023-12-02 03:18:21 +0100shapr(~user@2600:1700:c640:3100:a0ba:87d7:8ba1:c40)
2023-12-02 03:18:29 +0100xff0x(~xff0x@2405:6580:b080:900:2cef:72cf:22:b0de) (Ping timeout: 268 seconds)
2023-12-02 03:19:41 +0100mjs2600(~mjs2600@c-174-169-225-239.hsd1.vt.comcast.net) (Quit: ZNC 1.8.2 - https://znc.in)
2023-12-02 03:19:50 +0100xff0x(~xff0x@178.255.149.135)
2023-12-02 03:21:26 +0100mjs2600(~mjs2600@c-174-169-225-239.hsd1.vt.comcast.net)
2023-12-02 03:21:35 +0100 <iqubic> exarkun: do you know if there's a way I can get a list of all possible options? Perhaps with Nix Repl or something?
2023-12-02 03:21:37 +0100rosco(~rosco@175.136.158.171)
2023-12-02 03:25:17 +0100wroathe(~wroathe@user/wroathe) (Quit: Lost terminal)
2023-12-02 03:27:21 +0100myme(~myme@2a01:799:d60:e400:4086:b673:1073:656f) (Ping timeout: 256 seconds)
2023-12-02 03:27:34 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex)
2023-12-02 03:28:17 +0100myme(~myme@2a01:799:d60:e400:674:e335:7501:d41d)
2023-12-02 03:28:29 +0100iqubic(~avi@2601:602:9502:c70:f5b9:3022:a2d7:d3ca) (Ping timeout: 256 seconds)
2023-12-02 03:30:19 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 03:31:33 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 03:37:34 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 03:38:21 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 03:39:15 +0100chomwitt(~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1) (Ping timeout: 260 seconds)
2023-12-02 03:44:44 +0100iqubic(~avi@2601:602:9502:c70:4074:a07:97c8:fa87)
2023-12-02 03:47:42 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 03:48:03 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 03:51:17 +0100sh1n(~sh1n@2800:21e5:c000:9f1::db48) (Ping timeout: 256 seconds)
2023-12-02 03:53:11 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-02 03:55:02 +0100 <hippoid> i was too lazy to get rid of my parser after realizing my logic mistake, so i just parsed the line forwards and then backwards: https://termbin.com/mapf
2023-12-02 03:55:51 +0100 <hippoid> and by realizing my logic mistake, i mean glguy telling me what it was
2023-12-02 03:55:52 +0100xff0x(~xff0x@178.255.149.135) (Ping timeout: 255 seconds)
2023-12-02 03:56:11 +0100 <[Leary]> iqubic: nix eval --impure --expr 'with (import <nixpkgs> {}); lib.attrNames haskell.packages'
2023-12-02 03:57:36 +0100xff0x(~xff0x@2405:6580:b080:900:2cef:72cf:22:b0de)
2023-12-02 03:58:07 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 255 seconds)
2023-12-02 04:00:49 +0100ph88(~ph88@ip5b40e272.dynamic.kabel-deutschland.de) (Ping timeout: 255 seconds)
2023-12-02 04:01:12 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 04:02:56 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 04:04:03 +0100 <iqubic> Thank you!
2023-12-02 04:06:04 +0100andrea_(~andrea@159.196.202.200)
2023-12-02 04:06:36 +0100andrea_andreabedini
2023-12-02 04:07:43 +0100 <hippoid> iqubic: https://search.nixos.org/packages?query=ghc&channel=unstable
2023-12-02 04:08:02 +0100 <iqubic> thanks.
2023-12-02 04:08:25 +0100andreabedini(~andrea@159.196.202.200) (Client Quit)
2023-12-02 04:12:57 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 04:13:11 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 04:14:14 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e149:4c4f:e3f1:4f3e) (Remote host closed the connection)
2023-12-02 04:14:29 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e149:4c4f:e3f1:4f3e)
2023-12-02 04:17:08 +0100 <iqubic> the latest news section of haskell.org/ghc confuses me. 10 November 2023: GHC 9.4.8 Released! 9 October 2023: GHC 9.8.1 Released!
2023-12-02 04:17:52 +0100 <iqubic> Did they downgrade GHC or what? Why did the version number go down when the time goes forward?
2023-12-02 04:18:11 +0100 <geekosaur> because its' a point release of the older version with bug fixes
2023-12-02 04:18:33 +0100 <geekosaur> so the 9.4 series is now at 9.4.8 and the first 9.8 release is out
2023-12-02 04:19:17 +0100 <geekosaur> new versions often have enough changes that people with existing projects continue to use older ghc versions, but need bug fixes
2023-12-02 04:22:32 +0100 <geekosaur> in particular, iirc there was a critical GC bug fix in 9.4.8
2023-12-02 04:23:32 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 04:25:06 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 04:25:08 +0100 <geekosaur> it will probably be the last release of 9.4, as 9.10 will be frozen in early January and 9.4 will no longer be updated after 9.10 is released (but 9.6 and 9.8 will continue to get bug fixes)
2023-12-02 04:28:28 +0100edr(~edr@user/edr) (Quit: Leaving)
2023-12-02 04:39:33 +0100Xyloes(~wyx@2400:dd01:103a:1012:5923:33ce:7857:fc04)
2023-12-02 04:40:42 +0100 <hexology> i'm trying to setup ghcup, ghc, and hls, but i'm having what must be a PEBCAK issue. i created a discussion thread at https://github.com/haskell/haskell-language-server/discussions/3884 but maybe someone here happens to know what i did wrong
2023-12-02 04:41:36 +0100 <haskellbridge> 14<m​aerwald> what is the project you're using HLS with
2023-12-02 04:41:47 +0100 <haskellbridge> 14<m​aerwald> what is the editor
2023-12-02 04:41:53 +0100 <haskellbridge> 14<m​aerwald> how is hls invoked?
2023-12-02 04:41:59 +0100 <haskellbridge> 14<m​aerwald> what is the error
2023-12-02 04:43:07 +0100 <hexology> there's no project yet, i was going to do advent of code. i'm using the neovim built-in language server client. when that starts up, it says there's no ghc binary and asks me to manually enter the path. when i start haskell-language-server-wrapper from the command line, it starts but says "Failed to find executable "ghc" in $PATH for this Default project."
2023-12-02 04:43:30 +0100 <hexology> the hls docs suggested that i shouldn't need a config file, so i didn't create one
2023-12-02 04:43:48 +0100 <haskellbridge> 14<m​aerwald> so you're using HLS on a plain haskell file without a project?
2023-12-02 04:43:50 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 04:43:53 +0100 <hexology> correct
2023-12-02 04:44:08 +0100 <haskellbridge> 14<m​aerwald> run: `ghcup set ghc 9.4.7`
2023-12-02 04:44:09 +0100 <hexology> i can add project stuff later, but i didn't want to mess around with it right away
2023-12-02 04:44:56 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
2023-12-02 04:44:56 +0100finn_elija(~finn_elij@user/finn-elija/x-0085643)
2023-12-02 04:44:56 +0100finn_elijaFinnElija
2023-12-02 04:44:59 +0100 <hexology> perfect thank you, i actually did `ghcup set ghc recommended` and now there's `~/.ghcup/bin/ghc`
2023-12-02 04:45:04 +0100 <hexology> i must have missed that in the setup instructions
2023-12-02 04:45:17 +0100 <hexology> i didn't seem to need that command for hls, stack, or cabal
2023-12-02 04:45:28 +0100 <haskellbridge> 14<m​aerwald> that's by design
2023-12-02 04:45:35 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 04:45:45 +0100 <haskellbridge> 14<m​aerwald> `ghcup install ghc x.y.z` does not switch the default ghc binary
2023-12-02 04:45:53 +0100 <haskellbridge> 14<m​aerwald> for the other tools, it does
2023-12-02 04:46:05 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-02 04:46:19 +0100 <haskellbridge> 14<m​aerwald> because GHC is not backwards compatible, usually
2023-12-02 04:46:23 +0100 <hexology> makes sense
2023-12-02 04:46:25 +0100 <haskellbridge> 14<m​aerwald> a newer cabal binary usually is
2023-12-02 04:46:36 +0100 <hexology> you asked about project config: are you talking about hie.yaml, or something else?
2023-12-02 04:46:45 +0100 <hexology> i haven't looked into cabal or stack at all
2023-12-02 04:47:59 +0100 <iqubic> So, I'm using this shell.nix to build my Haskell project. It mostly just automatically generates a derivation from a cabal file and runs that for me. However, this doesn't seem to pull in an HLS compatible with GHC9.6.2. What gives? https://dpaste.com/CJXFUTLJ6
2023-12-02 04:47:59 +0100 <haskellbridge> 14<m​aerwald> https://cabal.readthedocs.io/en/stable/developing-packages.html#introduction
2023-12-02 04:53:06 +0100 <[Leary]> iqubic: I imagine you need to get hls from haskell.packages.ghc962, rather than from pkgs.
2023-12-02 04:53:40 +0100 <hexology> @maerwald do you prefer cabal over stack? i can flip a coin and pick one to start with, but it'd be nice to know the pros and cons
2023-12-02 04:53:40 +0100 <lambdabot> Unknown command, try @list
2023-12-02 04:53:46 +0100 <hexology> (btw where is this bridged from? matrix? discord?)
2023-12-02 04:54:13 +0100 <haskellbridge> 14<m​aerwald> my opinion varies wildly whether you're asking me as an end-user or potential contributor
2023-12-02 04:54:26 +0100 <haskellbridge> 14<m​aerwald> if I had time to improve either cabal or stack, I would pick stack
2023-12-02 04:54:32 +0100 <haskellbridge> 14<m​aerwald> but I don't really use it at the moment
2023-12-02 04:55:00 +0100 <iqubic> [le
2023-12-02 04:55:15 +0100 <haskellbridge> 14<m​aerwald> cabal supports my workflow better
2023-12-02 04:55:20 +0100 <iqubic> [Leary]: that seems to work.
2023-12-02 04:55:30 +0100 <haskellbridge> 14<m​aerwald> but it has wildly inconsistent ergonomics
2023-12-02 04:57:29 +0100 <haskellbridge> 14<m​aerwald> stack layers too much stuff into the default experience and it's inconvenient for me as a power user to control its behavior properly
2023-12-02 04:58:43 +0100 <haskellbridge> 14<m​aerwald> my experience (contrary to popular belief) is that stack is more confusing to newcomers
2023-12-02 05:00:24 +0100 <haskellbridge> 14<m​aerwald> when you look at the purely technical side, the differences are not even that big. The biggest is that: cabal has a constraint solver to resolve dependencies from hackage (the main haskell package repository). Stack does not have a constraint solver, but instead has a fixed set of packages that are updated manually (called stackage)
2023-12-02 05:01:46 +0100td_(~td@i5387090F.versanet.de) (Ping timeout: 268 seconds)
2023-12-02 05:03:10 +0100td_(~td@i53870935.versanet.de)
2023-12-02 05:13:53 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 05:21:36 +0100dikiaap(~dikiaap@user/dikiaap)
2023-12-02 05:26:20 +0100Unicorn_Princess(~Unicorn_P@user/Unicorn-Princess/x-3540542) (Remote host closed the connection)
2023-12-02 05:34:01 +0100szkl(uid110435@id-110435.uxbridge.irccloud.com) (Quit: Connection closed for inactivity)
2023-12-02 05:49:03 +0100aforemny_(~aforemny@2001:9e8:6cc6:6d00:7f41:9fb0:8b7b:8b35)
2023-12-02 05:49:16 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 255 seconds)
2023-12-02 05:50:17 +0100aforemny(~aforemny@2001:9e8:6cdf:e00:38e7:17a8:21ff:bb15) (Ping timeout: 256 seconds)
2023-12-02 05:52:11 +0100ski(~ski@ext-1-042.eduroam.chalmers.se) (Ping timeout: 264 seconds)
2023-12-02 05:54:31 +0100dikiaap_(~dikiaap@user/dikiaap)
2023-12-02 05:54:40 +0100dikiaap(~dikiaap@user/dikiaap) (Remote host closed the connection)
2023-12-02 06:00:42 +0100takuan(~takuan@178-116-218-225.access.telenet.be)
2023-12-02 06:03:37 +0100iqubic(~avi@2601:602:9502:c70:4074:a07:97c8:fa87) (Remote host closed the connection)
2023-12-02 06:03:37 +0100takuan(~takuan@178-116-218-225.access.telenet.be) (Read error: Connection reset by peer)
2023-12-02 06:04:07 +0100takuan(~takuan@178-116-218-225.access.telenet.be)
2023-12-02 06:08:30 +0100 <hexology> maerwald: i'm asking primarily as an end user. thanks for your opinion. something like stackage is very uncommon, the only other place i've seen that is common lisp quicklisp. so that's certainly an interesting and unusual choice coming from other languages.
2023-12-02 06:08:56 +0100jathan(~jathan@69.61.93.38) (Quit: WeeChat 2.3)
2023-12-02 06:09:17 +0100 <hexology> is there a straightforward way to catch the error thrown by Data.List.NonEmpty.fromList when called on an empty list? i just want to print the offending list and then re-throw the error.
2023-12-02 06:13:34 +0100 <hexology> i did some searching (and even asked chatgpt) and got as far as this: `let lst' = Data.List.NonEmpty.fromList lst ; _ = catch (evaluate lst') (\ (e :: SomeException) -> do print lst ; throw e)` -- but it seems to throw the error "eagerly", befreo the 2nd expression happens. not sure if that's the correct diagnosis
2023-12-02 06:14:14 +0100 <hexology> i know i can do other things here (like checking length and calling trace) but i feel like this is a good learning opportunity
2023-12-02 06:14:25 +0100 <[Leary]> hexology: What's there to print when it can only be []? That said, you want `nonEmpty` instead of `fromList`; trying to catch "pure errors" is nasty and should be avoided.
2023-12-02 06:14:57 +0100 <hexology> [Leary]: oh sorry, i'm actually printing the value of something else from which lst is computed (apparently incorrectly)
2023-12-02 06:15:47 +0100bugger2`(~user@184-99-108-65.boid.qwest.net)
2023-12-02 06:16:21 +0100 <hexology> i assume there will be cases when i can't insert Maybe easily -- e.g. in my current code i'm not using it, i'd have to do some refactoring. not a big deal for 15 lines, but that seems like it could cause a lot of problems in a bigger system
2023-12-02 06:17:50 +0100 <hexology> or is there some easy way to handle that?
2023-12-02 06:18:16 +0100 <[Leary]> It's entirely local. `case nonEmpty lst of { Nothing -> do { print ...; throw ... } ; Just nel -> do ... }`
2023-12-02 06:18:37 +0100 <hexology> ohh i see, thank you
2023-12-02 06:18:41 +0100bugger2`(~user@184-99-108-65.boid.qwest.net) (Client Quit)
2023-12-02 06:19:22 +0100dikiaap_dikiaap
2023-12-02 06:19:26 +0100 <hexology> i was hoping to re-throw the original error but i guess that works fo rnow
2023-12-02 06:20:06 +0100 <[Leary]> Pure errors are not meant to be caught in the first place.
2023-12-02 06:20:16 +0100 <[Leary]> Avoid functions that throw them.
2023-12-02 06:20:27 +0100 <hexology> not even for debugging purposes?
2023-12-02 06:20:37 +0100 <hexology> but noted about avoiding functions that throw them. i see it's a pain to deal with
2023-12-02 06:20:55 +0100bugger2(~user@184-99-108-65.boid.qwest.net)
2023-12-02 06:21:17 +0100 <hexology> i have been using idris2 and i guess i'm a little spoiled with dependent types. it's very convenient to have this all safely handled at the type level
2023-12-02 06:22:28 +0100Xyloes(~wyx@2400:dd01:103a:1012:5923:33ce:7857:fc04) (Quit: Konversation terminated!)
2023-12-02 06:22:35 +0100 <bugger2> hello! I'm fairly new to this whole functional programming thing, and I was wondering if anybody could give me some feedback on a simple function I wrote, and if it's really written in the 'functional' way
2023-12-02 06:22:37 +0100 <bugger2> sumAll :: [Integer] -> Integer
2023-12-02 06:22:37 +0100 <bugger2> sumAll a =
2023-12-02 06:22:37 +0100 <bugger2> do
2023-12-02 06:22:37 +0100 <bugger2> let (x:xs) = a
2023-12-02 06:22:40 +0100 <bugger2> if null xs
2023-12-02 06:22:44 +0100 <bugger2> then x
2023-12-02 06:22:47 +0100 <bugger2> else x + sumAll xs
2023-12-02 06:23:17 +0100 <hexology> bugger2: you might want to post code on a paste site instead, pasting into IRC does not usually end well. it looks like there's a paste site linked in the topic: https://paste.tomsmeding.com/
2023-12-02 06:23:23 +0100 <hexology> (i usually use https://bpaste.net)
2023-12-02 06:24:01 +0100 <bugger2> oh, thanks! will do
2023-12-02 06:24:24 +0100 <bugger2> https://bpa.st/FRRQ
2023-12-02 06:24:35 +0100 <int-e> I'd use pattern matching for that one... sumAll [] = ..., sumAll (x:xs) = ...
2023-12-02 06:24:46 +0100 <int-e> (and use the empty list as the base case, as indicated)
2023-12-02 06:24:53 +0100 <int-e> > sum []
2023-12-02 06:24:55 +0100 <lambdabot> 0
2023-12-02 06:26:11 +0100Inst(~Inst@120.244.192.187) (Ping timeout: 245 seconds)
2023-12-02 06:27:20 +0100 <bugger2> oh I see! are you saying that I can essentially overload functions like I can in languages like java or c++ in haskell?
2023-12-02 06:27:36 +0100 <int-e> That's not an overload; it's a case distinction.
2023-12-02 06:28:24 +0100 <int-e> it gets translated into the equivalent of sumAll arg = case arg of [] -> ...; (x:xs) -> ..., but it's easier to read.
2023-12-02 06:28:53 +0100 <bugger2> so it's generally more recommended to use case distinctions for base cases instead of if statements?
2023-12-02 06:28:57 +0100 <bugger2> thanks for the help
2023-12-02 06:30:53 +0100 <Guest69> a lot of this pattern matching stuff is just syntactic sugar, you can use whichever form you like
2023-12-02 06:32:26 +0100 <int-e> I'd only use `null xs` if I don't want to decompose the list into head and tail in the non-null case.
2023-12-02 06:33:15 +0100 <bugger2> yeah I pretty much just put that there because the linter suggested I do
2023-12-02 06:34:22 +0100juri_(~juri@faikvm.com) (Ping timeout: 260 seconds)
2023-12-02 06:35:36 +0100 <int-e> I'd also never use `do` for non-monadic code. It works, but it looks odd to me. (There is a `let` syntax for expressions, `let foo = bar in baz`)
2023-12-02 06:36:17 +0100 <int-e> (so you need an `in` keyword that you don't have in `do` notation)
2023-12-02 06:40:53 +0100 <int-e> @src sum
2023-12-02 06:40:53 +0100 <lambdabot> sum = foldl (+) 0
2023-12-02 06:41:15 +0100juri_(~juri@faikvm.com)
2023-12-02 06:42:42 +0100 <EvanR> oh hell yeah...
2023-12-02 06:42:56 +0100 <EvanR> got it on first try
2023-12-02 06:43:18 +0100 <EvanR> (advent of code 2023)
2023-12-02 06:43:56 +0100 <int-e> bugger2: ^^ this is for later maybe... there are generic functions for lists that embody common recursion patterns. People actually use those quite a bit, but it's healthy to start with manual recursion first until you actually see that there are common patterns.
2023-12-02 06:44:56 +0100 <int-e> (it's good practice too; you'll often fall back on explicit recursion regardless, in my experience)
2023-12-02 06:46:21 +0100trev(~trev@user/trev)
2023-12-02 06:50:19 +0100shapr(~user@2600:1700:c640:3100:a0ba:87d7:8ba1:c40) (Remote host closed the connection)
2023-12-02 06:50:34 +0100shapr(~user@2600:1700:c640:3100:9ca8:a6d7:dfea:ccc7)
2023-12-02 06:51:56 +0100 <glguy> Today's AoC parser (th wrapper around ReadP) [format|2023 2 (Game %d: (%d %s)&(, )&(; )%n)*|]
2023-12-02 06:52:33 +0100 <xerox> that work paid off :)
2023-12-02 06:53:07 +0100 <EvanR> did you design this "regex" language yourself or is it based on prior art
2023-12-02 06:55:05 +0100 <glguy> Started from scanf and enriched from there with repetition and automatically generated enum parsers from data type definitions
2023-12-02 06:56:10 +0100 <monochrom> Wait, you mean %d works for all Enum instances?!
2023-12-02 06:56:24 +0100 <glguy> No, there's another % for that
2023-12-02 06:56:47 +0100 <glguy> Any % capital letter generates an enum parser for that type
2023-12-02 06:56:58 +0100 <glguy> Using the constructor names for the strings to match
2023-12-02 06:58:52 +0100 <glguy> Err, I was close, it looks like this: https://github.com/glguy/advent/blob/main/solutions/src/2020/04.hs#L32
2023-12-02 06:59:09 +0100 <glguy> @F matches the data type F above (dropping the leading F from each constructors name)
2023-12-02 06:59:09 +0100 <lambdabot> Maybe you meant: v @ ? .
2023-12-02 06:59:23 +0100 <glguy> No, lambdabot; I meant what I said!
2023-12-02 06:59:39 +0100 <int-e> @v
2023-12-02 06:59:39 +0100 <lambdabot> "\"\\\"\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\"
2023-12-02 07:00:11 +0100 <EvanR> fix show
2023-12-02 07:00:13 +0100 <EvanR> > fix show
2023-12-02 07:00:15 +0100 <lambdabot> "\"\\\"\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\...
2023-12-02 07:00:15 +0100 <int-e> @help v
2023-12-02 07:00:15 +0100 <lambdabot> let v = show v in v
2023-12-02 07:00:20 +0100 <int-e> what a silly command
2023-12-02 07:00:50 +0100 <xerox> just strings you along
2023-12-02 07:01:34 +0100 <EvanR> 1 3 7 15 31
2023-12-02 07:02:27 +0100alp_(~alp@2001:861:e3d6:8f80:d334:4783:851a:5b3c)
2023-12-02 07:02:52 +0100 <int-e> > fix (scanl (+) 1 . map succ)
2023-12-02 07:02:53 +0100 <lambdabot> [1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535,131071,262...
2023-12-02 07:07:21 +0100bugger2(~user@184-99-108-65.boid.qwest.net) (Remote host closed the connection)
2023-12-02 07:07:36 +0100 <Guest69> anyone else see horizontal parabolas in the output?
2023-12-02 07:21:42 +0100 <haskellbridge> 06<s​m> hexology: things like stackage aren't uncommon at all, look at eg Debian
2023-12-02 07:27:36 +0100 <haskellbridge> 06<s​m> hackage is debian unstable (or maybe github), stackage nightly is debian testing, stackage lts is debian stable, roughly
2023-12-02 07:29:19 +0100whatsupdoc(uid509081@id-509081.hampstead.irccloud.com) (Quit: Connection closed for inactivity)
2023-12-02 07:35:12 +0100bilegeek(~bilegeek@2600:1008:b056:35d:76c2:a006:21b1:7eff) (Quit: Leaving)
2023-12-02 07:45:43 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-02 07:48:36 +0100ski(~ski@remote11.chalmers.se)
2023-12-02 07:50:14 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 252 seconds)
2023-12-02 07:50:15 +0100harveypwca(~harveypwc@2601:246:c280:7940:585a:99af:3e4c:209b)
2023-12-02 07:55:17 +0100notzmv(~zmv@user/notzmv) (Ping timeout: 252 seconds)
2023-12-02 08:01:01 +0100shapr(~user@2600:1700:c640:3100:9ca8:a6d7:dfea:ccc7) (Remote host closed the connection)
2023-12-02 08:01:14 +0100shapr(~user@2600:1700:c640:3100:8c27:ff31:fa9a:9753)
2023-12-02 08:08:04 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 08:10:21 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 08:12:26 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 08:19:11 +0100alp_(~alp@2001:861:e3d6:8f80:d334:4783:851a:5b3c) (Ping timeout: 256 seconds)
2023-12-02 08:28:52 +0100Xyloes(~wyx@2400:dd01:103a:1012:5923:33ce:7857:fc04)
2023-12-02 08:34:44 +0100coot(~coot@89-69-206-216.dynamic.chello.pl)
2023-12-02 08:41:37 +0100target_i(~target_i@217.175.14.39)
2023-12-02 08:50:15 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 08:55:00 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 08:57:23 +0100jargon(~jargon@184.101.176.143) (Remote host closed the connection)
2023-12-02 09:01:43 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-02 09:09:07 +0100simendsjo(~user@84.209.170.3)
2023-12-02 09:11:19 +0100azimut(~azimut@gateway/tor-sasl/azimut) (Ping timeout: 240 seconds)
2023-12-02 09:11:20 +0100whatsupdoc(uid509081@id-509081.hampstead.irccloud.com)
2023-12-02 09:11:46 +0100 <haskellbridge> 14<m​aerwald> hackage is archlinux
2023-12-02 09:12:01 +0100 <haskellbridge> 14<m​aerwald> zero quality control, just upstream releases
2023-12-02 09:12:51 +0100 <haskellbridge> 14<m​aerwald> stackage is RHEL
2023-12-02 09:12:54 +0100 <haskellbridge> 14<m​aerwald> :P
2023-12-02 09:19:02 +0100gdown(~gavin@h69-11-149-109.kndrid.broadband.dynamic.tds.net) (Remote host closed the connection)
2023-12-02 09:20:11 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470) (Remote host closed the connection)
2023-12-02 09:22:49 +0100mobounce(~mobivme@112.201.111.217)
2023-12-02 09:24:07 +0100mobivme(~mobivme@112.201.111.217) (Ping timeout: 260 seconds)
2023-12-02 09:28:44 +0100Guest69(~Guest69@akh16.neoplus.adsl.tpnet.pl) (Quit: Client closed)
2023-12-02 09:28:57 +0100waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
2023-12-02 09:32:34 +0100tomboy64(~tomboy64@user/tomboy64) (Ping timeout: 255 seconds)
2023-12-02 09:33:14 +0100guest123(~guest123@188.253.225.68)
2023-12-02 09:33:44 +0100guest123(~guest123@188.253.225.68) (Client Quit)
2023-12-02 09:45:40 +0100tomboy64(~tomboy64@user/tomboy64)
2023-12-02 09:47:17 +0100jack_rabbit(~knusbaum@2601:240:8401:630::9a71) (Ping timeout: 268 seconds)
2023-12-02 09:53:52 +0100mobounce(~mobivme@112.201.111.217) (Remote host closed the connection)
2023-12-02 09:55:16 +0100mobivme(~mobivme@112.201.111.217)
2023-12-02 09:55:40 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 09:55:59 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 09:56:32 +0100tzh(~tzh@c-71-193-181-0.hsd1.or.comcast.net) (Quit: zzz)
2023-12-02 10:00:36 +0100Square(~Square@user/square)
2023-12-02 10:00:50 +0100gmg(~user@user/gehmehgeh)
2023-12-02 10:06:49 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e149:4c4f:e3f1:4f3e) (Remote host closed the connection)
2023-12-02 10:07:44 +0100_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl)
2023-12-02 10:11:00 +0100notzmv(~zmv@user/notzmv)
2023-12-02 10:12:01 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 246 seconds)
2023-12-02 10:12:55 +0100euleritian(~euleritia@dynamic-002-247-251-222.2.247.pool.telefonica.de)
2023-12-02 10:13:18 +0100fendor(~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c)
2023-12-02 10:17:36 +0100rosco(~rosco@175.136.158.171) (Quit: Lost terminal)
2023-12-02 10:18:48 +0100notzmv(~zmv@user/notzmv) (Ping timeout: 256 seconds)
2023-12-02 10:24:56 +0100euleritian(~euleritia@dynamic-002-247-251-222.2.247.pool.telefonica.de) (Read error: Connection reset by peer)
2023-12-02 10:25:12 +0100euleritian(~euleritia@77.22.252.56)
2023-12-02 10:27:23 +0100euleritian(~euleritia@77.22.252.56) (Read error: Connection reset by peer)
2023-12-02 10:27:37 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-02 10:35:48 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655)
2023-12-02 10:38:45 +0100Tuplanolla(~Tuplanoll@91-159-68-236.elisa-laajakaista.fi)
2023-12-02 10:40:11 +0100rosco(~rosco@175.136.158.171)
2023-12-02 10:44:03 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e149:4c4f:e3f1:4f3e)
2023-12-02 10:53:45 +0100harveypwca(~harveypwc@2601:246:c280:7940:585a:99af:3e4c:209b) (Quit: Leaving)
2023-12-02 11:00:31 +0100iqubic(~avi@2601:602:9502:c70:4074:a07:97c8:fa87)
2023-12-02 11:01:49 +0100waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 276 seconds)
2023-12-02 11:01:54 +0100tdammers(~tdammers@219-131-178-143.ftth.glasoperator.nl) (Ping timeout: 268 seconds)
2023-12-02 11:02:15 +0100rosco(~rosco@175.136.158.171) (Read error: Connection reset by peer)
2023-12-02 11:03:05 +0100chomwitt(~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1)
2023-12-02 11:04:04 +0100rosco(~rosco@193.138.218.161)
2023-12-02 11:06:39 +0100ddb(ddb@tilde.club) (Quit: WeeChat 4.1.1)
2023-12-02 11:08:27 +0100econo_(uid147250@id-147250.tinside.irccloud.com) (Quit: Connection closed for inactivity)
2023-12-02 11:09:42 +0100shapr(~user@2600:1700:c640:3100:8c27:ff31:fa9a:9753) (Remote host closed the connection)
2023-12-02 11:09:56 +0100shapr(~user@2600:1700:c640:3100:1985:f966:9b37:1390)
2023-12-02 11:12:58 +0100Lord_of_Life_(~Lord@user/lord-of-life/x-2819915)
2023-12-02 11:13:07 +0100idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
2023-12-02 11:14:23 +0100Lord_of_Life(~Lord@user/lord-of-life/x-2819915) (Ping timeout: 264 seconds)
2023-12-02 11:15:58 +0100Lord_of_Life_Lord_of_Life
2023-12-02 11:16:33 +0100raehik(~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net)
2023-12-02 11:19:13 +0100coot(~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
2023-12-02 11:19:59 +0100simendsjo(~user@84.209.170.3) (Remote host closed the connection)
2023-12-02 11:24:02 +0100wootehfoot(~wootehfoo@user/wootehfoot)
2023-12-02 11:26:31 +0100coot(~coot@89-69-206-216.dynamic.chello.pl)
2023-12-02 11:27:01 +0100chomwitt(~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1) (Ping timeout: 245 seconds)
2023-12-02 11:28:09 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 252 seconds)
2023-12-02 11:38:53 +0100rosco(~rosco@193.138.218.161) (Ping timeout: 240 seconds)
2023-12-02 11:40:43 +0100rosco(~rosco@175.136.158.171)
2023-12-02 11:45:59 +0100raehik(~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net) (Ping timeout: 260 seconds)
2023-12-02 11:46:57 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-02 11:50:29 +0100Inst(~Inst@120.244.192.187)
2023-12-02 11:51:58 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 255 seconds)
2023-12-02 11:52:45 +0100__monty__(~toonn@user/toonn)
2023-12-02 11:56:05 +0100danza(~francesco@151.46.206.152)
2023-12-02 12:02:20 +0100tomboy64(~tomboy64@user/tomboy64) (Ping timeout: 268 seconds)
2023-12-02 12:07:02 +0100sawilagar(~sawilagar@user/sawilagar)
2023-12-02 12:08:15 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 256 seconds)
2023-12-02 12:08:27 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-02 12:10:53 +0100shapr(~user@2600:1700:c640:3100:1985:f966:9b37:1390) (Remote host closed the connection)
2023-12-02 12:11:11 +0100shapr(~user@2600:1700:c640:3100:27e8:54c4:4d67:f08)
2023-12-02 12:11:20 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net)
2023-12-02 12:13:04 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Remote host closed the connection)
2023-12-02 12:13:26 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net)
2023-12-02 12:15:56 +0100tomboy64(~tomboy64@user/tomboy64)
2023-12-02 12:17:31 +0100lisbeths_(uid135845@id-135845.lymington.irccloud.com)
2023-12-02 12:18:31 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 276 seconds)
2023-12-02 12:20:23 +0100tomboy64(~tomboy64@user/tomboy64) (Ping timeout: 264 seconds)
2023-12-02 12:21:03 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net)
2023-12-02 12:21:06 +0100 <hapisnake> Hello
2023-12-02 12:22:50 +0100 <Rembane> Hi hapisnake !
2023-12-02 12:24:50 +0100 <hapisnake> Hi Rembane, I'm new to haskell community, where to i will start to learn haskell, it was really interesting programming languages, anyone can guide me where to start, any resources for haskell,
2023-12-02 12:24:51 +0100 <hapisnake> Thanks in advance
2023-12-02 12:25:43 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 246 seconds)
2023-12-02 12:25:53 +0100euleritian(~euleritia@dynamic-002-247-251-222.2.247.pool.telefonica.de)
2023-12-02 12:27:35 +0100 <haskellbridge> 14<m​aerwald> https://www.haskell.org/ghcup/steps/
2023-12-02 12:27:37 +0100 <Rembane> hapisnake: I have no idea anymore, but there are others here who do.
2023-12-02 12:27:57 +0100 <hapisnake> Sure Rembane
2023-12-02 12:28:01 +0100rosco(~rosco@175.136.158.171) (Quit: Lost terminal)
2023-12-02 12:28:12 +0100rosco(~rosco@175.136.158.171)
2023-12-02 12:29:10 +0100 <hapisnake> I need to what is the future of haskell, which companies are using haskell
2023-12-02 12:29:38 +0100 <idgaen> hapisnake: there is a list of resource here: https://www.haskell.org/documentation/
2023-12-02 12:29:44 +0100euleritian(~euleritia@dynamic-002-247-251-222.2.247.pool.telefonica.de) (Read error: Connection reset by peer)
2023-12-02 12:30:03 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-02 12:31:26 +0100 <Rembane> hapisnake: These of instance: https://github.com/erkmos/haskell-companies
2023-12-02 12:33:02 +0100notzmv(~zmv@user/notzmv)
2023-12-02 12:33:12 +0100 <idgaen> cis194 is knwon to be a good starting, although I didn't learn with this. I like the haskell wiki and the haskell wikibook
2023-12-02 12:34:07 +0100 <hapisnake> Thanks Rembane and idgaen
2023-12-02 12:36:29 +0100 <Rembane> hapisnake: np, good luck! :)
2023-12-02 12:37:00 +0100kritzefitz(~kritzefit@debian/kritzefitz) (Remote host closed the connection)
2023-12-02 12:38:45 +0100zetef(~quassel@2a02:2f00:5201:4b00:7fc8:6fbe:33d9:ba2a)
2023-12-02 12:38:46 +0100kritzefitz(~kritzefit@debian/kritzefitz)
2023-12-02 12:45:03 +0100Sgeo(~Sgeo@user/sgeo) (Read error: Connection reset by peer)
2023-12-02 12:45:40 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 12:47:20 +0100 <idgaen> hapisnake: you're wellcom
2023-12-02 12:47:23 +0100 <idgaen> +e
2023-12-02 12:48:32 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 12:52:50 +0100Unicorn_Princess(~Unicorn_P@user/Unicorn-Princess/x-3540542)
2023-12-02 12:59:10 +0100__monty__(~toonn@user/toonn) (Quit: leaving)
2023-12-02 13:04:39 +0100tomboy64(~tomboy64@user/tomboy64)
2023-12-02 13:06:35 +0100pavonia(~user@user/siracusa) (Quit: Bye!)
2023-12-02 13:07:57 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 13:13:07 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 13:14:46 +0100pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Ping timeout: 255 seconds)
2023-12-02 13:16:01 +0100Unicorn_Princess(~Unicorn_P@user/Unicorn-Princess/x-3540542) (Remote host closed the connection)
2023-12-02 13:18:04 +0100hapisnake(~hapisnake@120.138.12.155) (Quit: Client closed)
2023-12-02 13:22:58 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-02 13:23:10 +0100coot(~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
2023-12-02 13:31:25 +0100turlando(~turlando@user/turlando) (Quit: No Ping reply in 180 seconds.)
2023-12-02 13:31:54 +0100danza(~francesco@151.46.206.152) (Read error: Connection reset by peer)
2023-12-02 13:32:40 +0100turlando(~turlando@user/turlando)
2023-12-02 13:33:19 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 13:34:19 +0100Guest79(~Guest79@102.88.35.165)
2023-12-02 13:34:44 +0100wootehfoot(~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
2023-12-02 13:36:12 +0100Guest79(~Guest79@102.88.35.165) (Client Quit)
2023-12-02 13:37:21 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 13:39:40 +0100progress(~progress@45.112.243.217)
2023-12-02 13:40:05 +0100progress(~progress@45.112.243.217) (Client Quit)
2023-12-02 13:41:43 +0100AlexZenon(~alzenon@5.139.232.120) (Quit: ;-)
2023-12-02 13:42:08 +0100AlexNoo(~AlexNoo@5.139.232.120) (Quit: Leaving)
2023-12-02 13:55:05 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 13:57:06 +0100todi(~todi@pd9571327.dip0.t-ipconnect.de) (Quit: ZNC - https://znc.in)
2023-12-02 13:57:25 +0100coot(~coot@89-69-206-216.dynamic.chello.pl)
2023-12-02 13:58:53 +0100sawilagar(~sawilagar@user/sawilagar) (Ping timeout: 268 seconds)
2023-12-02 14:00:05 +0100coot(~coot@89-69-206-216.dynamic.chello.pl) (Client Quit)
2023-12-02 14:01:31 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 14:01:56 +0100FinnBoat(~user@176-151-21-224.abo.bbox.fr)
2023-12-02 14:02:09 +0100 <FinnBoat> can makefile achieve cabal functionalities?
2023-12-02 14:03:37 +0100Nixkernal(~Nixkernal@115.16.194.178.dynamic.wline.res.cust.swisscom.ch)
2023-12-02 14:13:32 +0100wootehfoot(~wootehfoo@user/wootehfoot)
2023-12-02 14:17:20 +0100coot(~coot@89-69-206-216.dynamic.chello.pl)
2023-12-02 14:18:30 +0100wootehfoot(~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
2023-12-02 14:19:08 +0100iteratee_(~kyle@162.218.222.207)
2023-12-02 14:19:20 +0100iteratee(~kyle@162.218.222.207) (Read error: Connection reset by peer)
2023-12-02 14:24:21 +0100ph88(~ph88@ip5b40e272.dynamic.kabel-deutschland.de)
2023-12-02 14:24:21 +0100AlexZenon(~alzenon@5.139.232.120)
2023-12-02 14:24:31 +0100AlexNoo(~AlexNoo@5.139.232.120)
2023-12-02 14:25:24 +0100FinnBoat(~user@176-151-21-224.abo.bbox.fr) (Ping timeout: 268 seconds)
2023-12-02 14:25:58 +0100phma(phma@2001:5b0:210d:4b88:3e7a:d751:236f:1da4) (Read error: Connection reset by peer)
2023-12-02 14:26:23 +0100phma(~phma@host-67-44-208-227.hnremote.net)
2023-12-02 14:27:39 +0100alp_(~alp@2001:861:e3d6:8f80:1973:f886:fe50:985c)
2023-12-02 14:29:13 +0100zetef(~quassel@2a02:2f00:5201:4b00:7fc8:6fbe:33d9:ba2a) (Ping timeout: 256 seconds)
2023-12-02 14:29:52 +0100wootehfoot(~wootehfoo@user/wootehfoot)
2023-12-02 14:33:09 +0100 <juri_> so, i have a Makefile that wraps cabal, but no.
2023-12-02 14:34:38 +0100wootehfoot(~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
2023-12-02 14:36:07 +0100coot(~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
2023-12-02 14:43:11 +0100dikiaap(~dikiaap@user/dikiaap) (Remote host closed the connection)
2023-12-02 14:43:53 +0100dikiaap(~dikiaap@user/dikiaap)
2023-12-02 14:46:43 +0100chomwitt(~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1)
2023-12-02 14:47:05 +0100lisbeths_(uid135845@id-135845.lymington.irccloud.com) (Quit: Connection closed for inactivity)
2023-12-02 14:52:35 +0100chomwitt(~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1) (Ping timeout: 256 seconds)
2023-12-02 14:56:08 +0100 <tomsmeding> cabal does dependency resolution: from the dependency bounds of your package, and of all the other packages on Hackage, it tries to determine some set of consistent versions
2023-12-02 14:56:27 +0100 <tomsmeding> that's something that you won't get Make to do easily
2023-12-02 14:57:55 +0100zetef(~quassel@2a02:2f00:5201:4b00:7fc8:6fbe:33d9:ba2a)
2023-12-02 14:59:39 +0100 <kaol> If you limit yourself to what cabal --offline does then you could get away with it.
2023-12-02 15:01:39 +0100shapr(~user@2600:1700:c640:3100:27e8:54c4:4d67:f08) (Remote host closed the connection)
2023-12-02 15:01:53 +0100shapr(~user@2600:1700:c640:3100:778b:1629:d1a6:3cd5)
2023-12-02 15:03:04 +0100 <tomsmeding> kaol: will that not still do the solving, just not download anything if it doesn't have it locally yet?
2023-12-02 15:04:14 +0100 <kaol> I guess autoconf and/or automake would be a better analogue. It still doesn't do any downloads.
2023-12-02 15:04:27 +0100 <tomsmeding> stil no version solving though
2023-12-02 15:04:35 +0100 <tomsmeding> but if you have the equivalent of a freeze file, you don't need to solve anything
2023-12-02 15:05:31 +0100sawilagar(~sawilagar@user/sawilagar)
2023-12-02 15:08:24 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-02 15:10:56 +0100coot(~coot@89-69-206-216.dynamic.chello.pl)
2023-12-02 15:12:50 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 15:15:36 +0100shebpamm(~shebpamm@user/shebpamm)
2023-12-02 15:15:49 +0100shebpamm(~shebpamm@user/shebpamm) (Client Quit)
2023-12-02 15:15:51 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
2023-12-02 15:16:03 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-02 15:16:15 +0100shebpamm(~shebpamm@user/shebpamm)
2023-12-02 15:16:16 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 15:17:20 +0100 <shebpamm> Trying to do some very very basic haskell and I'm stumped at why in the world does my program output gibberish text when reading from a file when executed with stack run but not when I do the same in ghci
2023-12-02 15:18:29 +0100waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
2023-12-02 15:18:46 +0100Guest49(~Guest49@dyn216-174-69-55.HSIA.mnsi.net)
2023-12-02 15:20:07 +0100Guest49(~Guest49@dyn216-174-69-55.HSIA.mnsi.net) (Client Quit)
2023-12-02 15:24:23 +0100 <shebpamm> Here's the Main.hs and Lib.hs: https://paste.debian.net/1299940/ https://paste.debian.net/1299941/
2023-12-02 15:24:51 +0100 <shebpamm> If I run that with stack run I
2023-12-02 15:25:44 +0100 <shebpamm> get an output in the terminal that is not part of any file in the directory, but I can't figure out what it is.
2023-12-02 15:26:05 +0100 <shebpamm> I've confirmed with strace that it is indeed reading the correct file and content.
2023-12-02 15:26:19 +0100seydar(~seydar@38-73-249-43.starry-inc.net)
2023-12-02 15:26:34 +0100dikiaap(~dikiaap@user/dikiaap) (Remote host closed the connection)
2023-12-02 15:34:11 +0100elkcl(~elkcl@broadband-95-84-226-240.ip.moscow.rt.ru) (Ping timeout: 260 seconds)
2023-12-02 15:34:21 +0100 <shebpamm> I suspect it's me misusing head with a IO [String] somehow, but I'll have to look further
2023-12-02 15:35:01 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: Textual IRC Client: www.textualapp.com)
2023-12-02 15:35:14 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection)
2023-12-02 15:35:22 +0100dikiaap(~dikiaap@user/dikiaap)
2023-12-02 15:35:47 +0100FinnElija(~finn_elij@user/finn-elija/x-0085643)
2023-12-02 15:35:59 +0100 <kaol> I don't think your output line quite does what you expect. input :: [String], did you mean to take the first line? That'd be head input. head <$> input is equal to map head input, which just as a coincidence type checks as well but it takes the first letter of each line in input and makes a string out of that.
2023-12-02 15:36:01 +0100 <idgaen> shebpamm: notice that input should be a String not an IO String
2023-12-02 15:36:45 +0100 <idgaen> so why are you using <$>?
2023-12-02 15:38:09 +0100 <idgaen> oops, I'm wrong, input is a [String], anyway you don't have to use <$> to just get the first element of the list.
2023-12-02 15:38:38 +0100 <kaol> > map head ["foo", "bar", "asdf"]
2023-12-02 15:38:39 +0100 <lambdabot> "fba"
2023-12-02 15:41:10 +0100 <kaol> I'm guessing the difference between using stack and ghci comes from running main versus calling readChallengeInput "1" directly from Lib. Running main in ghci would get the same result as stack run.
2023-12-02 15:42:02 +0100 <ncf> more info needed
2023-12-02 15:42:04 +0100elkcl(~elkcl@broadband-95-84-226-240.ip.moscow.rt.ru)
2023-12-02 15:42:13 +0100 <ncf> what commands are you running, what is it outputting, etc
2023-12-02 15:43:06 +0100 <shebpamm> kaol: Thanks for the response! Quite funny that I managed to accidentally output the first letter from every line.
2023-12-02 15:43:28 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-02 15:43:51 +0100wootehfoot(~wootehfoo@user/wootehfoot)
2023-12-02 15:44:42 +0100 <kaol> I've done customer projects long enough to get good at guessing the missing parts from a problem description. ;-)
2023-12-02 15:48:17 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-02 15:48:30 +0100 <shebpamm> ncf: I ran head <$> readChallengeInput "1" using `stack ghci` and that seemed to display the first row of the file, which I assume is the same as what I've written in main. There's a real possibility `do` does not do what I think it does, which would also make sense.
2023-12-02 15:49:10 +0100 <kaol> Yeah, that's not the same because in doing that the functor is IO. In your main the functor was list.
2023-12-02 15:50:34 +0100 <shebpamm> Makes sense, thanks for the help all!
2023-12-02 15:50:38 +0100 <kaol> input <- head <$> readChallengeInput "1" would have done what expected.
2023-12-02 15:53:10 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 255 seconds)
2023-12-02 15:59:03 +0100Xyloes(~wyx@2400:dd01:103a:1012:5923:33ce:7857:fc04) (Quit: Konversation terminated!)
2023-12-02 16:03:45 +0100wootehfoot(~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
2023-12-02 16:17:35 +0100rosco(~rosco@175.136.158.171) (Quit: Lost terminal)
2023-12-02 16:18:01 +0100 <seydar> why am i so dumb: https://paste.tomsmeding.com/CKymaZQ7
2023-12-02 16:19:51 +0100td_(~td@i53870935.versanet.de) (Ping timeout: 256 seconds)
2023-12-02 16:21:25 +0100td_(~td@i5387091D.versanet.de)
2023-12-02 16:23:13 +0100 <seydar> line 12, I am unable to figure out how to get the sum. `sum <$> Just [1, 2, 3, 4, 5]` works, and that's the result of `sequence`, but somehow I can't get the sum in there as well
2023-12-02 16:23:44 +0100alp_(~alp@2001:861:e3d6:8f80:1973:f886:fe50:985c) (Ping timeout: 256 seconds)
2023-12-02 16:25:11 +0100 <seydar> it looks like it's just a matter of precedence and parenthesis — what's the best way to phrase it?
2023-12-02 16:27:09 +0100 <[Leary]> seydar: You're writing point-free, so you need to compose rather than apply: s/sum <$>/(sum <$>) ./
2023-12-02 16:28:03 +0100 <kaol> Or just "fmap sum ."
2023-12-02 16:28:04 +0100 <seydar> ahhhh. i ended up switching it to an fmap (pointful?)
2023-12-02 16:28:05 +0100 <haskellbridge> 14<m​auke> Or `fmap sum .`
2023-12-02 16:28:13 +0100 <seydar> is there a preferred way to phrase that line?
2023-12-02 16:28:29 +0100 <haskellbridge> 14<m​auke> Ah, too late
2023-12-02 16:28:38 +0100 <kaol> No internet points for you.
2023-12-02 16:28:43 +0100 <ncf> sequence . map f = traverse f
2023-12-02 16:29:57 +0100 <seydar> ncf: perfect, thank you
2023-12-02 16:31:24 +0100Unicorn_Princess(~Unicorn_P@user/Unicorn-Princess/x-3540542)
2023-12-02 16:37:12 +0100 <seydar> can i get some corrections on how to make this function prettier? https://paste.tomsmeding.com/B2zE1pHF
2023-12-02 16:37:20 +0100 <seydar> i hate that i'm using a case expression
2023-12-02 16:37:35 +0100[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470)
2023-12-02 16:38:20 +0100 <kaol> fromMaybe 0
2023-12-02 16:40:05 +0100 <seydar> the haskell gods have favored us this winter with their gift of fromMaybe
2023-12-02 16:40:12 +0100 <[Leary]> Also `fold`
2023-12-02 16:41:02 +0100 <kaol> Int is not a monoid.
2023-12-02 16:41:45 +0100 <[Leary]> Ah, right. How bothersome. I'd be tempted to write the whole function as a foldMap with Sum...
2023-12-02 16:45:09 +0100 <[Leary]> I guess you'd need Ap too. Too many wrappers; not worth it. <.<
2023-12-02 16:45:11 +0100 <lambdabot> 0
2023-12-02 16:46:06 +0100 <kaol> > getProduct . foldMap Product $ Nothing
2023-12-02 16:46:07 +0100 <lambdabot> 1
2023-12-02 16:46:34 +0100emmanuelux(~emmanuelu@user/emmanuelux)
2023-12-02 16:49:05 +0100xigua(~xigua@user/xigua) (Remote host closed the connection)
2023-12-02 16:49:41 +0100xigua(~xigua@user/xigua)
2023-12-02 16:50:28 +0100alp_(~alp@2001:861:e3d6:8f80:6957:2c28:8123:157f)
2023-12-02 16:54:27 +0100Angelz(Angelz@Angelz.oddprotocol.org) (Remote host closed the connection)
2023-12-02 16:55:29 +0100mjs2600(~mjs2600@c-174-169-225-239.hsd1.vt.comcast.net) (Quit: ZNC 1.8.2 - https://znc.in)
2023-12-02 16:58:48 +0100mjs2600(~mjs2600@c-174-169-225-239.hsd1.vt.comcast.net)
2023-12-02 16:59:54 +0100Angelz(Angelz@2605:6400:30:fc15:9bd1:2217:41cd:bb15)
2023-12-02 17:02:28 +0100azimut(~azimut@gateway/tor-sasl/azimut)
2023-12-02 17:09:43 +0100azimut(~azimut@gateway/tor-sasl/azimut) (Ping timeout: 240 seconds)
2023-12-02 17:11:36 +0100alp_(~alp@2001:861:e3d6:8f80:6957:2c28:8123:157f) (Ping timeout: 268 seconds)
2023-12-02 17:13:21 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 17:13:42 +0100L29Ah(~L29Ah@wikipedia/L29Ah) ()
2023-12-02 17:21:05 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer)
2023-12-02 17:21:18 +0100hochata(~user@user/hochata)
2023-12-02 17:28:28 +0100idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1)
2023-12-02 17:29:11 +0100dikiaap(~dikiaap@user/dikiaap) (Remote host closed the connection)
2023-12-02 17:29:59 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
2023-12-02 17:30:00 +0100zetef(~quassel@2a02:2f00:5201:4b00:7fc8:6fbe:33d9:ba2a) (Ping timeout: 256 seconds)
2023-12-02 17:30:31 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
2023-12-02 17:31:57 +0100jmdaemon(~jmdaemon@user/jmdaemon) (Ping timeout: 268 seconds)
2023-12-02 17:35:41 +0100econo_(uid147250@id-147250.tinside.irccloud.com)
2023-12-02 17:46:14 +0100seydar(~seydar@38-73-249-43.starry-inc.net) (Quit: leaving)
2023-12-02 17:49:44 +0100_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Remote host closed the connection)
2023-12-02 17:59:58 +0100euleritian(~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 246 seconds)
2023-12-02 18:00:16 +0100euleritian(~euleritia@dynamic-002-247-248-198.2.247.pool.telefonica.de)
2023-12-02 18:03:57 +0100L29Ah(~L29Ah@wikipedia/L29Ah)
2023-12-02 18:05:55 +0100dhil(~dhil@2001:8e0:2014:3100:b5b8:c8ab:cfa1:c979)
2023-12-02 18:15:26 +0100tzh(~tzh@c-71-193-181-0.hsd1.or.comcast.net)
2023-12-02 18:15:50 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-02 18:18:29 +0100chomwitt(~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1)
2023-12-02 18:22:44 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:e149:4c4f:e3f1:4f3e) (Remote host closed the connection)
2023-12-02 18:22:59 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:f878:9036:c8c3:a993)
2023-12-02 18:26:10 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-02 18:29:40 +0100hochata(~user@user/hochata) (Ping timeout: 276 seconds)
2023-12-02 18:32:30 +0100pavonia(~user@user/siracusa)
2023-12-02 18:34:50 +0100zetef(~quassel@2a02:2f00:5201:4b00:7fc8:6fbe:33d9:ba2a)
2023-12-02 18:53:49 +0100todi(~todi@pd9571327.dip0.t-ipconnect.de)
2023-12-02 18:56:53 +0100ACuriousMoose(~ACuriousM@142.166.18.53) (Ping timeout: 240 seconds)
2023-12-02 18:57:49 +0100euleritian(~euleritia@dynamic-002-247-248-198.2.247.pool.telefonica.de) (Ping timeout: 256 seconds)
2023-12-02 18:58:02 +0100euleritian(~euleritia@dynamic-002-247-251-219.2.247.pool.telefonica.de)
2023-12-02 18:59:49 +0100euleritian(~euleritia@dynamic-002-247-251-219.2.247.pool.telefonica.de) (Read error: Connection reset by peer)
2023-12-02 19:00:06 +0100euleritian(~euleritia@77.22.252.56)
2023-12-02 19:02:53 +0100azimut(~azimut@gateway/tor-sasl/azimut)
2023-12-02 19:03:53 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:f878:9036:c8c3:a993) (Remote host closed the connection)
2023-12-02 19:04:19 +0100 <c_wraith> Since this traps me every year, what the heck does parser-combinator's sepEndBy actually do?
2023-12-02 19:05:08 +0100eggplantade(~Eggplanta@2600:1700:38c5:d800:f878:9036:c8c3:a993)
2023-12-02 19:05:26 +0100L29Ah(~L29Ah@wikipedia/L29Ah) ()
2023-12-02 19:05:31 +0100 <EvanR> it parses like A;B;C or A;B;C;
2023-12-02 19:05:46 +0100 <iqubic> sepEndBy :: Alternative m => m a -> m sep -> m [a]
2023-12-02 19:05:51 +0100 <c_wraith> that's what it says it does. But my experience is that what it actually does is create infinite loops
2023-12-02 19:07:41 +0100 <monochrom> I have never got an infinite loop with it.
2023-12-02 19:07:58 +0100 <c_wraith> I get one every time I use it.
2023-12-02 19:08:07 +0100 <EvanR> if p always succeeds it might keep looping until input runs out?
2023-12-02 19:08:10 +0100 <monochrom> But if the separator parser accepts the empty string, that would be one way.
2023-12-02 19:08:25 +0100 <EvanR> oh failing to consume
2023-12-02 19:09:00 +0100 <c_wraith> I make sure the separator doesn't accept an empty input, and it still immediately gives me infinite loops
2023-12-02 19:09:02 +0100 <monochrom> Err no, that may not be enough. Perhaps need both separator parser and item parser to accept the empty string.
2023-12-02 19:09:43 +0100 <c_wraith> Then I sigh, replace (sepEndBy a b) with (sepBy a b <* optional b) and it works.
2023-12-02 19:14:03 +0100 <EvanR> which Alternative is this
2023-12-02 19:14:30 +0100 <EvanR> attoparsec?
2023-12-02 19:15:18 +0100ddellacosta(~ddellacos@ool-44c73d16.dyn.optonline.net) (Quit: WeeChat 4.1.1)
2023-12-02 19:15:23 +0100 <c_wraith> Earley's Prod
2023-12-02 19:17:53 +0100 <monochrom> I have tested sepEndBy (some (oneOf "ab")) (some (oneOf ";,")) . Haven't found a way to infinite-loop it yet.
2023-12-02 19:18:21 +0100 <EvanR> maybe it has something to do with the definition of <|> in use
2023-12-02 19:19:53 +0100ddellacosta(~ddellacos@ool-44c73d16.dyn.optonline.net)
2023-12-02 19:27:49 +0100cstml(~cstml@user/cstml)
2023-12-02 19:28:03 +0100cstml(~cstml@user/cstml) (Client Quit)
2023-12-02 19:30:46 +0100iqubic(~avi@2601:602:9502:c70:4074:a07:97c8:fa87) (Ping timeout: 245 seconds)
2023-12-02 19:32:16 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-02 19:34:49 +0100trev(~trev@user/trev) (Quit: trev)
2023-12-02 19:40:39 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-02 19:44:56 +0100[itchyjunk][itchTheBroken]
2023-12-02 19:49:47 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-02 19:53:53 +0100 <glguy> c_wraith: do you have an example of a looping parser with sepEndBy?
2023-12-02 19:53:59 +0100 <glguy> (that was throwing you off)
2023-12-02 19:54:10 +0100 <c_wraith> I mean, it's literally every single time I use it.
2023-12-02 19:54:14 +0100glguyadds 2023 to https://glguy.net/advent/
2023-12-02 19:54:17 +0100 <c_wraith> I'm unsure how people can make it work
2023-12-02 19:55:03 +0100 <glguy> do you use the applicative one or monad one?
2023-12-02 19:55:28 +0100 <c_wraith> applicative. Since I'm using Earley, that's the only option..
2023-12-02 19:55:28 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 276 seconds)
2023-12-02 19:56:14 +0100nerdypepper(~nerdypepp@user/nerdypepper)
2023-12-02 19:56:53 +0100 <glguy> Maybe the looping is specific to using it with Earley
2023-12-02 19:56:54 +0100 <EvanR> both sides are racing to not present an example of it either working or not working xD
2023-12-02 19:57:11 +0100 <EvanR> (with Earley)
2023-12-02 19:57:12 +0100 <cheater> if i have a GADT called Foo, can I somehow enforce that all constructors are of the form (Foo sometype) -> .... -> (Foo some other or the same type)? (with the edge condition that mkFoo :: Foo somethirdtype is allowed). also, can I somehow enforce that exactly one Foo _ is on the arg list?
2023-12-02 19:57:21 +0100 <glguy> and you're not allowed to use recursion in Earley the way that its defined
2023-12-02 19:57:21 +0100 <nerdypepper> https://termbin.com/w74f can someone help me make sense of why read fails here?
2023-12-02 19:57:48 +0100 <cheater> hi glguy
2023-12-02 19:57:52 +0100 <glguy> hi
2023-12-02 19:58:13 +0100L29Ah(~L29Ah@wikipedia/L29Ah)
2023-12-02 19:58:20 +0100 <c_wraith> glguy: I suppose that's possible, if it's just passing some and many through to Earley's Alternative instance
2023-12-02 19:58:23 +0100 <EvanR> cheater, Foo a -> Foo not necessarily a?
2023-12-02 19:58:34 +0100 <EvanR> that would be just Foo a -> Foo b right
2023-12-02 19:58:36 +0100 <glguy> nerdypepper: probably gid = read <$> many1 digit got default to reading ()
2023-12-02 19:58:47 +0100 <ski> cheater : "is on the arg list" ?
2023-12-02 19:58:47 +0100 <glguy> nerdypepper: try putting a type signature on that
2023-12-02 19:58:49 +0100 <monochrom> nerdypepper: You didn't specify a number type for gid, so ghci defaults to a non-number type, so digit strings are parse errors.
2023-12-02 19:58:53 +0100adanwan(~adanwan@gateway/tor-sasl/adanwan) (Read error: Connection reset by peer)
2023-12-02 19:58:53 +0100chexum_(~quassel@gateway/tor-sasl/chexum) (Remote host closed the connection)
2023-12-02 19:59:05 +0100 <cheater> yeah, i don't care about what's inside Foo, just that every entry in the GADT starts with a Foo, ends with a Foo, and there are no other Foo's
2023-12-02 19:59:24 +0100 <cheater> ski: arg list == everything to the left of the last right-arrow (->)
2023-12-02 19:59:29 +0100adanwan(~adanwan@gateway/tor-sasl/adanwan)
2023-12-02 19:59:31 +0100chexum(~quassel@gateway/tor-sasl/chexum)
2023-12-02 19:59:39 +0100 <nerdypepper> glguy: monochrom: ah makes sense, thanks
2023-12-02 19:59:53 +0100 <ski> cheater : i still dunno what "exactly one Foo _ is on the arg list" means
2023-12-02 20:00:03 +0100 <monochrom> If you wrote code in a file, you would get a much better error message, or even better, the defaulting would take the rest of the file into account and choose a number type.
2023-12-02 20:00:05 +0100 <tomsmeding> c_wraith: I suppose that's the downside of using a separate parser combinator library -- it can't do much else than building on some/many
2023-12-02 20:00:18 +0100 <EvanR> you specify all the constructor arguments yourself, don't put any Foo you don't want?
2023-12-02 20:00:37 +0100 <c_wraith> tomsmeding: it could implement sepEndBy on top of many, instead of doing it itself...
2023-12-02 20:00:45 +0100 <EvanR> the payload type isn't configurable
2023-12-02 20:00:49 +0100 <glguy> c_wraith: sepEndBy in parser-combinators builds itself recursively using <|> and pure
2023-12-02 20:00:55 +0100 <tomsmeding> c_wraith: fair
2023-12-02 20:00:58 +0100 <cheater> it means you can have MyFoo1 :: Foo a -> Int -> Foo b, but you can't have MyFooBad :: Foo a -> Foo c -> Foo b because there are two Foo's to the left of the rightmost right arrow (they are Foo a and Foo c)
2023-12-02 20:01:02 +0100 <ski> cheater : "every entry in the GADT starts with a Foo, ends with a Foo, and there are no other Foo's
2023-12-02 20:01:08 +0100 <glguy> but afaik Earley is based around reflecting on the whole structure of the parser - but this makes an infinite one
2023-12-02 20:01:08 +0100 <EvanR> (er, reconfigurable)
2023-12-02 20:01:20 +0100 <ski> " -- oh, i thought that you wanted every argument type of the data constructors to be a `Foo'
2023-12-02 20:01:41 +0100 <EvanR> cheater, you want to stop the programmer from typing that constructor definition?
2023-12-02 20:01:44 +0100azimut(~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection)
2023-12-02 20:01:45 +0100 <cheater> yes
2023-12-02 20:01:52 +0100 <cheater> (to EvanR )
2023-12-02 20:02:01 +0100azimut(~azimut@gateway/tor-sasl/azimut)
2023-12-02 20:02:02 +0100 <EvanR> that sounds problematic
2023-12-02 20:02:06 +0100 <cheater> why
2023-12-02 20:02:17 +0100 <EvanR> UN declaration of human rights?
2023-12-02 20:02:24 +0100 <cheater> uh huh
2023-12-02 20:02:41 +0100 <tomsmeding> you could inspect the definition of a particular GADT using TemplateHaskell
2023-12-02 20:02:47 +0100 <tomsmeding> but that might not be what you had in mind
2023-12-02 20:02:48 +0100 <EvanR> I don't get what kind of restriction you are talking about
2023-12-02 20:02:51 +0100 <cheater> hmm i could couldn't i
2023-12-02 20:02:56 +0100 <cheater> TH could throw an error
2023-12-02 20:03:00 +0100 <cheater> while compiling
2023-12-02 20:03:02 +0100 <tomsmeding> yes
2023-12-02 20:03:04 +0100 <cheater> or not throw an error
2023-12-02 20:03:17 +0100 <cheater> i hate TH, and i would probably scratch my eyes out while trying to make this thing
2023-12-02 20:03:21 +0100 <cheater> but it's a possibility
2023-12-02 20:03:22 +0100 <cheater> thanks
2023-12-02 20:03:28 +0100 <tomsmeding> I think there is _no_ other possibility
2023-12-02 20:03:30 +0100wroathe(~wroathe@50.205.197.50)
2023-12-02 20:03:30 +0100wroathe(~wroathe@50.205.197.50) (Changing host)
2023-12-02 20:03:30 +0100wroathe(~wroathe@user/wroathe)
2023-12-02 20:03:44 +0100 <tomsmeding> with normal ADTs you also have GHC Generics, which, depending on the person, is no less infuriating to use
2023-12-02 20:03:59 +0100 <ski> cheater : sounds like you could factor out this pattern into something like <https://hackage.haskell.org/package/thrist-0.2.2/docs/Data-Thrist.html>, i think ?
2023-12-02 20:04:02 +0100 <tomsmeding> but Generics don't work with general GADTs (there is kind-generics but I believe that is for something different)
2023-12-02 20:04:13 +0100 <nerdypepper> monochrom: unfortunately this function was unused in code (& no type signautre), so had similar behaviour
2023-12-02 20:04:20 +0100 <glguy> TH is the only way to do it in Haskell. If you're going to reflect on the data definitions like that th-abstraction package is a better interface than raw template-haskell reify
2023-12-02 20:04:23 +0100iqubic(~avi@2601:602:9502:c70:cb59:8f8d:7da8:6547)
2023-12-02 20:04:38 +0100L29Ah(~L29Ah@wikipedia/L29Ah) ()
2023-12-02 20:05:47 +0100 <wroathe> Hey guys, I've finally had some success making sense of my space leak and wanted to get your input. The situation is that I've got a program that reads a file into memory and then attempts to iterate through the characters of the file fixing instances where backslashes that should be escaped, aren't (i.e. "\" should be "\\"). My first implementation of this was a fold over a bytestring, and then using
2023-12-02 20:05:53 +0100 <wroathe> https://hackage.haskell.org/package/bytestring-0.12.0.2/docs/Data-ByteString-Builder.html to construct my newly "fixed" version of the file before writing it back to the FS.
2023-12-02 20:06:07 +0100 <wroathe> Thanks to GHC.DataSize I'm able to see that the final constructed Builder object uses about 24 bytes of memory per character of the input file
2023-12-02 20:06:15 +0100 <cheater> so the practical consideration is as follows: 1. a lot of stuff done in programming is state machines 2. state space is easily expressed as a haskell adt (non-gadt) 3. state transitions are easily expressed as GADTs: LogOut :: UserState LoggedIn -> UserState NotLoggedIn 4. however, every state transition must start and end with a state, and not mention any other states either, since the state transition space is a directed graph
2023-12-02 20:07:08 +0100 <ski> cheater : did you check `thrist' ?
2023-12-02 20:07:16 +0100 <cheater> i am looking at the link right now
2023-12-02 20:07:30 +0100 <wroathe> My questions are: 1. Is the Data.ByteString.Builder pretty impractical for even moderately large files? Should I be looking to Data.ByteString.Builder.Prim instead? 3. Is the problem here missing strictness annotations?
2023-12-02 20:07:34 +0100 <cheater> idk how a list of some sort helps?
2023-12-02 20:07:49 +0100 <tomsmeding> wroathe: I think the Builder API is meant for larger chunks than single characters
2023-12-02 20:08:03 +0100 <wroathe> tomsmeding: Ah. I was wondering about that.
2023-12-02 20:08:06 +0100 <glguy> wroathe: builder isn't going to be good if you build one character at a time
2023-12-02 20:08:10 +0100 <cheater> ski: so i actually want to use the GADT syntax
2023-12-02 20:08:18 +0100 <glguy> But fortunately you don't need to build one at a time
2023-12-02 20:08:22 +0100 <cheater> because it's pretty well made for state transitions
2023-12-02 20:08:31 +0100 <cheater> it's just that it's a little too "G"
2023-12-02 20:08:43 +0100 <cheater> so you have to de-G the GADT a little
2023-12-02 20:08:47 +0100 <ski> cheater : if you want at most one `Foo' argument to `Foo' data constructors, then that implies some kind of list, imho
2023-12-02 20:08:50 +0100 <EvanR> maybe you want to generate the GADTs from some more sane description of states
2023-12-02 20:08:52 +0100 <glguy> Also don't bother building a new bytestring, just write the chunks back to the output file
2023-12-02 20:08:54 +0100 <wroathe> glguy: Well, given this, and given what I see the representation of a Builder is I'm starting to think that what I want is just a Vector
2023-12-02 20:08:57 +0100 <cheater> ski: idk how
2023-12-02 20:09:10 +0100 <cheater> why does it imply a list to you?
2023-12-02 20:09:34 +0100 <EvanR> wroathe, Vector has a fixed size per vector, rather than growing dynamically like C++ vector
2023-12-02 20:09:38 +0100 <wroathe> Since I know the output will always be larger than the input I can allocate a vector that starts out at the same size, and it should then only re-alloc once while I'm appending characters
2023-12-02 20:09:45 +0100 <EvanR> appending to it would reconstruct the entire Vector so far
2023-12-02 20:09:52 +0100 <ski> cheater : because of "at most one `Foo' argument in `Foo' constructors"
2023-12-02 20:10:00 +0100 <cheater> yes, and?
2023-12-02 20:10:10 +0100 <wroathe> EvanR: That so? Hmm, I would've expected anything named "Vector" to have a similiar implementation in Haskell
2023-12-02 20:10:17 +0100 <cheater> i don't see the connection at all
2023-12-02 20:10:19 +0100 <glguy> wroathe: still better is to just write back to the file and not bother with so much allocation
2023-12-02 20:10:25 +0100 <wroathe> I.e. arrays, allocating a new larger array, and then copying and collecting the old one
2023-12-02 20:10:28 +0100idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
2023-12-02 20:10:36 +0100 <EvanR> yeah no
2023-12-02 20:10:44 +0100 <wroathe> glguy: So like a putChar kind of thing?
2023-12-02 20:11:26 +0100 <glguy> Yeah, and writing whole chunks not individual characters every time
2023-12-02 20:11:38 +0100 <glguy> You only need to do individuals when adding escapes
2023-12-02 20:11:48 +0100 <EvanR> wroathe, yes that is what concatting a Vector would do, every time
2023-12-02 20:12:01 +0100 <glguy> At least for the immutable vector
2023-12-02 20:12:01 +0100 <EvanR> allocate and do two copies
2023-12-02 20:12:13 +0100 <ski> cheater : so instead of `data UserState :: State -> * where Initial :: UserState NotLoggedIn; LogOut :: UserState LoggedIn -> UserState NotLoggedIn; ...' you'd use `Thrist UserStateTransition NotLoggedIn a' where `data UserStateTransition :: State -> * where LogOut :: UserStateTransition LoggedIn NotLoggedIn; ...'
2023-12-02 20:12:32 +0100 <glguy> There's a mutable interface, too
2023-12-02 20:12:53 +0100 <EvanR> so you could implement the big buffer that has logic to grow yourself
2023-12-02 20:13:12 +0100 <EvanR> but question whether it is necessary to buffer anything at all for your problem
2023-12-02 20:13:15 +0100 <ski> cheater : instead of `Initial', you have `Nil'. instead of `LogOut (LogIn Initial)' you have `Cons LogOut (Cons LogIn Nil)'
2023-12-02 20:13:20 +0100shapr(~user@2600:1700:c640:3100:778b:1629:d1a6:3cd5) (Remote host closed the connection)
2023-12-02 20:13:22 +0100 <wroathe> glguy: Well shouldn't `putChar` already handle the buffering for me?
2023-12-02 20:13:23 +0100 <cheater> ski, could you please put that in a paste? i'm having a hard time reading this
2023-12-02 20:13:34 +0100shapr(~user@2600:1700:c640:3100:bb5e:f749:fac6:1840)
2023-12-02 20:13:46 +0100 <EvanR> each call to putChar has overhead
2023-12-02 20:13:48 +0100 <ski> cheater : it would help if you had a more fleshed out example we could look at
2023-12-02 20:14:09 +0100 <EvanR> if you were writing individual Word8 that would reduce that somewhat
2023-12-02 20:14:19 +0100 <EvanR> but it's still better to write chunks at a time
2023-12-02 20:14:21 +0100 <cheater> well i mean, you surely know the typical workflow of a user object in a web app, just go with that
2023-12-02 20:15:02 +0100 <cheater> like to LogIn you need a password, so it would be LogIn :: UserState NotLoggedIn -> Password -> UserState LoggedIn, etc
2023-12-02 20:15:08 +0100 <wroathe> EvanR: How would I write "chunks" in this case? Maintain a pair of indexes for the span to write?
2023-12-02 20:15:21 +0100 <wroathe> Or buffer a chunk and write?
2023-12-02 20:16:02 +0100 <monochrom> putChar writes to a buffer (assuming defaults), so it is already cheaper than builder. To be sure, put-a-big-chunk is even cheaper (per byte), so since we are unescaping, it is not always going to be a big chunk verbatim.
2023-12-02 20:16:13 +0100 <cheater> ski: ^
2023-12-02 20:16:31 +0100chexum(~quassel@gateway/tor-sasl/chexum) (Ping timeout: 240 seconds)
2023-12-02 20:16:47 +0100 <ski> cheater : right. that translates to `LogIn :: Password -> UserStateTransition NotLoggedIn LoggedIn'
2023-12-02 20:17:06 +0100 <monochrom> But I did the heresy and I use the put (chunk) action, but my chunk is only 1 byte! >:D
2023-12-02 20:17:12 +0100chexum(~quassel@gateway/tor-sasl/chexum)
2023-12-02 20:17:40 +0100 <EvanR> wroathe, just write a ByteString
2023-12-02 20:18:15 +0100 <EvanR> ideally one which originally came from the input itself rather than being built Word8 at a time
2023-12-02 20:18:20 +0100 <wroathe> monochrom: So is this hypothetical program then waffling between printing bytestrings that I slice off of the original input, and then writing writing individual escaped characters?
2023-12-02 20:18:37 +0100pretty_dumm_guy(~trottel@2a02:810b:43bf:aba0:436e:e1e6:f8d4:a6aa)
2023-12-02 20:18:40 +0100 <wroathe> EvanR: Right, so that implies some kind of "slice" and then write operation
2023-12-02 20:18:42 +0100 <cheater> ski: but I can still write a GADT that's like LogMeta :: UserStateTransition NotLoggedIn LoggedIn -> UserStateTransition Something Another
2023-12-02 20:18:51 +0100 <EvanR> when you slice into a ByteString the new ByteString is pointing into the original instead of copying, unless you do an explicit copy
2023-12-02 20:18:54 +0100 <monochrom> OK, I did it deliberately because I was writing a sample socket server for students to test their clients against mine, and to drive home the point "data can be split arbitrarily", I sent 1 byte, delayed for some milliseconds, send the 2nd byte, etc.
2023-12-02 20:19:28 +0100 <monochrom> Yeah wroathe.
2023-12-02 20:19:30 +0100 <wroathe> EvanR: Ah. Ok, so maintain slice counters and only stop to putChar when I encounter my unescaped characters then
2023-12-02 20:19:36 +0100 <wroathe> I'll give that a shot
2023-12-02 20:19:37 +0100 <EvanR> something like that yeah
2023-12-02 20:20:29 +0100 <wroathe> Of course my concern with that approach is often that buffer sizes on handles are too small. I wonder if Haskell lets me manipulate that to avoid multiple writes...
2023-12-02 20:20:31 +0100alp_(~alp@2001:861:e3d6:8f80:2847:8bc:9af8:f09b)
2023-12-02 20:20:49 +0100 <cheater> ski: also, with your encoding I can't do something like accessSecretPage ... = case userState of { UserState NotLoggedIn -> ... show access error ...; UserState LoggedIn -> ... continue showing pagee ... }
2023-12-02 20:20:59 +0100 <geekosaur> hSetBuffering's BlockBuffering lets you specify a block size
2023-12-02 20:20:59 +0100 <cheater> which is very useful
2023-12-02 20:21:04 +0100 <glguy> wroathe: you can configure the buffer mode to a block size
2023-12-02 20:21:31 +0100 <monochrom> But what I don't understand is that if you use Builder, and if you realize it as a lazy bytestring and send it to writeFile (say), then the whole thing should stay in O(64KB) space.
2023-12-02 20:21:41 +0100 <wroathe> glguy: Perfect, yeah I see that in the docs of GHC.IO.Handle here
2023-12-02 20:21:49 +0100 <wroathe> Thanks guys
2023-12-02 20:21:56 +0100 <wroathe> I don't know why I thought Builder would be a good idea
2023-12-02 20:22:06 +0100xxpor(~xxpor@user/xxpor) (Ping timeout: 252 seconds)
2023-12-02 20:22:53 +0100 <wroathe> monochrom: I'm doing exactly that, and my program literally runs out of memory and the OOM killer kills my program
2023-12-02 20:22:54 +0100 <monochrom> hSetBuffering BlockBuffering needs just System.IO ...
2023-12-02 20:23:01 +0100mc47(~mc47@xmonad/TheMC47)
2023-12-02 20:23:06 +0100 <EvanR> it's a common belief that builder pattern = fast, e.g. blaze-html
2023-12-02 20:23:21 +0100 <cheater> but no builder pattern even faster!
2023-12-02 20:23:24 +0100 <EvanR> but there's a bunch of caveats
2023-12-02 20:23:31 +0100 <cheater> in fact, not outputting... even faster
2023-12-02 20:23:44 +0100 <monochrom> OK, I forgot: and if you don't keep the builder around otherwise.
2023-12-02 20:23:59 +0100 <wroathe> monochrom: I don't keep it around.
2023-12-02 20:24:01 +0100xxpor(~xxpor@user/xxpor)
2023-12-02 20:24:02 +0100 <monochrom> So, you use it linearly...
2023-12-02 20:24:56 +0100 <wroathe> monochrom: Here's a whittled down example of my larger program that exhibits the problem. Normally lines 21-23 aren't there, and 24 is uncommented: https://gist.github.com/JustinChristensen/9f6bba03c9d8a40ff0b520471661db0e
2023-12-02 20:25:20 +0100 <wroathe> Oh, whoops
2023-12-02 20:25:31 +0100 <wroathe> Ignore the BangPatterns. I was just trying something.
2023-12-02 20:25:40 +0100 <wroathe> The main program doesn't have those
2023-12-02 20:27:23 +0100 <wroathe> It only takes a 100M file for this thing to send my system into convulsions
2023-12-02 20:28:13 +0100 <EvanR> you might be building a 100000M builder then finally unspooling it to the output file
2023-12-02 20:28:25 +0100 <wroathe> EvanR: That's exactly what eventlog2html indicates I'm doing
2023-12-02 20:28:27 +0100 <EvanR> not very lazy
2023-12-02 20:28:34 +0100 <wroathe> That's the problem here
2023-12-02 20:28:47 +0100 <wroathe> So I think your suggestions to go right to IO are right on the money
2023-12-02 20:29:08 +0100 <monochrom> I am not impressed by "size <- recursiveSize $! fixedContents". If you have both that and "send to file/stdout", you are not using the builder linearly.
2023-12-02 20:29:27 +0100 <wroathe> Despite writing hobbyist programs in Haskell I still find it very hard to avoid laziness "gotchas" like this
2023-12-02 20:29:49 +0100 <EvanR> when IO is involved it can be tricky
2023-12-02 20:30:08 +0100 <EvanR> because mapM for example builds the whole list of results before continuing with IO
2023-12-02 20:30:14 +0100 <monochrom> We already know a very low tech way to describe and reproduce the issue. sum xs / length xs.
2023-12-02 20:31:16 +0100 <wroathe> monochrom: I just updated the gist to reflect what it normally is
2023-12-02 20:31:30 +0100 <wroathe> The `recursiveSize` stuff was just me getting some measurements
2023-12-02 20:31:47 +0100 <monochrom> OK this one looks good.
2023-12-02 20:31:54 +0100 <monochrom> But I guess I should test it.
2023-12-02 20:32:19 +0100 <cheater> ski: what do you think?
2023-12-02 20:33:02 +0100 <wroathe> monochrom: Knock yourself out :P I'm going to scrap this builder stuff and just do the IO writing approach that we discussed above
2023-12-02 20:33:30 +0100 <wroathe> I think EvanR was spot on when he said I was buffering up this huge Builder that writeFile was then fully evaluating before writing
2023-12-02 20:33:49 +0100 <EvanR> no
2023-12-02 20:33:52 +0100 <wroathe> I was trying to use this approach to process a directory of 24G of these text files :P
2023-12-02 20:34:05 +0100 <EvanR> it might not be fully evaluating, but that you have a giant nested thunk is just as bad
2023-12-02 20:34:31 +0100 <wroathe> "giant nested thunk" <- you're referring to the representation of Builder?
2023-12-02 20:34:46 +0100 <wroathe> The whole BuildStep a -> BuildStep a thing?
2023-12-02 20:34:47 +0100 <EvanR> if you build a builder wrong yeah it can be that
2023-12-02 20:35:01 +0100 <wroathe> How do you build a builder right?
2023-12-02 20:35:23 +0100 <EvanR> otoh when you're using builder it's probably because you needed to do it that way
2023-12-02 20:35:37 +0100 <EvanR> because you randomly appending and prepending stuff to the document
2023-12-02 20:36:09 +0100 <wroathe> My _hope_ with this was to get comparable performance to sed. I've got a shell script that does these steps already, but just for the hell of it I'm trying to avoid shell scripts and add it to the main haskell program
2023-12-02 20:36:26 +0100 <wroathe> Fun exercise to keep trying to understand these laziness gotchas
2023-12-02 20:39:24 +0100 <EvanR> are you just appending to the end of the "answer" repeatedly and then finally outputting it
2023-12-02 20:39:40 +0100 <EvanR> that's arguably wrong xD
2023-12-02 20:40:08 +0100 <EvanR> or equivalent to prepending to a list and finally reversing it before outputting
2023-12-02 20:40:13 +0100 <ski> cheater : `LogMeta :: UserStateTransition NotLoggedIn LoggedIn -> UserStateTransition Something Another' -- sure. but there'll still only be at most one `Foo' (strictly) inside a `Foo'
2023-12-02 20:40:46 +0100 <ski> cheater : "also, with your encoding I can't do something like accessSecretPage ... = case userState of { UserState NotLoggedIn -> ... show access error ...; UserState LoggedIn -> ... continue showing pagee ... }" -- how come ?
2023-12-02 20:40:48 +0100 <wroathe> EvanR: "wrong" in what sense?
2023-12-02 20:41:02 +0100 <cheater> ski: because in your encoding, UserState doesn't exist.
2023-12-02 20:41:04 +0100 <EvanR> if the goal was to process the file without using much memory
2023-12-02 20:41:15 +0100 <EvanR> it doesn't do that
2023-12-02 20:41:20 +0100xxpor(~xxpor@user/xxpor) (Ping timeout: 252 seconds)
2023-12-02 20:41:34 +0100 <ski> cheater : how does it exist in your original `Foo' version, then ?
2023-12-02 20:41:59 +0100 <wroathe> EvanR: Yes, we've already discussed that the Builder approach is very wrong for managing memory :P My goal is to use memory roughly equivalent to the size of the input file plus corrections, and then do one single system call to write
2023-12-02 20:42:11 +0100 <cheater> ski: because i defined it
2023-12-02 20:42:32 +0100 <EvanR> 100M bytes, times the overhead of handling each byte, it could be gigs
2023-12-02 20:42:35 +0100 <wroathe> But as we've pointed out using IO with setting the buffer size is going to help me with that nicely
2023-12-02 20:42:47 +0100 <wroathe> EvanR: Yup, that's exactly the problem with this Builder approach
2023-12-02 20:42:48 +0100 <cheater> ski: you can't have both. either state transitions are encoded in your way, or in my way. having both would suck
2023-12-02 20:43:21 +0100 <EvanR> so I would not shoot for using about 100M, shoot for using about 0M by doing it lazily?
2023-12-02 20:43:22 +0100xxpor(~xxpor@user/xxpor)
2023-12-02 20:43:37 +0100 <wroathe> EvanR: I also want it to be fast
2023-12-02 20:43:51 +0100 <EvanR> even better reason to use not much memory because gc
2023-12-02 20:43:59 +0100 <wroathe> EvanR: So what are you suggesting?
2023-12-02 20:44:06 +0100 <EvanR> gc cost is proportional to live heap
2023-12-02 20:44:14 +0100 <ski> cheater : you could easily have `data UserStateIs :: State -> * where LoggedInSing :: UserStateIs LoggedIn; LoggedOutSing :: UserStateIs LoggedOut', e.g.
2023-12-02 20:44:27 +0100 <wroathe> EvanR: Ok, so the IO with buffering approach is out. What are you suggesting?
2023-12-02 20:44:45 +0100JeremyB99(~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069)
2023-12-02 20:44:46 +0100 <wroathe> This `Builder` thing is already lazy, and it sucks
2023-12-02 20:44:49 +0100 <cheater> ski: what is "Sing"?
2023-12-02 20:44:53 +0100 <EvanR> wrong kind of lazy
2023-12-02 20:44:55 +0100 <wroathe> So not sure how increasing laziness is going to help
2023-12-02 20:45:03 +0100 <EvanR> I mean incremental processing
2023-12-02 20:45:10 +0100 <ski> (cheater : i can't tell whether that'd be useful, though, since i dunno how you intended to use `UserState NotLoggedIn' with your original `Foo' approach .. since you didn't provide a concrete example, really)
2023-12-02 20:45:15 +0100 <ski> cheater : "Singletons"
2023-12-02 20:45:23 +0100 <wroathe> "incremental processing" is just a function of how large I define my IO buffer to be in this sense, isn't it?
2023-12-02 20:45:52 +0100 <wroathe> EvanR: You suggested "incremental processing" with a past issue I brought in here before and you gave a similar justification (fear of the GC). Can you be more specific on how you'd implement that in this case?
2023-12-02 20:45:53 +0100 <EvanR> I got the impression you were trying to buffer the entire file
2023-12-02 20:45:58 +0100 <cheater> ski: idk how singletons are used. but anyways, you made an error. I didn't have a UserState Foo type. I had UserStateTransition.
2023-12-02 20:46:21 +0100 <wroathe> EvanR: I might. Like I did in my C days I'll tweak the size of the buffer until I get an acceptable balance of memory use and speed
2023-12-02 20:46:29 +0100 <EvanR> yeah that's not how incremental works
2023-12-02 20:46:34 +0100 <wroathe> It doesn't need to be one single write, but in general I/O works
2023-12-02 20:46:38 +0100 <cheater> so you have a UserStateTransition (directed edges) that lives on something we could call UserState (vertices)
2023-12-02 20:46:40 +0100 <wroathe> I/O is expensive*
2023-12-02 20:46:52 +0100 <wroathe> EvanR: Sure, so what should I do?
2023-12-02 20:47:31 +0100 <EvanR> you're doing something like a sed substitution? you have an automaton which looks at each byte and outputs zero or more processed bytes?
2023-12-02 20:47:36 +0100 <wroathe> Right
2023-12-02 20:48:45 +0100 <EvanR> if you just loop readByte and writeByte whatever comes out immediately, it will be better than the 1000gigs of memory usage so far xD
2023-12-02 20:49:12 +0100 <wroathe> EvanR: That's exactly what we said the solution should be above, isn't it?
2023-12-02 20:49:24 +0100 <wroathe> It kind of feels like you're wrapping up what we discussed in buzz words :P
2023-12-02 20:49:24 +0100 <EvanR> maybe!
2023-12-02 20:49:56 +0100 <wroathe> Almost immediately in this conversation I was told to just read characters and write them back out
2023-12-02 20:50:02 +0100 <EvanR> I know!
2023-12-02 20:50:12 +0100 <EvanR> i agree with that suggestion
2023-12-02 20:50:15 +0100 <cheater> ski: so you'd have data UserState = LoggedIn | NotLoggedIn | Deleted | ... (some other stuff here), and then you'd have data UserStateTransition where LogIn :: UserStateTx NotLoggedIn -> Password -> UserStateTx LoggedIn
2023-12-02 20:50:17 +0100 <EvanR> characters / bytes
2023-12-02 20:50:18 +0100 <wroathe> I suppose the difference with what you're saying is to avoid `readFile` entirely and just using the IO plumbing on both sides
2023-12-02 20:50:35 +0100 <EvanR> sure
2023-12-02 20:50:48 +0100 <wroathe> EvanR: Do you have some kind of reading I can do on "incremental processing"? We've had this exact conversation before, and I get the sense that it forms a very foundational aspect of how you think of Haskell programming
2023-12-02 20:50:49 +0100 <cheater> ski: by keeping vertices and edges apart, you can do a case, matching on what vertex you're on
2023-12-02 20:51:01 +0100Sgeo(~Sgeo@user/sgeo)
2023-12-02 20:51:19 +0100 <wroathe> I.e. fear of heap usage - do everything "incrementally"
2023-12-02 20:51:33 +0100 <wroathe> I get the sense that the Haskell GC is an entity to be feared
2023-12-02 20:51:34 +0100 <ski> cheater : perhaps i missed it, but your initial question, afaics, was about a `Foo' GADT, didn't mention `UserState' at all (which is fine). then, you introduced a briefly sketched example mentioning `LogOut :: UserState LoggedIn -> UserState NotLoggedIn' (and i commented on an idea to factor the "listness" out of this). but i'm not clear on how that would connect to your later `case userState of { UserState
2023-12-02 20:51:40 +0100 <ski> NotLoggedIn -> ... show access error ...; UserState LoggedIn -> ... continue showing pagee ... }' -- since in this case, `UserState' is a data constructor, not a type constructor (but i suggested one could use singletons to "reflect" these back to value level)
2023-12-02 20:51:42 +0100 <wroathe> GHC* GC
2023-12-02 20:52:04 +0100 <EvanR> there are certainly ways to make a mistake and use an egregious amount of heap
2023-12-02 20:52:05 +0100 <ski> cheater : "by keeping vertices and edges apart, you can do a case, matching on what vertex you're on" -- sounds ok, to me
2023-12-02 20:52:07 +0100 <cheater> ski: yes. my initial question was a simplification, and later i motivated it with the UserState / UserStateTransition example
2023-12-02 20:52:31 +0100 <EvanR> which may or may not still work, but be wasteful. In the worst case it's so bad you get killed
2023-12-02 20:52:56 +0100 <EvanR> wroathe, what is the form of your automaton. Something like Char -> s -> ([Char], s) ?
2023-12-02 20:53:11 +0100 <ski> cheater : in `data UserState = LoggedIn | NotLoggedIn | Deleted | ...', we have `UserState :: *'. but in 'case userState of { UserState NotLoggedIn -> .... }', what is `UserState' here ? is it another data constructor, of type `UserState -> SomethingHer' ?
2023-12-02 20:53:20 +0100 <wroathe> EvanR: Well, in general if I was doing this kind of I/O work in C and I knew how big my input would be and how much memory my system has, I was seek to strike a balance between heap usage and minimizing I/O operations
2023-12-02 20:53:41 +0100 <cheater> ski: sorry that was a typo, in that case, just delete the "UserState" label
2023-12-02 20:53:46 +0100 <duncan> Except we never have that luxury, do we?
2023-12-02 20:53:52 +0100 <ski> cheater : oh, okay. ty
2023-12-02 20:54:05 +0100 <cheater> it should have been case userState of { NotLoggedIn -> ... }
2023-12-02 20:54:06 +0100 <EvanR> sure loading an entire 100M file is not a problem in this day and age. Because we have more memory now. But do you want to try that with 100gig file? Either way it's not incremental
2023-12-02 20:54:09 +0100 <ski> i see
2023-12-02 20:54:32 +0100 <wroathe> EvanR: And what I'm saying is that this "incremental" thing you keep pushing sounds like a buzz word unless you get to specifics
2023-12-02 20:54:38 +0100 <EvanR> loading the 100M file and operating on it in ghc, I think you would do better to use the compact region support
2023-12-02 20:54:48 +0100 <EvanR> because the 100M file loaded won't be copy collected or moved or even traversed
2023-12-02 20:54:56 +0100 <EvanR> so you can do your C way in a sense
2023-12-02 20:55:44 +0100 <ski> cheater : anyway, i don't really see a problem with the approach i suggested, yet. perhaps if you elaborate more ?
2023-12-02 20:55:46 +0100 <EvanR> wroathe, incremental would be like, if you had an automaton like Char -> s -> ([Char], s), then loop getChar, apply that function to the current state, output the resulting chars, repeat
2023-12-02 20:55:59 +0100 <cheater> ski: with your approach, I don't have a UserState
2023-12-02 20:56:05 +0100 <EvanR> s would be a very small state data structure
2023-12-02 20:56:45 +0100 <wroathe> EvanR: This is exactly what was proposed above. i think the only question is how much buffering to do on either end of that transaction
2023-12-02 20:56:52 +0100 <wroathe> I could for example make it completely unbuffered reads and writes
2023-12-02 20:57:03 +0100 <EvanR> that's a trivial configuration option with no bearing on your code
2023-12-02 20:57:05 +0100 <wroathe> And that would be another pathological case, but I get the sense that would fit into your definition of "incremental"
2023-12-02 20:57:19 +0100 <EvanR> if you just leave it at a default it will be better than before
2023-12-02 20:57:33 +0100 <ski> cheater : with your original `LogOut :: UserState LoggedIn -> UserState NotLoggedIn', you have it (`data UserState = LoggedIn | NotLoggedIn | Deleted | ...', where this `UserState' is distinct from the one in the type of `LogOut') as much or as little as with my approach, afics
2023-12-02 20:57:36 +0100 <wroathe> Well, yeah, we know that buffering everything up as a Builder is wrong. We learned that at the start of this :D
2023-12-02 20:57:38 +0100 <ski> s/afics/afaics/
2023-12-02 20:58:03 +0100 <ski> (it doesn't really help here that multiple distinct things have been called `UserState' in this discussion)
2023-12-02 20:58:21 +0100 <cheater> ski: yes, I should have used a different name for that wrapper there
2023-12-02 20:58:49 +0100 <cheater> ok, let's take new names
2023-12-02 20:58:56 +0100 <ski> for the former, or the latter, `UserState', that i mentioned in that message ?
2023-12-02 21:00:13 +0100 <ski> (again, this is why i'd preferred a more fleshed out example)
2023-12-02 21:01:07 +0100 <ski> (e.g. with a paste to start from, it would have been easier to suggest a paste adapted to a suggested change)
2023-12-02 21:01:20 +0100 <ski> (bbiam)
2023-12-02 21:02:02 +0100megaTherion(~therion@unix.io) (Quit: ZNC 1.8.2 - https://znc.in)
2023-12-02 21:02:28 +0100 <cheater> data ShoppingCartState = Empty | Items [Item] | Checkout; data ShoppingCartTransition ... where NewCart :: State Empty; AddFirstItem :: State Empty -> Item -> State Items; AddSubsequentItem :: State Items -> Item -> State Items; GoCheckout :: StateItems -> State Checkout; FinalizeCheckout :: State Checkout -> State Empty; AbandonCart :: State Items -> State Empty
2023-12-02 21:02:41 +0100 <cheater> ski ^
2023-12-02 21:03:05 +0100 <cheater> let me know if you accept this as valid code (i have no way to test it)
2023-12-02 21:03:09 +0100megaTherion(~therion@unix.io)
2023-12-02 21:03:17 +0100 <EvanR> wroathe, in an idiomatic incrementally process program I get something like 30k in heap usage regardless of the size of the file. If 100M of file is loaded as a vector of Word8, then a lot more than 30k would potentially moved around as part of gc. However, ByteStrings live in pinned memory so that's actually not an issue...
2023-12-02 21:03:23 +0100megaTherion(~therion@unix.io) (Client Quit)
2023-12-02 21:03:56 +0100johnw(~johnw@69.62.242.138)
2023-12-02 21:03:56 +0100 <EvanR> if you load it as a single ByteString
2023-12-02 21:04:14 +0100wroathe(~wroathe@user/wroathe) (Ping timeout: 260 seconds)
2023-12-02 21:04:26 +0100megaTherion(~therion@unix.io)
2023-12-02 21:05:11 +0100simendsjo(~user@84.209.170.3)
2023-12-02 21:06:23 +0100Eoco(~ian@128.101.131.218)
2023-12-02 21:10:23 +0100megaTherion(~therion@unix.io) (Quit: ZNC 1.8.2 - https://znc.in)
2023-12-02 21:11:28 +0100megaTherion(~therion@unix.io)
2023-12-02 21:11:58 +0100machinedgod(~machinedg@modemcable243.147-130-66.mc.videotron.ca)
2023-12-02 21:14:51 +0100mobivme(~mobivme@112.201.111.217) (Ping timeout: 259 seconds)
2023-12-02 21:14:58 +0100simendsjo(~user@84.209.170.3) (Ping timeout: 260 seconds)
2023-12-02 21:18:49 +0100Eoco(~ian@128.101.131.218) (Remote host closed the connection)
2023-12-02 21:21:16 +0100Inst(~Inst@120.244.192.187) (Read error: Connection reset by peer)
2023-12-02 21:27:17 +0100 <ski> cheater : well, you could do `data ShoppingCartState = Empty | Items' and then
2023-12-02 21:27:27 +0100 <ski> data ShoppingCart :: ShoppingCartState -> *
2023-12-02 21:27:29 +0100 <ski> where
2023-12-02 21:27:41 +0100 <ski> NewCart :: ShoppingCart Empty
2023-12-02 21:27:47 +0100 <ski> AddFirstItem :: ShoppingCart Empty -> Item -> ShoppingCart Items
2023-12-02 21:27:57 +0100 <ski> AddSubsequentItem :: ShoppingCart Items -> Item -> ShoppingCart Items
2023-12-02 21:28:03 +0100 <ski> GoCheckout :: ShoppingCart Items -> ShoppingCart Checkout
2023-12-02 21:28:15 +0100 <ski> FinalizeCheckout :: ShoppingCart Checkout -> ShoppingCart Empty
2023-12-02 21:28:18 +0100 <ski> AbandonCart :: ShoppingCart Items -> ShoppingCart Empty
2023-12-02 21:28:34 +0100 <ski> (well, add `Checkout' as an alternative to `ShoppingCartState' as well)
2023-12-02 21:29:00 +0100 <ski> that seems to me to be the most direct way of adapting your list snippet to something that type-checks, and seems at least somewhat reasonable
2023-12-02 21:29:08 +0100Eoco(~ian@128.101.131.218)
2023-12-02 21:32:21 +0100 <ski> but then, one could wonder, what is the use of adding all these actions (add item,checkout,finalize,abandom) to such a trace ?
2023-12-02 21:32:29 +0100alp_(~alp@2001:861:e3d6:8f80:2847:8bc:9af8:f09b) (Ping timeout: 252 seconds)
2023-12-02 21:33:00 +0100 <ski> (perhaps some of these could be functions that you invoke, rather than data constructors ?)
2023-12-02 21:34:02 +0100 <cheater> how is the code you posted different from the code i posted?
2023-12-02 21:35:04 +0100 <cheater> ah yeah, ShoppingCart instead of State
2023-12-02 21:35:31 +0100 <ski> also i skipped the argument to `Items'
2023-12-02 21:35:51 +0100Square(~Square@user/square) (Ping timeout: 260 seconds)
2023-12-02 21:35:51 +0100 <cheater> skipped or forgot?
2023-12-02 21:36:14 +0100 <cheater> i guess it doesn't matter
2023-12-02 21:36:15 +0100 <cheater> "what is the use of adding all these actions (add item,checkout,finalize,abandom) to such a trace ?" well, the idea is to encode a state machine and its allowed transitions. that's all.
2023-12-02 21:36:30 +0100 <ski> skipped
2023-12-02 21:37:00 +0100 <ski> (since you didn't use that anyway, in the types of `AddFirstItem',`AddSubSequentItem',..)
2023-12-02 21:37:48 +0100 <cheater> OK
2023-12-02 21:38:21 +0100 <ski> (the actual list of items is part of the dynamic state. the parameters/indices passed to `ShoppingCart', in the type of the data constructors above, are "static state", probably wouldn't include the specific items)
2023-12-02 21:39:37 +0100 <EvanR> so ShoppingCart is a language where the only sentences / programs represent a sequence of actions you could take on an "offscreen" shopping cart
2023-12-02 21:39:50 +0100mobivme(~mobivme@112.201.111.217)
2023-12-02 21:39:56 +0100 <cheater> yeah, you wouldn't generally want to disallow "GoCheckout" if the Items value contained a RedBicycle
2023-12-02 21:39:59 +0100 <EvanR> and unallowed actions couldn't be represented
2023-12-02 21:40:25 +0100 <EvanR> action sequences
2023-12-02 21:40:53 +0100 <cheater> i'm with you so far
2023-12-02 21:41:09 +0100 <EvanR> that's all I got xD
2023-12-02 21:41:21 +0100 <cheater> well, there's a difference between what i'm saying and what you're saying
2023-12-02 21:43:05 +0100 <cheater> when building a language with a GADT you want some sort of data Term where you have both flat Terms defined (like Term Int) and transitions (like MultiplyByTwo :: Term Int -> Term Int). but the idea is to be able to have a case statement that does not accept transitions, only flat values
2023-12-02 21:43:35 +0100 <EvanR> hmm
2023-12-02 21:43:57 +0100Eoco(~ian@128.101.131.218) (Remote host closed the connection)
2023-12-02 21:44:03 +0100 <EvanR> you mean like, evaluated "value" terms and non-value reducible terms?
2023-12-02 21:44:17 +0100 <cheater> so like, it would be acceptable if i could say: "in this GADT, when case analysis is being done, there should be two different options for case analysis: either you're analyzing the flat values, or the transitions, but you never mix them in one case analysis"
2023-12-02 21:45:01 +0100 <ski> `ShoppingCart' above seems to embody the transitions .. what would the corresponding "flat" values be ?
2023-12-02 21:45:44 +0100 <cheater> according to the code you posted, ShoppingCartState
2023-12-02 21:46:41 +0100 <ski> but that's on type-level, not value-level
2023-12-02 21:46:48 +0100 <ski> (the way it's used here)
2023-12-02 21:46:50 +0100Eoco(~ian@128.101.131.218)
2023-12-02 21:47:08 +0100 <ski> (note that the `Items' alternative, in my take, did not include `[Item]')
2023-12-02 21:47:26 +0100 <cheater> what's "on type-level"?
2023-12-02 21:47:40 +0100 <ski> would your "flat values" alternative for `Items' include `[Item]' ?
2023-12-02 21:47:50 +0100 <cheater> yes
2023-12-02 21:48:09 +0100 <ski> cheater : `ShoppingCartState' is only used on type-level, in my snippet above
2023-12-02 21:48:28 +0100 <cheater> yes, but the way you defined it, ShoppingCartState is good for case analysis
2023-12-02 21:48:33 +0100 <ski> mhm, so you then want a separate dynamic / value-level version of that, i suppose
2023-12-02 21:48:40 +0100 <cheater> just like previously we were doing a case over whether the user is logged in or not
2023-12-02 21:49:37 +0100 <ski> cheater : "the way you defined it, ShoppingCartState is good for case analysis" -- no, not really .. at least, you couldn't usefully do case analysis on `Empty'/`Items'/`Checkout' themselves, with my snippet
2023-12-02 21:50:00 +0100 <cheater> why couldn't you?
2023-12-02 21:50:28 +0100 <ski> (you could do case analysis of transitions in `ShoppingCart', and have that give you information about the corresponding `ShoppingCartState's, though)
2023-12-02 21:51:16 +0100 <ski> cheater : because there are no values of type `ShoppingCartState' involved in my snippet. *only* *types* of kind `ShoppingCartState'
2023-12-02 21:51:57 +0100 <ski> (and, because Haskell has no dependent types, you can't connect values of type `ShoppingCartState' to types of kind `ShoppingCartState' .. except indirectly, if you do singletons)
2023-12-02 21:52:06 +0100 <cheater> yes? and why does that mean i can't write case cartState of ... ?
2023-12-02 21:52:18 +0100 <cheater> hm...
2023-12-02 21:52:26 +0100 <ski> you can't do
2023-12-02 21:52:52 +0100 <ski> foo :: (cartState :: ShoppingCartState) -> ShoppingCart cartState -> ...
2023-12-02 21:52:55 +0100 <ski> in Haskell
2023-12-02 21:52:55 +0100mobivme(~mobivme@112.201.111.217) (Ping timeout: 256 seconds)
2023-12-02 21:53:13 +0100 <ski> you can do
2023-12-02 21:53:26 +0100 <ski> foo :: ShoppingCartStateIs cartState -> ShoppingCart cartState -> ...
2023-12-02 21:53:35 +0100 <ski> if `ShoppingCartStateIs' is a singlton
2023-12-02 21:54:12 +0100 <ski> (but then `foo' isn't called with `cartState', but a singleton version of it)
2023-12-02 21:54:15 +0100fendor(~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c) (Remote host closed the connection)
2023-12-02 21:54:30 +0100 <cheater> i don't really know what singletons are
2023-12-02 21:54:33 +0100 <cheater> i gotta go do some work
2023-12-02 21:54:38 +0100 <cheater> we can pick this up some other time
2023-12-02 21:56:03 +0100 <ski> singletons are a way to make a family of types (indexed by some datakind, like `ShoppingCartState' above e.g.), each having exactly one (non-partial) value, such that the values of the singleton type corresponds exactly to the values of this datakind
2023-12-02 21:56:49 +0100 <ski> (well, perhaps i shouldn't say "family", since "type family" has a technical meaning in Haskell (extensions) .. i didn't mean that in particular)
2023-12-02 22:02:21 +0100 <steew> hello, what was the name of the function that grouped same elements from a list, returning that group and the rest of the elements that didn't match?
2023-12-02 22:04:39 +0100 <ski> > takeWhile isDigit "0123abc45d"
2023-12-02 22:04:40 +0100 <lambdabot> "0123"
2023-12-02 22:04:45 +0100mc47(~mc47@xmonad/TheMC47) (Remote host closed the connection)
2023-12-02 22:04:52 +0100 <ski> > span isDigit "0123abc45d"
2023-12-02 22:04:54 +0100 <lambdabot> ("0123","abc45d")
2023-12-02 22:05:17 +0100 <ski> > group "mississippi"
2023-12-02 22:05:19 +0100 <lambdabot> ["m","i","ss","i","ss","i","pp","i"]
2023-12-02 22:05:38 +0100 <EvanR> :t partition
2023-12-02 22:05:39 +0100 <lambdabot> (a -> Bool) -> [a] -> ([a], [a])
2023-12-02 22:05:52 +0100 <ski> was just about to mention that one, as well :)
2023-12-02 22:05:57 +0100 <EvanR> > partition isDigit "m1551551pp1"
2023-12-02 22:05:59 +0100 <lambdabot> ("15515511","mpp")
2023-12-02 22:06:05 +0100 <ski> > partition isDigit "0123abc45d"
2023-12-02 22:06:06 +0100 <lambdabot> ("012345","abcd")
2023-12-02 22:06:36 +0100 <EvanR> we have at least 3 ways to "group" and no ways to split xD
2023-12-02 22:06:48 +0100 <EvanR> though you could iterate span
2023-12-02 22:07:05 +0100 <steew> ski: thank you, it was span
2023-12-02 22:08:04 +0100 <ski> steew : parsing ?
2023-12-02 22:08:21 +0100 <ski> > (reads :: ReadS Int) "0123abc45d"
2023-12-02 22:08:22 +0100 <lambdabot> [(123,"abc45d")]
2023-12-02 22:08:44 +0100 <steew> yes, I am
2023-12-02 22:08:52 +0100 <steew> namely, advent of code
2023-12-02 22:08:59 +0100 <ski> `reads' could possibly be useful, in that case
2023-12-02 22:09:20 +0100CrunchyFlakes(~CrunchyFl@ip92348280.dynamic.kabel-deutschland.de) (Ping timeout: 252 seconds)
2023-12-02 22:09:29 +0100 <steew> I mostly have set it up with parsec, although im finding a way to solve something specific
2023-12-02 22:10:05 +0100 <steew> I'm probably doing it more complex than it should hehe
2023-12-02 22:10:20 +0100CrunchyFlakes(~CrunchyFl@ip92348280.dynamic.kabel-deutschland.de)
2023-12-02 22:14:04 +0100 <EvanR> from where did I hallucinate a function of type (a -> Maybe b) -> [a] -> [b]
2023-12-02 22:14:35 +0100 <EvanR> I'm sure it's in MissingH but is there a more respectable source xD
2023-12-02 22:14:45 +0100 <ski> @type mapMaybe
2023-12-02 22:14:46 +0100 <lambdabot> (a -> Maybe b) -> [a] -> [b]
2023-12-02 22:14:50 +0100 <EvanR> oh
2023-12-02 22:15:02 +0100 <ski> @index mapMaybe
2023-12-02 22:15:02 +0100 <lambdabot> Data.Maybe, Data.IntMap.Strict, Data.IntMap.Lazy, Data.IntMap, Data.Map.Strict, Data.Map.Lazy, Data.Map
2023-12-02 22:17:08 +0100coot(~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot)
2023-12-02 22:17:25 +0100 <monochrom> @tell wroathe https://paste.tomsmeding.com/k4GePgDO
2023-12-02 22:17:25 +0100 <lambdabot> Consider it noted.
2023-12-02 22:20:45 +0100tcard(~tcard@2400:4051:5801:7500:cf17:befc:ff82:5303) (Quit: Leaving)
2023-12-02 22:22:47 +0100tcard(~tcard@2400:4051:5801:7500:cf17:befc:ff82:5303)
2023-12-02 22:26:29 +0100machinedgod(~machinedg@modemcable243.147-130-66.mc.videotron.ca) (Ping timeout: 256 seconds)
2023-12-02 22:47:00 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2023-12-02 22:57:10 +0100tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2023-12-02 22:57:27 +0100gmg(~user@user/gehmehgeh) (Quit: Leaving)
2023-12-02 22:59:31 +0100Alatheia(~Alatheia@176.254.244.83) (Ping timeout: 245 seconds)
2023-12-02 23:00:34 +0100gmg(~user@user/gehmehgeh)
2023-12-02 23:00:57 +0100L29Ah(~L29Ah@wikipedia/L29Ah)
2023-12-02 23:01:03 +0100mobivme(~mobivme@112.201.111.217)
2023-12-02 23:03:32 +0100gmg(~user@user/gehmehgeh) (Remote host closed the connection)
2023-12-02 23:04:20 +0100gmg(~user@user/gehmehgeh)
2023-12-02 23:05:12 +0100Eoco(~ian@128.101.131.218) (Quit: WeeChat 2.3)
2023-12-02 23:05:36 +0100Eoco(~ian@128.101.131.218)
2023-12-02 23:14:22 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 276 seconds)
2023-12-02 23:18:07 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 240 seconds)
2023-12-02 23:20:38 +0100Eoco(~ian@128.101.131.218) (Quit: WeeChat 4.1.1)
2023-12-02 23:21:06 +0100Eoco(~ian@128.101.131.218)
2023-12-02 23:22:51 +0100monochrom(trebla@216.138.220.146) (Quit: ZNC 1.8.2+deb3.1 - https://znc.in)
2023-12-02 23:23:02 +0100monochrom(trebla@216.138.220.146)
2023-12-02 23:26:10 +0100dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net)
2023-12-02 23:29:59 +0100bitdex(~bitdex@gateway/tor-sasl/bitdex)
2023-12-02 23:32:05 +0100mobivme(~mobivme@112.201.111.217) (Ping timeout: 268 seconds)
2023-12-02 23:33:39 +0100Incredia(~Incredia@176.254.244.83)
2023-12-02 23:36:20 +0100Ranhir(~Ranhir@157.97.53.139)
2023-12-02 23:39:42 +0100zetef(~quassel@2a02:2f00:5201:4b00:7fc8:6fbe:33d9:ba2a) (Read error: Connection reset by peer)
2023-12-02 23:39:53 +0100szkl(uid110435@id-110435.uxbridge.irccloud.com)
2023-12-02 23:41:28 +0100 <tomsmeding> monochrom: doesn't that have the same problem as what they did before, where you have a Builder item per byte, which is a lot of overhead?
2023-12-02 23:41:42 +0100 <tomsmeding> or is the whole premise that that is too much overhead simply wrong
2023-12-02 23:42:53 +0100 <monochrom> The previous major issue was Theta(n) space vs O(1) space.
2023-12-02 23:43:12 +0100 <tomsmeding> ah, I apparently missed some code in the meantime :)
2023-12-02 23:44:37 +0100 <monochrom> We can argue and benchmark Builder's constant-multiplier efficiency/cost, but first I must clear its name of linear-space allegations!
2023-12-02 23:51:28 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net)
2023-12-02 23:52:37 +0100takuan(~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection)
2023-12-02 23:56:30 +0100nate4(~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 256 seconds)
2023-12-02 23:57:49 +0100notzmv(~zmv@user/notzmv) (Ping timeout: 255 seconds)
2023-12-02 23:58:28 +0100johnw(~johnw@69.62.242.138) (Quit: ZNC - http://znc.in)