2021-05-21 17:41:01 +0200 <boxscape> StateT m <|> StateT n = StateT $ \ s -> m s `mplus` n s
2021-05-21 17:41:33 +0200sondre(~sondrelun@eduroam-193-157-240-212.wlan.uio.no) (Ping timeout: 260 seconds)
2021-05-21 17:41:38 +0200 <ski> but sometimes, one such composand doesn't really make much sense, in isolation from another part, and so it may make more sense to only define its composition with that other part (separately named or not)
2021-05-21 17:42:07 +0200brandonh(~brandonh@2a04:3542:1000:910:905f:f9ff:fe67:4d32)
2021-05-21 17:43:13 +0200dolio(~dolio@130.44.130.54) (Quit: ZNC 1.8.2 - https://znc.in)
2021-05-21 17:44:12 +0200littlefinger(~00000000@selfhost1.threedot14.com)
2021-05-21 17:44:24 +0200 <ski> Hecate : .. not sure how much the above helps. would probably need to see more specific code (and perhaps also get an idea of the problem domain), to attempt to give more concrete suggestion
2021-05-21 17:44:45 +0200slice(~slice@user/slice)
2021-05-21 17:44:50 +0200 <ski> boxscape : hm, can you confirm `mplus = (<|>)' for whatever parser you're using ?
2021-05-21 17:45:33 +0200 <boxscape> ski it's just Either
2021-05-21 17:45:37 +0200Deidde(~Deide@217.155.19.23)
2021-05-21 17:45:59 +0200 <boxscape> % f :: (Alternative m, MonadError () m, MonadState String m) => m String; f = (put "errorState" >> throwError ()) <|> get
2021-05-21 17:45:59 +0200 <yahb> boxscape:
2021-05-21 17:46:00 +0200 <boxscape> % flip evalState "origState" . runExceptT $ f
2021-05-21 17:46:00 +0200 <yahb> boxscape: Right "errorState"
2021-05-21 17:46:02 +0200dolio(~dolio@130.44.130.54)
2021-05-21 17:46:15 +0200 <boxscape> it looks to me here like `get` should have received "origState"
2021-05-21 17:46:17 +0200 <Hecate> ski: it does, thanks :)
2021-05-21 17:46:22 +0200 <boxscape> I must be misunderstanding something
2021-05-21 17:47:00 +0200 <boxscape> ski err wait I suppose it's ExceptT not Either, could be a different instance
2021-05-21 17:47:20 +0200azeem(azeem@107.161.19.109) (Quit: Connection closed)
2021-05-21 17:47:59 +0200 <ski> Hecate : CPS is about passing a function (a callback, called a "continuation") to your functions, and instead of giving back the result, your function will (as the last thing it does, in each branch) call this continuation callback with the result (so, technically, will return whatever the continuation returns, when passed what would otherwise be thought of as the result)
2021-05-21 17:48:27 +0200jhill_jhill
2021-05-21 17:48:53 +0200 <Hecate> ski: ok :) It's not just about nested calls but also passing the next call to the function
2021-05-21 17:49:06 +0200 <Hecate> like, foo 1 baz
2021-05-21 17:49:54 +0200haskman(~haskman@106.215.53.61)
2021-05-21 17:50:03 +0200ddellacosta(~ddellacos@89.46.62.86) (Remote host closed the connection)
2021-05-21 17:50:30 +0200sondre(~sondrelun@eduroam-193-157-240-212.wlan.uio.no)
2021-05-21 17:51:13 +0200ddellacosta(~ddellacos@89.46.62.125)
2021-05-21 17:52:29 +0200 <ski> Hecate : one reason to do CPS can be efficiency. another reason is that one can do "funny" things, like deviate from "calling the continuation argument last", in certain circumstances. it's a very powerful (and also a bit hard to reason about, understand) tool for doing "control effects". CPS is also related to "monadic style", by which we mean using `foo >>= \x -> bar x >>= \y -> baz x y'
2021-05-21 17:52:34 +0200df(~ben@51.15.198.140)
2021-05-21 17:53:36 +0200samoit_(~samoit@153.red-79-153-5.dynamicip.rima-tde.net)
2021-05-21 17:53:42 +0200 <boxscape> I actually don't really understand how Except has an Alternative instance, it looks like Identity would need one but it doesn't seem to have one
2021-05-21 17:53:59 +0200 <ski> (e.g., in a language with continuation side-effects (not exactly the same as, but related to, CPS), (also you need state), given any implementation of a monad, you can "reflect" it into a corresponding side-effect. e.g. in SML/NJ, or Scheme, if you implement a parser monad, you can then reflect that into "parsing side-effects", as if the language had built-in support for keeping track of parsing under the
2021-05-21 17:54:05 +0200 <ski> covers, similarly to how many languages have native support for exceptions)
2021-05-21 17:54:13 +0200 <boxscape> oh wait, I might have misread the operator
2021-05-21 17:54:46 +0200 <boxscape> yeah ExceptT's Alternative instance uses <*> instead of <|>, so it is different from it's MonadPlus instance
2021-05-21 17:54:50 +0200 <ski> Hecate : here's an example of a `map' function, written in CPS :
2021-05-21 17:55:13 +0200 <ski> mapCPS :: (a -> (b -> o) -> o) -> ([a] -> ([b] -> o) -> o)
2021-05-21 17:55:19 +0200sondre(~sondrelun@eduroam-193-157-240-212.wlan.uio.no) (Ping timeout: 272 seconds)
2021-05-21 17:55:31 +0200 <ski> mapCPS f [ ] k = k []
2021-05-21 17:56:06 +0200 <ski> mapCPS f (x:xs) k = f x $ \y ->
2021-05-21 17:56:12 +0200samoit(~samoit@user/samoit/x-0249261) (Quit: Leaving)
2021-05-21 17:56:15 +0200 <boxscape> (no sorry, that was wrong, I just got confused in where in the source code I was :)
2021-05-21 17:56:22 +0200 <ski> map f xs $ \ys ->
2021-05-21 17:56:26 +0200samoit_(~samoit@153.red-79-153-5.dynamicip.rima-tde.net) (Changing host)
2021-05-21 17:56:26 +0200samoit_(~samoit@user/samoit/x-0249261)
2021-05-21 17:56:32 +0200 <ski> k (y:ys)
2021-05-21 17:57:10 +0200 <ski> here's a function that works the same, but is written using the `Cont o' monad instead
2021-05-21 17:57:31 +0200 <ski> mapCont :: (a -> Cont o b) -> ([a] -> Cont o [b])
2021-05-21 17:57:42 +0200 <ski> mapCont f [ ] = return []
2021-05-21 17:58:11 +0200 <ski> mapCont f (x:xs) = f x >>= \y ->
2021-05-21 17:58:30 +0200 <ski> mapCont f xs >>= \ys ->
2021-05-21 17:58:40 +0200 <ski> return (y:ys)
2021-05-21 17:59:10 +0200 <ski> boxscape : links ?
2021-05-21 17:59:26 +0200 <boxscape> https://hackage.haskell.org/package/transformers-0.5.6.2/docs/src/Control.Monad.Trans.Except.html#…
2021-05-21 17:59:31 +0200 <boxscape> ctrl-f for MonadPlus to get the other one
2021-05-21 17:59:37 +0200 <ski> (sorry, `map' in `mapCont' was of course meant to be `mapCont'. it should call itself recursively)
2021-05-21 17:59:59 +0200 <boxscape> I completely misread the code for some reason, it just requires a Monoid instance for the errors, nothing for Identity
2021-05-21 18:00:02 +0200nsilv(~nsilv@212.103.198.210) (Quit: WeeChat 3.0.1)
2021-05-21 18:01:15 +0200 <Hecate> ski: terrifying, but thanks! :D
2021-05-21 18:02:16 +0200 <ski> boxscape : those look the same, to me
2021-05-21 18:02:31 +0200 <boxscape> ski yeah they are
2021-05-21 18:02:53 +0200Aran(~Aran@port-92-194-80-170.dynamic.as20676.net)
2021-05-21 18:03:21 +0200sondre(~sondrelun@eduroam-193-157-240-212.wlan.uio.no)
2021-05-21 18:03:26 +0200tzh(~tzh@c-24-21-73-154.hsd1.or.comcast.net)
2021-05-21 18:04:55 +0200saikiran(~Thunderbi@171.49.232.50)
2021-05-21 18:07:34 +0200imdoor(~imdoor@balticom-142-78-50.balticom.lv) (Quit: imdoor)
2021-05-21 18:07:38 +0200sondre(~sondrelun@eduroam-193-157-240-212.wlan.uio.no) (Ping timeout: 245 seconds)
2021-05-21 18:08:59 +0200dhouthoo(~dhouthoo@178-117-36-167.access.telenet.be) (Quit: WeeChat 3.1)
2021-05-21 18:09:10 +0200sirodoht(uid499766@id-499766.brockwell.irccloud.com)
2021-05-21 18:09:46 +0200amk(~amk@176.61.106.150) (Ping timeout: 264 seconds)
2021-05-21 18:09:47 +0200heath(~heath@68.68.64.38) (Quit: Lost terminal)
2021-05-21 18:10:04 +0200amk(~amk@176.61.106.150)
2021-05-21 18:10:20 +0200horex539(~horex539@2a02:a03f:6aa5:a00:79b6:6869:fb6c:f113)
2021-05-21 18:11:49 +0200pretty_dumm_guy(~trottel@92.223.89.149)
2021-05-21 18:12:23 +0200heath(~heath@68.68.64.38)
2021-05-21 18:12:25 +0200 <boxscape> tbh it looks like I should probably just be using catchError instead of <|>, my Error type doesn't have a sensible Monoid instance
2021-05-21 18:12:41 +0200jmtdJon
2021-05-21 18:12:51 +0200 <boxscape> could use <|> if ExceptT didn't try to collect errors together with <|>/mplus
2021-05-21 18:13:11 +0200JonGuest3126
2021-05-21 18:13:27 +0200merijn(~merijn@83-160-49-249.ip.xs4all.nl)
2021-05-21 18:13:43 +0200samoit_(~samoit@user/samoit/x-0249261) (Quit: samoit_)
2021-05-21 18:14:09 +0200ikex(~ash@user/ikex) (Quit: WeeChat 3.2-dev)
2021-05-21 18:14:25 +0200 <ski> Hecate : as you can see, `mapCont' is "nested" (in terms of a call to itself), similar to one of your examples (which i why i said it could be related to CPS in some way). also, sometimes one thinks of the right operand of `>>=' as a "continuation" (what to do after executing the action to the left). however, with "true CPS", one would never nest like `(foo >>= \x -> bar x) >>= \y -> baz y' (and so, wouldn't
2021-05-21 18:14:31 +0200 <ski> write `fooBar >>= \y -> baz y', given the definition `fooBar = foo >>= \x -> bar x'), but always in the form `foo >>= \x -> (bar x >>= \y -> baz z)' (possibly naming `bar x >>= \y -> baz z', putting it in a definition of its own)
2021-05-21 18:14:46 +0200Guest3126Jon
2021-05-21 18:14:57 +0200littlefinger(~00000000@selfhost1.threedot14.com) (Ping timeout: 272 seconds)
2021-05-21 18:15:49 +0200 <Hecate> I see
2021-05-21 18:15:56 +0200Jon(~jon@2a00:23c7:e48a:4a01:ac66:201c:57c9:af4e) (Quit: Leaving)
2021-05-21 18:15:59 +0200 <ski> Hecate : anyway, if you're interested, i could try to give some more explanation of what CPS is about .. but above, i merely wanted to give some rough idea of what it is (and is not)
2021-05-21 18:16:03 +0200 <ski> @hackage managed
2021-05-21 18:16:04 +0200 <lambdabot> https://hackage.haskell.org/package/managed
2021-05-21 18:16:37 +0200Jon(jon@dow.land)
2021-05-21 18:16:37 +0200 <ski> is a simple example of an (internal) use of CPS, so you can see one thing it's good for
2021-05-21 18:16:55 +0200sondre(~sondrelun@eduroam-193-157-240-212.wlan.uio.no)
2021-05-21 18:17:08 +0200mrkajetanp(~kajetan@2a01:4b00:ea36:6c00:56e9:4ef3:28ef:7ef6)
2021-05-21 18:18:50 +0200 <ski> boxscape : hm, yea
2021-05-21 18:19:07 +0200 <ski> (i'm still not clear on what difference you observed between your two alternative forms)
2021-05-21 18:19:25 +0200epolanski(uid312403@id-312403.brockwell.irccloud.com) (Quit: Connection closed for inactivity)