Logs: liberachat/#haskell
| 2021-07-08 04:02:16 | → | MQ-17J joins (~MQ-17J@8.21.10.15) |
| 2021-07-08 04:05:58 | <janus> | right, i was thinking i'd get that answer :P but the point is that the composed function can be effectful... in practise it will be doing network IO |
| 2021-07-08 04:06:26 | → | dunkeln joins (~dunkeln@188.70.10.207) |
| 2021-07-08 04:07:51 | <janus> | i guess i am really thinking in the abstraction level that 'wither' operates in, but when writing haskell it seems so difficult to decide whether the abstraction level you wanna work with, which is sometimes too powerful, is worth its weight... |
| 2021-07-08 04:08:24 | × | warnz quits (~warnz@2600:1700:77c0:5610:edd9:472d:4b89:9ab8) (Ping timeout: 252 seconds) |
| 2021-07-08 04:08:29 | → | merijn joins (~merijn@83-160-49-249.ip.xs4all.nl) |
| 2021-07-08 04:10:49 | <janus> | i just have to accept the fact that there is no one way to do it, and embrace politics :( |
| 2021-07-08 04:12:07 | → | arjun joins (~Srain@user/arjun) |
| 2021-07-08 04:16:33 | → | hexreel joins (~hr@69.233.98.238) |
| 2021-07-08 04:19:16 | → | oxide joins (~lambda@user/oxide) |
| 2021-07-08 04:36:02 | × | chase quits (~chase@89.45.224.218) (Ping timeout: 272 seconds) |
| 2021-07-08 04:37:26 | <lechner> | Hi, how can I print the value in line 20 and also save it in a file, please? I'm stuck inside the monad. Thanks! https://paste.debian.net/1203754/ |
| 2021-07-08 04:42:22 | × | merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 246 seconds) |
| 2021-07-08 04:45:13 | → | a6a45081-2b83 joins (~aditya@106.214.66.197) |
| 2021-07-08 04:46:26 | → | yauhsien joins (~yauhsien@61-231-39-135.dynamic-ip.hinet.net) |
| 2021-07-08 04:50:46 | × | yauhsien quits (~yauhsien@61-231-39-135.dynamic-ip.hinet.net) (Ping timeout: 246 seconds) |
| 2021-07-08 04:51:30 | <oxytocat> | instead of using pointfree style, you can name the result and then use it more than once |
| 2021-07-08 04:51:48 | <lechner> | with <- ? |
| 2021-07-08 04:51:57 | <oxytocat> | yeah |
| 2021-07-08 04:52:25 | <oxytocat> | instead of `receive responder >>=` you can do `msg <- receive responder` |
| 2021-07-08 04:52:33 | <lechner> | i tried that |
| 2021-07-08 04:52:45 | <lechner> | how do i use the result, please? |
| 2021-07-08 04:53:44 | <lechner> | i tried to feed it in with >>= but that did not work |
| 2021-07-08 04:53:44 | <oxytocat> | the line that starts with `liftIO` is a chain of function composition, `>>=` passes the result from `receive responder` to the other section |
| 2021-07-08 04:54:19 | <oxytocat> | you can wrap the whole expression in parenthesis and pass `msg` to it, like this: |
| 2021-07-08 04:54:30 | <oxytocat> | `(liftIO . printf "Received request: [%s]\n" . unpack . GZip.decompress . fromStrict) msg` |
| 2021-07-08 04:54:38 | <oxytocat> | or alternatively: |
| 2021-07-08 04:54:44 | <oxytocat> | `liftIO . printf "Received request: [%s]\n" . unpack . GZip.decompress . fromStrict $ msg` |
| 2021-07-08 04:54:48 | <oxytocat> | or alternatively: |
| 2021-07-08 04:55:11 | <oxytocat> | `liftIO (printf "Received request: [%s]\n" (unpack (GZip.decompress (fromStrict msg))))` |
| 2021-07-08 04:55:52 | <oxytocat> | note that `liftIO ...` and `msg <- ...` need to have the same indentation width |
| 2021-07-08 04:56:21 | <lechner> | thatks! i understand all of that, except perhaps the entire purpose of LiftIO |
| 2021-07-08 04:56:42 | <dsal> | :t liftIO |
| 2021-07-08 04:56:43 | <lambdabot> | MonadIO m => IO a -> m a |
| 2021-07-08 04:57:09 | <dsal> | If you have an mtl stack with IO at the bottom and need to run something in IO, liftIO gets you there. |
| 2021-07-08 04:57:55 | <oxytocat> | the runZMQ has some capabilities beyond IO so it has a different type |
| 2021-07-08 04:57:56 | → | acidjnk_new joins (~acidjnk@p200300d0c72b9526e1b6d7c282fb2b66.dip0.t-ipconnect.de) |
| 2021-07-08 04:58:05 | <lechner> | what is mtl please? |
| 2021-07-08 04:59:18 | <oxytocat> | check out https://github.com/soupi/haskell-study-plan#monad-transformers |
| 2021-07-08 04:59:20 | <lechner> | what does the LiftIO do in this line, please? liftIO (printf "Received request: [%s]\n" (unpack (GZip.decompress (fromStrict msg)))) |
| 2021-07-08 04:59:32 | <dsal> | :t liftIO -- it does that |
| 2021-07-08 04:59:33 | <lambdabot> | MonadIO m => IO a -> m a |
| 2021-07-08 04:59:50 | <lechner> | to me that is different from the other two |
| 2021-07-08 04:59:56 | <dsal> | You're using runZMQ which is: runZMQ :: MonadIO m => (forall z. ZMQ z a) -> m a |
| 2021-07-08 05:00:28 | → | fizbin joins (~fizbin@c-73-33-197-160.hsd1.nj.comcast.net) |
| 2021-07-08 05:01:10 | <oxytocat> | the type for regular IO actions is `IO <something>` - this is a description (or recipe) for a computation that may run some IO actions and return a value of type <something> |
| 2021-07-08 05:01:43 | <lechner> | yeah that part i understand |
| 2021-07-08 05:02:03 | <oxytocat> | ZMQ has a different type than that, it wants to be able to describe actions that can do ZMQ stuff as well as regular IO actions |
| 2021-07-08 05:02:32 | <oxytocat> | so it needs a different type than IO |
| 2021-07-08 05:03:05 | <dsal> | Instead of directly specifying IO, it just specifies that it needs something monadic that knows how to get to IO. |
| 2021-07-08 05:03:08 | <lechner> | so the LiftIO is specimic to System.ZMQ4.Monadic ? |
| 2021-07-08 05:03:15 | <lechner> | specific |
| 2021-07-08 05:03:30 | <dsal> | No, it's a method of MonadIO |
| 2021-07-08 05:03:58 | <oxytocat> | liftIO is a function that many other types like ZMQ implement, so that users can run arbitrary IO actions while working in ZMQ type |
| 2021-07-08 05:04:06 | <oxytocat> | or their respective types, actually |
| 2021-07-08 05:04:28 | <dsal> | https://hackage.haskell.org/package/base-4.15.0.0/docs/Control-Monad-IO-Class.html |
| 2021-07-08 05:04:53 | <lechner> | why is it needed to evaluate this expression? liftIO (printf "Received request: [%s]\n" (unpack (GZip.decompress (fromStrict msg)))) |
| 2021-07-08 05:04:59 | <oxytocat> | for example ActionM from the scotty package that is used to describe web requests processing also implements that function |
| 2021-07-08 05:05:10 | × | fizbin quits (~fizbin@c-73-33-197-160.hsd1.nj.comcast.net) (Ping timeout: 272 seconds) |
| 2021-07-08 05:05:13 | <lechner> | it comes after the print? |
| 2021-07-08 05:05:23 | <oxytocat> | :t liftIO |
| 2021-07-08 05:05:25 | <lambdabot> | MonadIO m => IO a -> m a |
| 2021-07-08 05:05:55 | <oxytocat> | the whole expression to the right of liftIO |
| 2021-07-08 05:06:02 | <oxytocat> | has the type `IO ()` |
| 2021-07-08 05:06:26 | <oxytocat> | but anything running in ZMQ has a different type that relates to ZMQ |
| 2021-07-08 05:07:15 | <oxytocat> | so liftIO takes the `IO ()` and transforms it to work within `m ()` |
| 2021-07-08 05:07:21 | <lechner> | i see |
| 2021-07-08 05:07:23 | <oxytocat> | where `m` is the relevant ZMQ type |
| 2021-07-08 05:07:51 | <lechner> | but m is not named? |
| 2021-07-08 05:07:59 | <oxytocat> | I'm not sure what it is because it is not specified here and the docs for zeromq-haskell are missing from hackage |
| 2021-07-08 05:08:16 | <lechner> | yeah they did not generate |
| 2021-07-08 05:08:24 | <oxytocat> | `liftIO` is a bit general, think like `print :: Show a => a -> String` |
| 2021-07-08 05:08:52 | <oxytocat> | we know that print will work for any type that implements the `Show` interface |
| 2021-07-08 05:09:12 | <oxytocat> | with liftIO we know that it will work for any `m` that implements the `MonadIO` interface |
| 2021-07-08 05:09:20 | × | acidjnk_new quits (~acidjnk@p200300d0c72b9526e1b6d7c282fb2b66.dip0.t-ipconnect.de) (Ping timeout: 252 seconds) |
| 2021-07-08 05:09:47 | <dsal> | lechner: You can use any m as long as it has a MonadIO instance. It's a constraint, not a type. |
| 2021-07-08 05:09:52 | <lechner> | it's about the caller though rather than the argument, right? |
| 2021-07-08 05:10:08 | <oxytocat> | sorry print is actually `print :: Show a => a -> IO ()`, my mistake |
| 2021-07-08 05:10:22 | × | hiruji quits (~hiruji@user/hiruji) (Ping timeout: 246 seconds) |
| 2021-07-08 05:10:25 | <oxytocat> | yes, it's what the caller supplies generally |
| 2021-07-08 05:10:44 | <dsal> | % liftIO . print $ (1,2,3) |
| 2021-07-08 05:10:44 | <yahb> | dsal: (1,2,3) |
| 2021-07-08 05:10:56 | <lechner> | what is the likely type of msg above please? |
| 2021-07-08 05:12:01 | <oxytocat> | I expect it is ZMQ |
| 2021-07-08 05:12:13 | <oxytocat> | oh, of msg? sorry |
| 2021-07-08 05:12:14 | <oxytocat> | let's check |
| 2021-07-08 05:12:38 | <lechner> | so with LiftIO, both the code to the right and to the left is effectful, yes |
| 2021-07-08 05:13:27 | <oxytocat> | https://gitlab.com/twittner/zeromq-haskell/-/blob/develop/src/System/ZMQ4/Monadic.hs#L351 |
| 2021-07-08 05:13:29 | <dsal> | liftIO just digs out the the IO and runs the supplied IO action. |
| 2021-07-08 05:13:40 | <oxytocat> | this indicates that it is `ByteString` |
| 2021-07-08 05:14:17 | <lechner> | dsal: like 'do'? |
| 2021-07-08 05:14:45 | <dsal> | What do you mean? `do` doesn't, um, `do` anything. |
| 2021-07-08 05:15:37 | <lechner> | sorry it's my second run at haskell. i thought do can print |
| 2021-07-08 05:15:47 | <oxytocat> | `do` is just alternative syntax for `>>=` and `>>` |
| 2021-07-08 05:15:48 | <dsal> | do is just syntax sugar. |
| 2021-07-08 05:15:59 | <dsal> | @undo do { print "x" } |
| 2021-07-08 05:15:59 | <lambdabot> | print "x" |
| 2021-07-08 05:16:43 | <oxytocat> | check out this section, let me know if it makes it clearer: https://github.com/soupi/haskell-study-plan#do-notation |
| 2021-07-08 05:16:53 | × | AgentM quits (~agentm@pool-162-83-130-212.nycmny.fios.verizon.net) (Quit: Leaving.) |
| 2021-07-08 05:17:14 | <dsal> | > do { a <- Just 1; b <- Just 2; pure (a + b) } |
All times are in UTC.