Logs: freenode/#haskell
| 2021-03-16 09:19:07 | <dminuoso> | You are missing the callCC there. |
| 2021-03-16 09:19:22 | <dminuoso> | The setjmp magic is encapsulated by callCC. |
| 2021-03-16 09:20:46 | → | kam1 joins (~kam1@83.123.167.219) |
| 2021-03-16 09:21:08 | × | kam1 quits (~kam1@83.123.167.219) (Read error: Connection reset by peer) |
| 2021-03-16 09:21:17 | × | heatsink quits (~heatsink@2600:1700:bef1:5e10:7c0e:3b57:dfb:2cb4) (Ping timeout: 260 seconds) |
| 2021-03-16 09:23:57 | → | esp32_prog joins (~esp32_pro@185.254.75.51) |
| 2021-03-16 09:29:29 | × | Mrbuck quits (~Mrbuck@gateway/tor-sasl/mrbuck) (Ping timeout: 268 seconds) |
| 2021-03-16 09:30:31 | ← | asheshambasta parts (~user@ptr-e1lysavz4fnu38pr3di.18120a2.ip6.access.telenet.be) ("ERC (IRC client for Emacs 28.0.50)") |
| 2021-03-16 09:32:05 | × | jhrcek quits (~jhrcek@ip-89-103-183-101.net.upcbroadband.cz) (Quit: Leaving) |
| 2021-03-16 09:35:12 | × | vicfred quits (vicfred@gateway/vpn/mullvad/vicfred) (Quit: Leaving) |
| 2021-03-16 09:36:08 | × | Paks quits (~paks@c-69-136-183-189.hsd1.il.comcast.net) (Ping timeout: 256 seconds) |
| 2021-03-16 09:37:35 | → | Paks joins (~paks@c-69-136-183-189.hsd1.il.comcast.net) |
| 2021-03-16 09:42:36 | × | plutonux quits (~q@ppp-223-24-184-182.revip6.asianet.co.th) (Read error: Connection reset by peer) |
| 2021-03-16 09:42:47 | → | kam1 joins (~kam1@83.123.167.219) |
| 2021-03-16 09:42:55 | → | dftxbs3e joins (~dftxbs3e@unaffiliated/dftxbs3e) |
| 2021-03-16 09:43:12 | × | kam1 quits (~kam1@83.123.167.219) (Read error: Connection reset by peer) |
| 2021-03-16 09:46:33 | <joncol> | charukiewicz: Thanks! |
| 2021-03-16 09:47:21 | <guest316> | dminuoso: but callCC x :: Cont r a |
| 2021-03-16 09:47:35 | <guest316> | dminuoso: right? |
| 2021-03-16 09:47:40 | <guest316> | :t callCC |
| 2021-03-16 09:47:41 | <lambdabot> | MonadCont m => ((a -> m b) -> m a) -> m a |
| 2021-03-16 09:48:18 | <dminuoso> | guest316: Try to go back one excercise. |
| 2021-03-16 09:48:46 | <dminuoso> | Conceptually callCC already is a "setjmp", and it provides "longjmp" as an argument to its function. |
| 2021-03-16 09:49:41 | <dminuoso> | Except it's a scoped setjmp, with the trick in the excercise you are looking at, you're leaking the jump target to outside callCC. |
| 2021-03-16 09:52:00 | → | m0rphism joins (~m0rphism@HSI-KBW-085-216-104-059.hsi.kabelbw.de) |
| 2021-03-16 09:53:41 | → | frozenErebus joins (~frozenEre@94.128.82.20) |
| 2021-03-16 09:54:11 | <guest316> | dminuoso: I don't get it, "leaking the jump target to outside callCC." |
| 2021-03-16 09:54:45 | <guest316> | dminuoso: so the jump back trick isn't related to fixed-point, but related to callCC? |
| 2021-03-16 09:55:11 | × | sz0 quits (uid110435@gateway/web/irccloud.com/x-tawqhplyvvjuqusl) (Quit: Connection closed for inactivity) |
| 2021-03-16 09:56:13 | <dminuoso> | Yes. |
| 2021-03-16 09:56:16 | → | thc202 joins (~thc202@unaffiliated/thc202) |
| 2021-03-16 09:56:28 | <dminuoso> | Not just related, that's the entire point of callCC |
| 2021-03-16 09:56:42 | <dminuoso> | Think of `callCC` as setting up a catch frame, and providing you with a jump |
| 2021-03-16 09:56:50 | <dminuoso> | callCC $ \jumpBack -> ... |
| 2021-03-16 09:57:31 | × | kuribas quits (~user@ptr-25vy0iaa19zfetqtyes.18120a2.ip6.access.telenet.be) (Read error: Connection reset by peer) |
| 2021-03-16 09:58:48 | × | frozenErebus quits (~frozenEre@94.128.82.20) (Ping timeout: 256 seconds) |
| 2021-03-16 09:58:54 | → | Mrbuck joins (~Mrbuck@gateway/tor-sasl/mrbuck) |
| 2021-03-16 09:59:02 | × | shad0w_ quits (67573b43@103.87.59.67) (Quit: Connection closed) |
| 2021-03-16 09:59:04 | <guest316> | dminuoso: without fixed-point, could callCC jump inside Cont do-notation? |
| 2021-03-16 09:59:11 | <dminuoso> | yes |
| 2021-03-16 09:59:18 | <guest316> | dminuoso: example code? |
| 2021-03-16 09:59:23 | × | ADG1089__ quits (~aditya@106.214.253.186) (Remote host closed the connection) |
| 2021-03-16 09:59:27 | <dminuoso> | e.g.: g = callCC $ \throw -> do { n <- getSomeNumber; when (n > 10) (throw 100); m <- getAnotherNumber; pure (n + m) } |
| 2021-03-16 10:00:23 | <dminuoso> | Here `throw` can shortcircuit the rest of the inner block. It essentially jumps to the outer callCC back, and resumes with the provided answer. |
| 2021-03-16 10:00:45 | <guest316> | dminuoso: could we change `when' to if-then-else? |
| 2021-03-16 10:00:49 | <dminuoso> | Sure |
| 2021-03-16 10:00:58 | <dminuoso> | Note this "throw" handle is what callCC provides you with. |
| 2021-03-16 10:01:06 | <guest316> | I'm not familiar with `when` or `until' |
| 2021-03-16 10:01:10 | <dminuoso> | Inside callCC, you can use it at any time to just abort the rest |
| 2021-03-16 10:01:36 | <dminuoso> | guest316: Are you familiar with regular exceptions in say IO? |
| 2021-03-16 10:01:43 | <guest316> | dminuoso: yes |
| 2021-03-16 10:01:52 | <dminuoso> | Imagine catch had the following type signature |
| 2021-03-16 10:01:57 | <dminuoso> | catch :: ((a -> IO b) -> IO a) -> IO a |
| 2021-03-16 10:03:10 | <dminuoso> | Then you could do something like: `catch $ \abort -> do { n <- getFromDatabase; when (badUser n) (abort Nothing); someMoreCode }` |
| 2021-03-16 10:03:43 | <dminuoso> | (Note, this primitive wouldnt behave very well in certain situations, but lets glance over that) |
| 2021-03-16 10:04:00 | <dminuoso> | Here, abort would just shortcircuit someMoreCode, and instantly provide an answer |
| 2021-03-16 10:04:10 | → | Wafelack joins (~Wafelack@2a01:cb16:6:9385:66f3:f20f:c394:340b) |
| 2021-03-16 10:04:14 | × | aarvar quits (~foewfoiew@2601:602:a080:fa0:1175:1d12:3f7a:f4b9) (Ping timeout: 264 seconds) |
| 2021-03-16 10:04:25 | <dminuoso> | Perhaps say via an exception that `catch` instantly catches, and reinserts as a value |
| 2021-03-16 10:04:26 | × | Wafelack quits (~Wafelack@2a01:cb16:6:9385:66f3:f20f:c394:340b) (Client Quit) |
| 2021-03-16 10:04:34 | <dminuoso> | And that's exactly what callCC does |
| 2021-03-16 10:04:57 | <guest316> | dminuoso: wait a sec, g :: Cont r a? |
| 2021-03-16 10:05:08 | <dminuoso> | What is g? |
| 2021-03-16 10:05:21 | <guest316> | <dminuoso> e.g.: g = callCC $ \throw -> do { n <- getSomeNumber; when (n > 10) (throw 100); m <- getAnotherNumber; pure (n + m) } |
| 2021-03-16 10:05:25 | <dminuoso> | Perhaps, you could think of `callCC` as giving you a proper "return" from imperative languages. |
| 2021-03-16 10:05:40 | <dminuoso> | guest316: Ah, it would be `g :: Cont r Int` perhaps |
| 2021-03-16 10:06:04 | <guest316> | dminuoso: now I know inside callCC can do abort earlier |
| 2021-03-16 10:06:13 | <dminuoso> | But callCC doesnt just give you a `return`, but it gives you `return` as a first class value, that you can pass around.. |
| 2021-03-16 10:06:39 | <dminuoso> | (Note when I say `return`, I mean it in the sense of say C++ or Java) |
| 2021-03-16 10:07:01 | <guest316> | dminuoso: would callCC would care what g would take? |
| 2021-03-16 10:07:10 | <dminuoso> | "what g would take"? |
| 2021-03-16 10:07:32 | <guest316> | g :: Cont r a, so g would take a continuation to extract r |
| 2021-03-16 10:07:56 | <guest316> | g = cons $ \k -> k x |
| 2021-03-16 10:08:07 | <dminuoso> | Not extract, but produce |
| 2021-03-16 10:09:22 | <dminuoso> | The broad idea is, that rather than `I have an Int`, this says `If you give me a function that knows how to proceed from an Int, I will provide you with an Int` |
| 2021-03-16 10:09:36 | <dminuoso> | Turning `Int` into `(Int -> a) -> a` |
| 2021-03-16 10:09:49 | → | aarvar joins (~foewfoiew@2601:602:a080:fa0:1175:1d12:3f7a:f4b9) |
| 2021-03-16 10:11:00 | × | Alleria__ quits (~textual@2603-7000-3040-0000-3133-bb30-065f-83b3.res6.spectrum.com) (Quit: My MacBook has gone to sleep. ZZZzzz…) |
| 2021-03-16 10:11:35 | <guest316> | dminuoso: so what g take would do something to callCC? |
| 2021-03-16 10:12:04 | × | minoru_shiraeesh quits (~shiraeesh@109.166.59.197) (Ping timeout: 276 seconds) |
| 2021-03-16 10:12:23 | <guest316> | g :: (a->r) -> r, would take (a->r) |
| 2021-03-16 10:12:40 | <dminuoso> | I dont understand the question |
| 2021-03-16 10:13:09 | <guest316> | g = callCC ... :: Cont r a, right? |
| 2021-03-16 10:13:12 | → | dbmikus joins (~dbmikus@cpe-76-167-86-219.natsow.res.rr.com) |
| 2021-03-16 10:13:25 | → | __monty__ joins (~toonn@unaffiliated/toonn) |
| 2021-03-16 10:13:40 | <guest316> | and g would take x:: (a->r) , so g x :: r, right? |
| 2021-03-16 10:14:14 | × | loller_ quits (uid358106@gateway/web/irccloud.com/x-cnpraiotvintahet) (Quit: Connection closed for inactivity) |
| 2021-03-16 10:14:21 | <dminuoso> | Lets pick my previous example |
| 2021-03-16 10:14:32 | <dminuoso> | g :: Cont r Int; g = callCC $ \throw -> do { n <- getSomeNumber; when (n > 10) (throw 100); m <- getAnotherNumber; pure (n + m) } |
| 2021-03-16 10:14:35 | <guest316> | so g x :: r, would be (callCC \abort -> ...) x |
| 2021-03-16 10:14:40 | → | elfets joins (~elfets@ip-37-201-23-96.hsi13.unitymediagroup.de) |
| 2021-03-16 10:14:52 | <dminuoso> | g does not take anything, as its not a function |
| 2021-03-16 10:15:10 | <dminuoso> | (well, strictly speaking intensionally it contains a function, but that's not as important here) |
| 2021-03-16 10:16:14 | <guest316> | dminuoso: (runCont g) x |
| 2021-03-16 10:16:57 | <guest316> | dminuoso: data types or functions just wrap and unwrap |
| 2021-03-16 10:17:07 | <dminuoso> | Yes, but lets not gloss over having to unrap them first. |
| 2021-03-16 10:17:29 | <dminuoso> | It makes a huge difference whether you write `(runCont g) x` or `(g x` |
| 2021-03-16 10:17:47 | <dminuoso> | Or rather `runCont g x` or `g x` |
| 2021-03-16 10:17:58 | × | dbmikus quits (~dbmikus@cpe-76-167-86-219.natsow.res.rr.com) (Ping timeout: 245 seconds) |
| 2021-03-16 10:18:04 | <dminuoso> | In my example, the type of `g` is `Cont r Int`, though |
All times are in UTC.