Logs: liberachat/#haskell
| 2025-09-04 15:16:33 | <bwe> | I stick with | S.size mySet == 0 = -- guard style |
| 2025-09-04 15:16:37 | <EvanR> | makes more sense than toList |
| 2025-09-04 15:16:55 | <EvanR> | comparing a number to zero? o_O |
| 2025-09-04 15:17:53 | <EvanR> | yeah if you really don't care about the structure if non-empty, then an if statement over null |
| 2025-09-04 15:19:24 | <EvanR> | but like "pattern matching" makes me think you do |
| 2025-09-04 15:19:41 | <bwe> | EvanR: | S.size mySet > 0 = -- is what I actually use now |
| 2025-09-04 15:19:51 | × | rekahsoft quits (~rekahsoft@174.95.4.83) (Remote host closed the connection) |
| 2025-09-04 15:20:18 | <ski> | (in Mercury, matching on data constructor of a type with user-defined equality (aka quotient type) is (committed-choice) nondeterministic (executing gives you one of the possible choices, possibly also affected by optimizations). you have to use the `promise_equivalent_solutions' pragma, at the point where the choice of representation no longer affects your answers) |
| 2025-09-04 15:20:21 | <EvanR> | it reads fine but seems like a roundabout way to do it |
| 2025-09-04 15:20:54 | <ski> | using `null' is more direct (possibly also more efficient ?) than using `size' |
| 2025-09-04 15:21:49 | <mari51613> | min and maxView are cool, allow to recur on the rest of the set |
| 2025-09-04 15:22:10 | <EvanR> | minView and maxView prove that the set is non-empty, if it is, and might be avoiding redundant work on your followup |
| 2025-09-04 15:22:15 | <EvanR> | or not |
| 2025-09-04 15:22:15 | <mari51613> | hm but you said they are log(n) |
| 2025-09-04 15:22:36 | <EvanR> | yes it has to do some work to give you the remainder set |
| 2025-09-04 15:22:52 | → | merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl) |
| 2025-09-04 15:23:03 | <EvanR> | but you could avoid it through laziness |
| 2025-09-04 15:23:07 | <EvanR> | don't look at the remainder |
| 2025-09-04 15:27:25 | <tomsmeding> | a Set is a binary search tree, so minView and maxView have to do log(n) work to descend to the left-most, resp. right-most, leaf in the tree |
| 2025-09-04 15:27:45 | × | merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds) |
| 2025-09-04 15:28:25 | <tomsmeding> | constructing the remainder of the set is just _more_ log(n) work |
| 2025-09-04 15:29:11 | <mari51613> | i am surprised a binary search tree could have an empty root while being nonempty |
| 2025-09-04 15:30:01 | <tomsmeding> | mari51613: what do you get from splitRoot? |
| 2025-09-04 15:30:20 | <mari51613> | huh the example by int-e above |
| 2025-09-04 15:30:21 | <int-e> | Also, if all you do with the result of `minView` is to check whether it's `Tip`, that *could* be constant time... bu of course the function is super strict so it isn't ;-) |
| 2025-09-04 15:30:29 | × | pavonia quits (~user@user/siracusa) (Quit: Bye!) |
| 2025-09-04 15:31:11 | <__monty__> | Isn't a bonus of null that it works for any Foldable? |
| 2025-09-04 15:31:18 | <tomsmeding> | mari51613: what splitRoot does internally is give you three sets: the elements less than what happens to be the root of the tree, a singleton set containing the root, and the elements greater than the root |
| 2025-09-04 15:31:43 | <tomsmeding> | which element in the set is the root depends on exactly how the Set came to be |
| 2025-09-04 15:32:09 | <mari51613> | hm almost suited for recursion. Thanks tomsmeding |
| 2025-09-04 15:32:20 | <tomsmeding> | in Set.fromList [1,2], apparently '1' is the root and '2' its right child; in Set.fromList [2,1], apparently '2' is the root |
| 2025-09-04 15:32:38 | <EvanR> | __monty__, if your algorithm works on any foldable, then you can't rely on any Set details whatsoever, so null would basically be your only option |
| 2025-09-04 15:32:50 | <EvanR> | rather than a benefit xD |
| 2025-09-04 15:33:11 | <mari51613> | __monty__: we are discussing how to keep set structures after pattern-matching |
| 2025-09-04 15:34:00 | <EvanR> | I conflated pattern matching with "covering views" for giggles, and changed the subject |
| 2025-09-04 15:34:23 | <EvanR> | since Set is abstract |
| 2025-09-04 15:36:32 | <bwe> | EvanR: what's the danger of S.size mySet == 0 ? |
| 2025-09-04 15:36:44 | <EvanR> | instead of null? |
| 2025-09-04 15:37:26 | <bwe> | yes |
| 2025-09-04 15:37:26 | <EvanR> | the danger of more letters, maybe more computation, otherwise just seems like style |
| 2025-09-04 15:37:31 | <tomsmeding> | null is more polymorphic, but the performance is the same |
| 2025-09-04 15:37:38 | <tomsmeding> | https://hackage.haskell.org/package/containers-0.7/docs/src/Data.Set.Internal.html#null |
| 2025-09-04 15:38:12 | <EvanR> | it wouldn't turn into a numeric test? |
| 2025-09-04 15:38:15 | → | segfaultfizzbuzz joins (~segfaultf@23-93-74-222.fiber.dynamic.sonic.net) |
| 2025-09-04 15:38:21 | → | merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl) |
| 2025-09-04 15:38:39 | <__monty__> | length would be the polymorphic version of S.size. |
| 2025-09-04 15:38:40 | <tomsmeding> | perhaps it will, perhaps it won't, but if an additional int equality test here is a performance problem, you have other issues |
| 2025-09-04 15:39:41 | → | Raito_Bezarius joins (~Raito@libera/contributor/wireguard.tunneler.raito-bezarius) |
| 2025-09-04 15:41:13 | <tomsmeding> | right, `null` can avoid the int equality test whereas GHC doesn't know that the presence of `Bin` implies size>0, so with `size` you do get an int equality test |
| 2025-09-04 15:41:49 | <tomsmeding> | but -- you know what -- pattern matching on the constructor is also an int equality test! (On the constructor tag) |
| 2025-09-04 15:42:25 | <EvanR> | it patterns matches on the underlying constructor anyway |
| 2025-09-04 15:42:39 | <EvanR> | in either case |
| 2025-09-04 15:42:50 | <tomsmeding> | yes so it's 1 versus 2 equality tests |
| 2025-09-04 15:43:16 | × | merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 256 seconds) |
| 2025-09-04 15:43:16 | <EvanR> | but if null is wrapped in an if, that's another test, of True vs False |
| 2025-09-04 15:43:29 | <EvanR> | but I guess == 0 also has that |
| 2025-09-04 15:43:32 | <tomsmeding> | that boolean test is also there after the int equality test |
| 2025-09-04 15:43:34 | <tomsmeding> | yes |
| 2025-09-04 15:43:41 | <EvanR> | multiple tests! |
| 2025-09-04 15:43:56 | <EvanR> | smh |
| 2025-09-04 15:44:10 | <tomsmeding> | (size s == 0) == True |
| 2025-09-04 15:44:43 | <EvanR> | clearly the library needs to add a method :: b -> (Set a -> b) -> b |
| 2025-09-04 15:44:58 | <tomsmeding> | which... does what, branch on the constructor? |
| 2025-09-04 15:45:04 | <EvanR> | yeah xD |
| 2025-09-04 15:45:20 | <tomsmeding> | ghc will eliminate the boolean equality test using case-of-case conversion |
| 2025-09-04 15:45:23 | <EvanR> | where the set passed to the callback is definitely non empty |
| 2025-09-04 15:45:46 | <EvanR> | good |
| 2025-09-04 15:45:59 | → | Lycurgus joins (~juan@user/Lycurgus) |
| 2025-09-04 15:46:14 | <tomsmeding> | case (case x of P1 -> True ; P2 -> False) of True -> A ; False -> B ~> case x of P1 -> (case True of True -> A ; False -> B) ; P2 -> (case False of True -> A ; False -> B) |
| 2025-09-04 15:46:28 | <tomsmeding> | where the last two cases immediately optimise to "A" and "B" |
| 2025-09-04 15:47:00 | <tomsmeding> | so your method is unneeded, S.null suffices |
| 2025-09-04 15:47:14 | <EvanR> | \o/ |
| 2025-09-04 15:47:49 | <mari51613> | bwe moved on to fire the rockets in the meantime, they are about to trigger |
| 2025-09-04 15:48:14 | <__monty__> | What's bwe? |
| 2025-09-04 15:48:22 | <mari51613> | an user |
| 2025-09-04 15:48:30 | <tomsmeding> | scroll about half a screen up |
| 2025-09-04 15:48:53 | <bwe> | mari51613: well, sort of. I get some stack traces for uncovered patterns. |
| 2025-09-04 15:49:13 | <__monty__> | : ( I was hoping for a rocket company acronym and a cool stream to go along with a launch. |
| 2025-09-04 15:49:26 | <EvanR> | a rocket company that runs on haskell |
| 2025-09-04 15:49:44 | <tomsmeding> | Bursting With Entropy? |
| 2025-09-04 15:49:45 | <EvanR> | so that they can be literal when they use launchMissiles :: IO () |
| 2025-09-04 15:50:25 | <mari51613> | :: IO Damage |
| 2025-09-04 15:50:51 | <EvanR> | you have to wait for the missiles to launch, fly, and hit the target |
| 2025-09-04 15:51:01 | <EvanR> | so the Damage is lazy I/O |
| 2025-09-04 15:51:14 | <tomsmeding> | IO can block just fine, no need for it to be lazy |
| 2025-09-04 15:51:22 | <bwe> | __monty__: btw there is this nice `streaming` package. |
| 2025-09-04 15:51:44 | <EvanR> | tomsmeding, better not miss the target then! |
| 2025-09-04 15:52:01 | <tomsmeding> | well then the damage is just 0, or perhaps there is still damage but not quite where you intended |
| 2025-09-04 15:52:25 | <EvanR> | how do you know what's a miss and what's taking the scenic route |
| 2025-09-04 15:52:40 | <tomsmeding> | how do you know that your `writeFile` is not going over the network |
| 2025-09-04 15:52:40 | <EvanR> | very relevant in DOOM II with those homing missiles |
| 2025-09-04 15:53:15 | <EvanR> | writeFile is a sad posterchild for I/O |
| 2025-09-04 15:53:45 | → | merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl) |
| 2025-09-04 15:53:53 | <EvanR> | even if it completes you don't know if the file has been committed |
| 2025-09-04 15:53:55 | <tomsmeding> | turns out it's versatile enough for reasoning about side-effects and concurrency without needing to implement mass-destruction weapons :) |
| 2025-09-04 15:54:01 | × | ByronJohnson quits (~bairyn@MAIL.DIGITALKINGDOM.ORG) (Ping timeout: 256 seconds) |
| 2025-09-04 15:54:41 | <segfaultfizzbuzz> | any love for decino (youtube) ? |
| 2025-09-04 15:55:54 | → | fp1 joins (~Thunderbi@159-255-252-137.bb.dnainternet.fi) |
| 2025-09-04 15:58:34 | × | merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 256 seconds) |
| 2025-09-04 15:59:49 | × | kuribas quits (~user@ip-188-118-57-242.reverse.destiny.be) (Quit: ERC 5.5.0.29.1 (IRC client for GNU Emacs 29.3)) |
All times are in UTC.