Newest at the top
| 2025-11-28 20:36:09 +0100 | <EvanR> | let loop x = x >> loop x in loop (putStrLn "HELLO WORLD") |
| 2025-11-28 20:36:01 +0100 | <milan> | Oh cool :) |
| 2025-11-28 20:35:53 +0100 | <EvanR> | you can also factor out the pattern |
| 2025-11-28 20:35:42 +0100 | <EvanR> | let x = putStrLn "HELLO WORLD" >> x in x -- or chaining infinite prints! |
| 2025-11-28 20:32:05 +0100 | <milan> | Which is possible by chaining multiple print in IO. that guarantees they will be executed multiple times when needed. |
| 2025-11-28 20:31:11 +0100 | <milan> | times. |
| 2025-11-28 20:31:09 +0100 | <milan> | No I was thining why outputing something to external object is encapsulated in IO. My reasoning was that wheter it chages state of this external object correctly or not can't affect our program (until we do some reading) and so IO here is unnecesary. But as pointed out problem with printing multiple times is one when programming would become very unreliable as sometimes we need to output several |
| 2025-11-28 20:29:15 +0100 | Lord_of_Life | (~Lord@user/lord-of-life/x-2819915) Lord_of_Life |
| 2025-11-28 20:28:55 +0100 | Lord_of_Life | (~Lord@user/lord-of-life/x-2819915) (Ping timeout: 240 seconds) |
| 2025-11-28 20:26:25 +0100 | notzmv | (~umar@user/notzmv) (Ping timeout: 264 seconds) |
| 2025-11-28 20:25:51 +0100 | <EvanR> | print id |
| 2025-11-28 20:25:48 +0100 | <EvanR> | you want it to print the function itself? |
| 2025-11-28 20:25:26 +0100 | <milan> | Okey I think I can see your point. |
| 2025-11-28 20:25:16 +0100 | <milan> | Yeah |
| 2025-11-28 20:25:12 +0100 | <mniip> | that would only print once |
| 2025-11-28 20:25:09 +0100 | <mniip> | yea but if you said `let x = print 3 in [x, x, x]` |
| 2025-11-28 20:24:49 +0100 | <lambdabot> | [a -> a] |
| 2025-11-28 20:24:49 +0100 | <milan> | Could ghc runtime execute print on every function it evaluates? |
| 2025-11-28 20:24:48 +0100 | <EvanR> | :t [id, id, id] |
| 2025-11-28 20:24:35 +0100 | <milan> | You can put functions to list too right? |
| 2025-11-28 20:23:23 +0100 | <mniip> | hell you can put them in a list: sequence_ [x, x, x] |
| 2025-11-28 20:23:16 +0100 | <mniip> | let x = print 3 in x >> x |
| 2025-11-28 20:22:43 +0100 | <EvanR> | yes! |
| 2025-11-28 20:22:43 +0100 | <mniip> | the bonus is that IO actions are values and you can manipulate them |
| 2025-11-28 20:22:22 +0100 | <milan> | And as runtime is evaluating big IO composed of smaler IOs it always executes action there. |
| 2025-11-28 20:22:21 +0100 | <EvanR> | orthogonal, but can be combined easily |
| 2025-11-28 20:22:02 +0100 | <EvanR> | yeah so, functions are over here and are like this, and I/O commands are over here |
| 2025-11-28 20:21:23 +0100 | <milan> | I get that they are encapsulated in IO... |
| 2025-11-28 20:20:06 +0100 | <EvanR> | in haskell they're two different things entirely |
| 2025-11-28 20:19:59 +0100 | <EvanR> | so they don't happen until someone calls the function |
| 2025-11-28 20:19:42 +0100 | <EvanR> | in most language the evaluation of a function call is intertwined with executing effects, which is why you have to wrap everything with a lambda wrapper to delay the effects |
| 2025-11-28 20:18:57 +0100 | <milan> | hmm |
| 2025-11-28 20:18:22 +0100 | acidjnk | (~acidjnk@p200300d6e7171911dda60d32ed7e3ae9.dip0.t-ipconnect.de) (Ping timeout: 246 seconds) |
| 2025-11-28 20:18:04 +0100 | <EvanR> | just evaluating print 3 by itself wouldn't necessarily do the IO i.e. in (print 3, print 3), so it's a big distinction to make |
| 2025-11-28 20:17:32 +0100 | <milan> | I agree |
| 2025-11-28 20:17:22 +0100 | ChaiTRex | (~ChaiTRex@user/chaitrex) ChaiTRex |
| 2025-11-28 20:17:04 +0100 | <EvanR> | algebraically |
| 2025-11-28 20:17:00 +0100 | <EvanR> | in this way you can build up a big IO from smaller ones |
| 2025-11-28 20:16:53 +0100 | ChaiTRex | (~ChaiTRex@user/chaitrex) (Remote host closed the connection) |
| 2025-11-28 20:16:42 +0100 | <lambdabot> | IO a -> (a -> IO b) -> (a -> IO c) -> IO c |
| 2025-11-28 20:16:41 +0100 | <EvanR> | :t bracket |
| 2025-11-28 20:16:28 +0100 | <EvanR> | or pass it as an argument |
| 2025-11-28 20:16:20 +0100 | <EvanR> | you could store the IO () in a data structure or mutable variable for later |
| 2025-11-28 20:16:00 +0100 | <EvanR> | but the program itself just computes data |
| 2025-11-28 20:15:53 +0100 | <milan> | Yep |
| 2025-11-28 20:15:50 +0100 | <EvanR> | would print twice |
| 2025-11-28 20:15:43 +0100 | <EvanR> | e.g. main = print 3 >> print 3 :: IO () |
| 2025-11-28 20:15:18 +0100 | <EvanR> | main :: IO () |
| 2025-11-28 20:15:10 +0100 | <EvanR> | as the program runs, the I/O commands it computes are executed |
| 2025-11-28 20:14:47 +0100 | <EvanR> | that's just the supporting infrastructure for the runtime |