Newest at the top
| 2026-04-06 11:41:46 +0000 | <ski> | (you could pass the same list to two different places. one might use `_' (not forcing), while the other might force it, naming) |
| 2026-04-06 11:41:43 +0000 | merijn | (~merijn@host-cl.cgnat-g.v4.dfn.nl) (Ping timeout: 264 seconds) |
| 2026-04-06 11:40:45 +0000 | <ski> | of course, if it's not named, then you're not forcing it (unless you use a strictness annotation, e.g. `!_'), so it's not forced unless someone else is forcing it, elsewhere |
| 2026-04-06 11:40:34 +0000 | <fp`> | I see |
| 2026-04-06 11:40:03 +0000 | <ski> | what matters is whether the parameter is used/demanded/forced, not really whether it's named |
| 2026-04-06 11:39:42 +0000 | <ski> | it would also have ignored `x', still short-circuiting |
| 2026-04-06 11:39:33 +0000 | <ski> | True || x = True |
| 2026-04-06 11:39:27 +0000 | <ski> | but if it had said |
| 2026-04-06 11:39:24 +0000 | <ski> | yes, in this case |
| 2026-04-06 11:39:19 +0000 | <ski> | the short-circuiting is not built-in, is just a consequence of how `||' is defined, and how lazy evaluation works |
| 2026-04-06 11:39:03 +0000 | <fp`> | So the `_' is what causes the short circuiting? |
| 2026-04-06 11:34:43 +0000 | <ski> | that short-circuits, does not evaluate the right parameter, in case the left is `True' |
| 2026-04-06 11:34:27 +0000 | <lambdabot> | False || x = x |
| 2026-04-06 11:34:27 +0000 | <lambdabot> | True || _ = True |
| 2026-04-06 11:34:26 +0000 | <ski> | @src (||) |
| 2026-04-06 11:34:22 +0000 | <ski> | but yes, the implementor of `||' (or whichever callback you're using) |
| 2026-04-06 11:33:54 +0000 | <ski> | there is no `:' is the result of `foldr' |
| 2026-04-06 11:33:44 +0000 | <ski> | not quite that |
| 2026-04-06 11:33:41 +0000 | merijn | (~merijn@host-cl.cgnat-g.v4.dfn.nl) merijn |
| 2026-04-06 11:33:26 +0000 | tromp | (~textual@2001:1c00:340e:2700:795f:6a6f:7cb5:ecd6) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 2026-04-06 11:29:38 +0000 | <fp`> | and the short-circuiting logic is down to... the implementor of (||)? Or ghc? Or is there even a runtime component? |
| 2026-04-06 11:28:42 +0000 | <fp`> | foldr f acc x:xs = (f x acc) : (foldr f acc xs) |
| 2026-04-06 11:28:41 +0000 | <fp`> | So foldr looks something like this (with an additional boundary condition) |
| 2026-04-06 11:28:22 +0000 | <lambdabot> | True |
| 2026-04-06 11:28:21 +0000 | <ski> | > foldr (||) False (map (> 10) [0 ..]) -- this hands over control to `||', which decides whether to continye with the next recursive `foldr' call or not |
| 2026-04-06 11:26:50 +0000 | <ski> | `foldl' keeps control, until it reaches the end of the list |
| 2026-04-06 11:26:25 +0000 | <ski> | `foldr' hands over control to the callback, and lets it decide if and when to continue with the `foldr' recursive call (being the second parameter passed to the callback) |
| 2026-04-06 11:25:44 +0000 | <lambdabot> | f a (f b (f c z)) |
| 2026-04-06 11:25:42 +0000 | <ski> | > foldr f z [a,b,c] :: Expr |
| 2026-04-06 11:25:40 +0000 | <lambdabot> | f (f (f z a) b) c |
| 2026-04-06 11:25:39 +0000 | <ski> | > foldl f z [a,b,c] :: Expr |
| 2026-04-06 11:25:25 +0000 | <ski> | both `foldl' and `foldr' start "from the left". what differs is the way it "associates" the callback (to the left, like `((z - a) - b) - c', for `foldl (-) z [a,b,c]', vs. to the right, like `a - (b - (c - z))', for `foldr (-) z [a,b,c]'). `foldl' keeps adding to, growing, the accumulator, while `foldr' wraps its recursive calls inside calls to the callback |
| 2026-04-06 11:22:39 +0000 | merijn | (~merijn@host-cl.cgnat-g.v4.dfn.nl) (Ping timeout: 255 seconds) |
| 2026-04-06 11:22:33 +0000 | xff0x | (~xff0x@2405:6580:b080:900:388f:e7ec:f5bb:9bd0) |
| 2026-04-06 11:22:03 +0000 | __monty__ | (~toonn@user/toonn) toonn |
| 2026-04-06 11:21:38 +0000 | <ski> | (this is the "direct recursive" version) |
| 2026-04-06 11:21:11 +0000 | <ski> | then basically the same thing would happen, as in the `foldr' version |
| 2026-04-06 11:20:59 +0000 | <ski> | for the last defining equation |
| 2026-04-06 11:20:54 +0000 | <ski> | putStr' (c:cs) = do putChar c; putStr' cs |
| 2026-04-06 11:20:51 +0000 | <ski> | or, if you prefer |
| 2026-04-06 11:20:44 +0000 | <ski> | putStr' (c:cs) = putChar c >> putStr' cs |
| 2026-04-06 11:20:26 +0000 | <ski> | putStr' [ ] = return () |
| 2026-04-06 11:20:16 +0000 | <ski> | btw, do note that if you defined |
| 2026-04-06 11:20:07 +0000 | __monty__ | (~toonn@user/toonn) (Ping timeout: 244 seconds) |
| 2026-04-06 11:18:37 +0000 | <ski> | exactly |
| 2026-04-06 11:18:31 +0000 | <ski> | do note that, as soon as the putChar 'a' has been executed, we don't need to keep memory around for it (although i showed it still in all the remaining lines above, for clarity), so we can discard that memory, and similarly for the other actions, so therefore we run in constant space |
| 2026-04-06 11:18:08 +0000 | <fp`> | Mm so it's not actually iterating from the right |
| 2026-04-06 11:17:41 +0000 | <ski> | { and now the return () which does nothing } |
| 2026-04-06 11:17:24 +0000 | <ski> | = putChar 'a' >> putChar 'b' >> putChar 'c' >> return () |
| 2026-04-06 11:17:15 +0000 | <ski> | { and now the putChar 'c' happens } |