Logs: liberachat/#haskell
| 2021-07-31 14:24:46 | <phaazon> | Guest1599: c is a constraint that will be applied on a functor wrapped in an existential |
| 2021-07-31 14:25:15 | <phaazon> | so I guess you’d use that with Task MonadIO to get a task running in « a MonadIO » |
| 2021-07-31 14:26:46 | × | jneira_ quits (~jneira_@28.red-80-28-169.staticip.rima-tde.net) (Ping timeout: 272 seconds) |
| 2021-07-31 14:26:52 | → | wroathe joins (~wroathe@c-68-54-25-135.hsd1.mn.comcast.net) |
| 2021-07-31 14:28:40 | × | cheater quits (~Username@user/cheater) (Ping timeout: 272 seconds) |
| 2021-07-31 14:29:56 | × | xff0x quits (~xff0x@2001:1a81:536d:8c00:2d4:a9e1:415e:5f77) (Ping timeout: 256 seconds) |
| 2021-07-31 14:30:16 | <[exa]> | phaazon: the all-to-all conversions don't really work nice with type inference, you'll usually jump into a situation where the type system needs to do a DFS on your code to find a good variant (and finish it to prove that it's not ambiguous), which is far from having the types intuitive |
| 2021-07-31 14:30:34 | × | fossdd quits (~fossdd@sourcehut/user/fossdd) (Ping timeout: 240 seconds) |
| 2021-07-31 14:30:41 | <Guest1599> | phaazon I'm a Haskell beginner; I know how to read `newtype ZipList a = ZipList { getZipList :: [a] }` and how to construct a type out of it (i.e. `ZipList Int`) |
| 2021-07-31 14:30:54 | <Guest1599> | but this `Task` still looks vague to me |
| 2021-07-31 14:30:58 | → | fossdd joins (~fossdd@sourcehut/user/fossdd) |
| 2021-07-31 14:31:17 | <phaazon> | [exa]: you mean because of the two type variables? |
| 2021-07-31 14:31:38 | → | Atum_ joins (~IRC@user/atum/x-2392232) |
| 2021-07-31 14:31:39 | <phaazon> | yeah, well, I agree it’s not perfect but most of the time it works great (in Rust at least, and Haskell type system is far better so I would expect it to behave better :D) |
| 2021-07-31 14:31:55 | <phaazon> | Guest1599: what’s bothering you is the forall, right? |
| 2021-07-31 14:32:10 | <phaazon> | you might need to get a look at a more specific version |
| 2021-07-31 14:32:12 | <phaazon> | like TaskIO |
| 2021-07-31 14:32:25 | <[exa]> | in rust the contexts are much much smaller, so it usually works nicely |
| 2021-07-31 14:32:47 | <[exa]> | in haskell you can easily get a function that has a whole convert chain in the type signature |
| 2021-07-31 14:32:48 | <phaazon> | newtype TaskIO k v = TaskIO (forall f. MonadIO f => (k -> f v) -> f v) -- Guest1599 |
| 2021-07-31 14:33:26 | <phaazon> | Guest1599: the forall here means that you cannot inspect and know what f it’s being used |
| 2021-07-31 14:33:39 | <phaazon> | the only place where you know that information is prior wrapping that function in the TaskIO |
| 2021-07-31 14:33:46 | <phaazon> | once it’s wrapped in, you lose the information of the type of f |
| 2021-07-31 14:33:54 | <phaazon> | and you only know about the constraint |
| 2021-07-31 14:34:03 | <phaazon> | so basically, MonadIO f, but you can’t know what f is inside |
| 2021-07-31 14:34:29 | <Guest1599> | hmm, okay |
| 2021-07-31 14:34:36 | <phaazon> | so you pass a (k -> f v) function and you get back a f v |
| 2021-07-31 14:34:58 | <phaazon> | I don’t know what that k and v means but it’s very likely to be an environment pattern, or some kind of pointer you can lookup in MonadIO |
| 2021-07-31 14:35:13 | <phaazon> | now, your initial type sig also abstracted on the constraint |
| 2021-07-31 14:35:18 | <Guest1599> | k - `key`, v - `value`, think of it as a storage |
| 2021-07-31 14:35:21 | <phaazon> | (with the c type param) |
| 2021-07-31 14:35:26 | <phaazon> | yeah that makes sense |
| 2021-07-31 14:36:24 | <Guest1599> | " pass a (k -> f v) function and you get back a f v" - where to pass it? I'm a bit lost |
| 2021-07-31 14:36:52 | AlexNoo_ | is now known as AlexNoo |
| 2021-07-31 14:37:09 | <Guest1599> | i.e. with `Maybe`: it's a type constructor - one can pass a type and it becomes `Maybe PassedType` - a concrete type |
| 2021-07-31 14:37:21 | <Guest1599> | I see thath TaskIO also accepts two types - `k` and `v` |
| 2021-07-31 14:37:39 | <Guest1599> | so... where's the place for `k -> f v` herE? |
| 2021-07-31 14:38:41 | → | jakalx joins (~jakalx@base.jakalx.net) |
| 2021-07-31 14:40:02 | <Guest1599> | I think my problem is that the right-hand side of `=` looks like nothing I've seen in the context of a newtype |
| 2021-07-31 14:40:51 | <phaazon> | Guest1599: yeah you’d have to pattern match on it |
| 2021-07-31 14:40:58 | <phaazon> | or use a function that does that for you |
| 2021-07-31 14:41:16 | <phaazon> | rewritting TaskIO in a way that automatically provides you a nice function to do so: |
| 2021-07-31 14:41:22 | <Guest1599> | I think I'm more lost than you expect |
| 2021-07-31 14:41:36 | <phaazon> | newtype TaskIO k v = TaskIO { runTaskIO :: forall f. MonadIO f => (k -> f v) -> f v } |
| 2021-07-31 14:42:58 | × | fossdd quits (~fossdd@sourcehut/user/fossdd) (Ping timeout: 240 seconds) |
| 2021-07-31 14:43:16 | → | fossdd joins (~fossdd@sourcehut/user/fossdd) |
| 2021-07-31 14:43:32 | → | kuribas joins (~user@ptr-25vy0i7fhp3jdg2nokv.18120a2.ip6.access.telenet.be) |
| 2021-07-31 14:43:53 | <Guest1599> | runTaskIO someTaskIO kToFVfunction would return `f v`...? |
| 2021-07-31 14:44:02 | <phaazon> | I can give you an example, wait :) |
| 2021-07-31 14:44:58 | <Guest1599> | phaazon : if it helps, the line comes from https://www.cambridge.org/core/journals/journal-of-functional-programming/article/build-systems-a-la-carte-theory-and-practice/097CE52C750E69BD16B78C318754C7A4 page 9 |
| 2021-07-31 14:45:36 | <Guest1599> | (the Task is a custom one, seperated from stdlib etc) |
| 2021-07-31 14:46:22 | <phaazon> | so: |
| 2021-07-31 14:46:34 | <phaazon> | let task = TaskIO $ \lookup -> liftA2 (+) (lookup "hey") (lookup "you") |
| 2021-07-31 14:46:53 | <phaazon> | here, we just lookup two keys (setting k = String) |
| 2021-07-31 14:46:57 | <phaazon> | and we add them together |
| 2021-07-31 14:47:09 | → | slowButPresent joins (~slowButPr@user/slowbutpresent) |
| 2021-07-31 14:47:09 | <phaazon> | so that we have v as Num v |
| 2021-07-31 14:47:27 | <phaazon> | the type of task is then (Num v) => TakIO String v |
| 2021-07-31 14:47:27 | × | MQ-17J quits (~MQ-17J@d14-69-206-129.try.wideopenwest.com) (Read error: Connection reset by peer) |
| 2021-07-31 14:47:44 | <phaazon> | now, you need to run that task, so as I told you earlier, you need to pass that (k -> f v) function |
| 2021-07-31 14:47:52 | <phaazon> | let’s just mockup something really quick |
| 2021-07-31 14:48:01 | <phaazon> | lookup "hey" = pure 1; lookup "you" = pure 2; lookup _ = pure 0 |
| 2021-07-31 14:48:05 | → | MQ-17J joins (~MQ-17J@d14-69-206-129.try.wideopenwest.com) |
| 2021-07-31 14:48:10 | <phaazon> | running the task like: |
| 2021-07-31 14:48:17 | <phaazon> | runTaskIO task lookup |
| 2021-07-31 14:48:23 | × | MQ-17J quits (~MQ-17J@d14-69-206-129.try.wideopenwest.com) (Read error: Connection reset by peer) |
| 2021-07-31 14:48:25 | <phaazon> | will tie everything and will provide 3 |
| 2021-07-31 14:49:03 | <phaazon> | the only place where we know the type of f is when we define task |
| 2021-07-31 14:49:19 | <phaazon> | I didn’t do anything specific but I could have used liftIO . print and it would have made f = IO |
| 2021-07-31 14:49:33 | → | MQ-17J joins (~MQ-17J@d14-69-206-129.try.wideopenwest.com) |
| 2021-07-31 14:50:05 | <phaazon> | the important thing is that you will get back a value in f v, yes |
| 2021-07-31 14:50:29 | → | lbseale joins (~lbseale@user/ep1ctetus) |
| 2021-07-31 14:51:19 | <Guest1599> | (let me digest it) |
| 2021-07-31 14:51:27 | <phaazon> | sure |
| 2021-07-31 14:51:36 | <phaazon> | existential quantification is not really beginner level anyway :) |
| 2021-07-31 14:51:44 | <phaazon> | it’s completly normal if you feel overwhelmed by it |
| 2021-07-31 14:52:17 | → | xff0x joins (~xff0x@2001:1a81:536d:8c00:2d4:a9e1:415e:5f77) |
| 2021-07-31 14:52:22 | <Guest1599> | First qustion: Why `newtype TaskIO k v = TaskIO { runTaskIO :: forall f. MonadIO f => (k -> f v) -> f v} ` , not just `newtype TaskIO k v = TaskIO { runTaskIO :: (MonadIO f) => (k -> f v) -> f v } ` ? |
| 2021-07-31 14:53:00 | <Guest1599> | what would be the difference? |
| 2021-07-31 14:53:09 | <phaazon> | good question; the right side of a data type declaration must use either concrete types or type variables declared on the left part |
| 2021-07-31 14:53:23 | <phaazon> | f here is only known on the right side |
| 2021-07-31 14:53:31 | <phaazon> | it doesn’t appear on the left side |
| 2021-07-31 14:53:37 | <phaazon> | so if I give you two different tasks |
| 2021-07-31 14:53:58 | <phaazon> | which types are TaskIO Int String and TaskIO Int String, what f is inside of them? the same? different? :) |
| 2021-07-31 14:54:17 | → | nate3 joins (~nate@108-233-125-227.lightspeed.sntcca.sbcglobal.net) |
| 2021-07-31 14:54:29 | <phaazon> | so the forall keyword is a bit confusing but allows us to say “there’s a f inside of that thing and it’s introduced here as existential; we know it’s there but we can’t inspect / observe it from outside” |
| 2021-07-31 14:55:07 | <Guest1599> | hmmm, okay |
| 2021-07-31 14:55:08 | <phaazon> | your second form would be valid if you had newtype TaskIO k f v, for instance |
| 2021-07-31 14:55:22 | × | fossdd quits (~fossdd@sourcehut/user/fossdd) (Ping timeout: 240 seconds) |
| 2021-07-31 14:55:29 | <phaazon> | it would be a problem, though |
| 2021-07-31 14:55:33 | → | fossdd joins (~fossdd@sourcehut/user/fossdd) |
| 2021-07-31 14:55:35 | <phaazon> | because someone could use any functor / monad here |
| 2021-07-31 14:55:41 | <phaazon> | (not necessarily MonadIO) |
| 2021-07-31 14:56:28 | <Guest1599> | phaazon couldn't we provide something like `(MondaIO f) =>` on the RHS ( right-hand side of the equation sign)? |
| 2021-07-31 14:58:08 | <Guest1599> | maybe that's a question that won't get us (me) anywhere though; |
| 2021-07-31 14:58:29 | <phaazon> | there are different position where we can do that but yeah, not sure |
| 2021-07-31 15:02:14 | × | nate3 quits (~nate@108-233-125-227.lightspeed.sntcca.sbcglobal.net) (Ping timeout: 272 seconds) |
| 2021-07-31 15:04:50 | <Guest1599> | phaazon are you a regular member of this channel? (I think I need to digest what you've said, read a few more things and perhaps (tomorrow...? some time in the future) discuss further if needed. Would be nice to see you around |
| 2021-07-31 15:09:33 | → | bitdex joins (~bitdex@gateway/tor-sasl/bitdex) |
| 2021-07-31 15:10:01 | → | hnOsmium0001 joins (uid453710@id-453710.stonehaven.irccloud.com) |
All times are in UTC.