2026/04/06

Newest at the top

2026-04-06 11:10:41 +0000 <ski> (a direct recursion would also be fine)
2026-04-06 11:10:20 +0000 <ski> if you define the `foldr' version, i can then explain why it's better here
2026-04-06 11:09:53 +0000 <fp`> But why would foldr be better? Since I'm iterating through the list backward, I can't even start thinking about IO actions until I know what the first thing to print is
2026-04-06 11:09:22 +0000 <ski> and `>>=' is "bind"
2026-04-06 11:09:12 +0000 <gentauro> (Y)
2026-04-06 11:09:08 +0000 <ski> "then"
2026-04-06 11:09:03 +0000 <gentauro> ski: what's the name of the `>>` operator? https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#v:-62--62-
2026-04-06 11:07:02 +0000 <ski> so, you can see that the accumulator keeps growing, as `foldl' continues looping through the list, requiring more and more space to be allocated
2026-04-06 11:06:30 +0000 <ski> and only at this point can we start performing, executing, the `putChar' actions
2026-04-06 11:06:15 +0000 <ski> = return () >> putChar 'a' >> putChar 'b' >> putChar 'c'
2026-04-06 11:06:09 +0000 <ski> = foldl (\acc c -> acc >> putChar c) (return () >> putChar 'a' >> putChar 'b' >> putChar 'c') []
2026-04-06 11:06:02 +0000 <ski> = foldl (\acc c -> acc >> putChar c) (return () >> putChar 'a' >> putChar 'b') ['c']
2026-04-06 11:05:54 +0000 <ski> = foldl (\acc c -> acc >> putChar c) (return () >> putChar 'a') ['b','c']
2026-04-06 11:05:44 +0000 <ski> = foldl (\acc c -> acc >> putChar c) (return ()) ['a','b','c']
2026-04-06 11:05:27 +0000 <ski> putStr' ['a','b','c']
2026-04-06 11:05:21 +0000merijn(~merijn@host-cl.cgnat-g.v4.dfn.nl) (Ping timeout: 272 seconds)
2026-04-06 11:05:21 +0000 <ski> then the evaluation trace looks like
2026-04-06 11:05:05 +0000 <ski> putStr' str = foldl (\acc c -> acc >> putChar c) (return ()) str
2026-04-06 11:04:53 +0000 <ski> let's assume you defined
2026-04-06 11:04:42 +0000fun-safe-math(~fun-safe-@97.115.234.213) fun-safe-math
2026-04-06 11:04:26 +0000 <ski> with `foldl', it *always* executes to the end (reaching the end of the list), before providing any result back to its caller. it's "bulky". so you can't start performing `IO'-sub-actions here, until you've seen the whole list
2026-04-06 11:03:39 +0000 <ski> this is because `foldr' can be incremental (depending on the callback you pass it), can return parts of the result, piecemeal, so that you can start executing sub-actions, before you've determined all the sub-actions
2026-04-06 11:02:40 +0000 <ski> using `foldr', you can do `putStr' in constant space. with `foldl', it's not constant space
2026-04-06 11:02:31 +0000fun-safe-math(~fun-safe-@97.115.234.213) ()
2026-04-06 11:02:03 +0000 <fp`> But why foldr? My understanding is that one uses foldr for its laziness, which benefits for infinitely long lists, but surely people don't want to print infinitely long strings
2026-04-06 11:00:05 +0000merijn(~merijn@host-cl.cgnat-g.v4.dfn.nl) merijn
2026-04-06 10:59:56 +0000 <fp`> Ah yeah
2026-04-06 10:59:51 +0000 <ski> putChar '\n' >> putChar 'a' >> putChar 'b' >> putChar 'c'
2026-04-06 10:59:32 +0000 <ski> that would give you
2026-04-06 10:59:26 +0000 <ski> "I'd just initialize the acc to putChar '\n'" -- no
2026-04-06 10:59:11 +0000 <ski> now, try to use `foldr' rather than `foldl'
2026-04-06 10:59:03 +0000 <ski> yes, that's correct
2026-04-06 10:58:18 +0000TimWolla(~timwolla@2a01:4f8:150:6153:beef::6667) TimWolla
2026-04-06 10:57:40 +0000 <fp`> And I guess if I wanted to make putStrLn', I'd just initialize the acc to putChar '\n'
2026-04-06 10:56:48 +0000 <fp`> Ok yeah I was able to come up with this after perusing the docs of IO, so the lambda should be (\acc c -> acc >> putChar c)
2026-04-06 10:50:59 +0000 <yahb2> ab
2026-04-06 10:50:59 +0000 <ski> % do putChar 'a'; putChar 'b'
2026-04-06 10:50:51 +0000 <ski> you could also use `do', if you prefer
2026-04-06 10:50:40 +0000 <ski> so, try combining your `putChar c' with the `acc' action (representing everything you're planning to do with all the previous `Char'acters you've seen, so far, in the list), combining them with the `>>' operator
2026-04-06 10:50:01 +0000TimWolla(~timwolla@2a01:4f8:150:6153:beef::6667) (Quit: Bye)
2026-04-06 10:49:45 +0000 <ski> that is a single compound action, that performs those two sub-actions, in that order, when it is executed
2026-04-06 10:49:21 +0000 <lambdabot> IO ()
2026-04-06 10:49:20 +0000 <ski> @type putChar 'a' >> putChar 'b'
2026-04-06 10:49:15 +0000 <yahb2> ab
2026-04-06 10:49:15 +0000 <ski> % putChar 'a' >> putChar 'b'
2026-04-06 10:49:13 +0000merijn(~merijn@host-cl.cgnat-g.v4.dfn.nl) (Ping timeout: 248 seconds)
2026-04-06 10:49:02 +0000 <ski> and the `>>' operator is good for this
2026-04-06 10:48:53 +0000 <ski> but that "queue" can just be a single, compound, `IO'-action, that contains all the `putChar' calls, in sequence
2026-04-06 10:48:30 +0000 <ski> yes, basically
2026-04-06 10:48:19 +0000 <ski> (of course, only if your `IO'-action is a part of a branch of execution that's activated in `main' will it be executed)