Newest at the top
| 2026-05-20 11:51:47 +0000 | aka_dude | (~aka_dude@192.71.166.120) |
| 2026-05-20 11:49:02 +0000 | weary-traveler | (~user@user/user363627) user363627 |
| 2026-05-20 11:49:00 +0000 | <ski> | (btw, it *is* also possible, in some ways, to learn more about the type, namely when using GADTs. doing a `case'-`of' analysis may then, in each appropriate branch, provide more information (at compilte-time) about abstract type parameters like `a' and `b') |
| 2026-05-20 11:46:41 +0000 | <ski> | to pass around the (unchanging) type parameters `a' and `b' (so `loop' is monomorphic .. i also factored out the unchanging `f' while i was at it), while for the `nestedShows' you'd have something like `nestedShows @a @{show_a} (x:xs) = show @a @{show_a} : nestedShows @[a] @{mkShowList show_a} (...)') |
| 2026-05-20 11:46:35 +0000 | <ski> | (in System F, when invoking a polymorphic operation, you are explicitly applying it to the types to use in place of the type parameters, in Haskell (with extensions) you can write this as e.g. `map @Int @Bool (> 4) [2,3,5,7]'. for monomorphic recursion, you can imagine `map' being defined as `map @a @b f = loop where loop :: [a] -> [b]; loop [ ] = []; loop (x:xs) = f x : loop xs', where you do *not* need |
| 2026-05-20 11:43:17 +0000 | fgarcia | (~lei@user/fgarcia) (Ping timeout: 272 seconds) |
| 2026-05-20 11:42:52 +0000 | puke | (~puke@user/puke) puke |
| 2026-05-20 11:42:51 +0000 | <mauke> | you can tell map uses monomorphic recursion because it can be implemented in C++ templates :-) |
| 2026-05-20 11:42:27 +0000 | puke | (~puke@user/puke) (Read error: error:0A000139:SSL routines::record layer failure) |
| 2026-05-20 11:40:54 +0000 | <ski> | otoh, `map' from above is *monomorphic* recursive (even though it's a polymorphic function), because, *within* the body of `map', we can think of it as being monomorphic, in the unknown types `a' and `b', recursive call calling on those *same* unknown types |
| 2026-05-20 11:40:49 +0000 | confusedalex | (~confuseda@user/confusedalex) confusedalex |
| 2026-05-20 11:39:54 +0000 | <ski> | most interesting functions (iow recursive) on these, will need to be polymorphic recursive |
| 2026-05-20 11:39:26 +0000 | <ski> | data PerfectlyBalancedBinaryTree a = Leaves a | Double (PerfectlyBalancedBinaryTree (a,a)) -- here we pass `(a,a)' in place of `a' |
| 2026-05-20 11:38:47 +0000 | <ski> | data SwapList a b = Nil | Cons a (SwapList b a) -- `a' and `b' are swapped around, so it's not the same parameter pattern |
| 2026-05-20 11:38:23 +0000 | <lambdabot> | "(((9,9),(9,9)),((9,9),(9,9)))" |
| 2026-05-20 11:38:22 +0000 | <mauke> | > let { foo :: Show a => Int -> a -> String; foo n x | n > 0 = foo (n - 1) (x, x) | otherwise = show x } in foo 3 9 |
| 2026-05-20 11:38:19 +0000 | dolio | (~dolio@130.44.140.168) dolio |
| 2026-05-20 11:38:04 +0000 | <lambdabot> | "((9,9),(9,9))" |
| 2026-05-20 11:38:03 +0000 | <mauke> | > let { foo :: Show a => Int -> a -> String; foo n x | n > 0 = foo (n - 1) (x, x) | otherwise = show x } in foo 2 9 |
| 2026-05-20 11:37:54 +0000 | <ski> | most more reasonable examples of polymorphic recursion involve "non-regular (recursive) data types", being data types whose recursion does not pass the same type parameters, e.g. |
| 2026-05-20 11:36:57 +0000 | <ski> | iow, it must create a new dictionary, at run-time |
| 2026-05-20 11:36:44 +0000 | <ski> | and, in this case, because we have a type class constraint, that means that when this is at run-time given an instance method dictionary for `Show Integer', it will then hand off (provide) a dictionary for `Show [Integer]' to the recursive call |
| 2026-05-20 11:36:39 +0000 | vanishingideal | (~vanishing@user/vanishingideal) vanishingideal |
| 2026-05-20 11:36:37 +0000 | Moyst | (~moyst@user/moyst) Moyst |
| 2026-05-20 11:35:54 +0000 | <ski> | so, if in the top call, `a' will be `Integer', then in the recursive call, `a' will next be `[Integer]', then `[[Integer]]', and so on |
| 2026-05-20 11:35:22 +0000 | <ski> | note that `xs' has type `[a]', but in the recursive call, `map (: []) xs)' has type `[[a]]' |
| 2026-05-20 11:34:56 +0000 | <ski> | nestedShows (x:xs) = show x : nestedShows (map (: []) xs) |
| 2026-05-20 11:34:37 +0000 | <ski> | nestedShows [ ] = [] |
| 2026-05-20 11:34:28 +0000 | <ski> | nestedShows :: Show a => [a] -> [String] |
| 2026-05-20 11:33:56 +0000 | <ski> | here's a simple (and a bit silly) example of a polymorhic recursive function |
| 2026-05-20 11:33:24 +0000 | <ski> | btw, polymorphic recursion is when a polymorphic operation is recursive, and at least some recursive invokation does *not* use the same unknown type variables as the current call |
| 2026-05-20 11:32:42 +0000 | weary-traveler | (~user@user/user363627) (Remote host closed the connection) |
| 2026-05-20 11:32:04 +0000 | myxos | (~myxos@67-1-178-42.tcso.qwest.net) myxokephale |
| 2026-05-20 11:31:52 +0000 | fgarcia | (~lei@user/fgarcia) fgarcia |
| 2026-05-20 11:31:48 +0000 | weary-traveler | (~user@user/user363627) user363627 |
| 2026-05-20 11:31:47 +0000 | synchromesh | (~john@2406:5a00:247e:1500:cb6:d4f7:ed0e:5cdb) synchromesh |
| 2026-05-20 11:31:38 +0000 | merijn | (~merijn@77.242.116.146) merijn |
| 2026-05-20 11:31:23 +0000 | Moyst | (~moyst@user/moyst) (*.net *.split) |
| 2026-05-20 11:31:23 +0000 | confusedalex | (~confuseda@user/confusedalex) (*.net *.split) |
| 2026-05-20 11:31:23 +0000 | myxos | (~myxos@67-1-178-42.tcso.qwest.net) (*.net *.split) |
| 2026-05-20 11:31:23 +0000 | synchromesh | (~john@2406:5a00:247e:1500:cb6:d4f7:ed0e:5cdb) (*.net *.split) |
| 2026-05-20 11:31:23 +0000 | dolio | (~dolio@130.44.140.168) (*.net *.split) |
| 2026-05-20 11:31:23 +0000 | chele | (~chele@user/chele) (*.net *.split) |
| 2026-05-20 11:31:23 +0000 | merijn | (~merijn@77.242.116.146) (*.net *.split) |
| 2026-05-20 11:31:23 +0000 | weary-traveler | (~user@user/user363627) (*.net *.split) |
| 2026-05-20 11:31:22 +0000 | fgarcia | (~lei@user/fgarcia) (*.net *.split) |
| 2026-05-20 11:31:22 +0000 | vanishingideal | (~vanishing@user/vanishingideal) (*.net *.split) |
| 2026-05-20 11:31:22 +0000 | nhar | (~noah@76.33.110.8) (*.net *.split) |
| 2026-05-20 11:31:21 +0000 | <ski> | e.g. the logic/functional programming language Mercury *does* pass around type infos, at run-time, to polymorphic operations, in this fashion |
| 2026-05-20 11:31:12 +0000 | <mesaoptimizer> | I see |