Newest at the top
| 2025-10-27 05:41:11 +0100 | merijn | (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 265 seconds) |
| 2025-10-27 05:40:00 +0100 | trickard_ | (~trickard@cpe-55-98-47-163.wireline.com.au) |
| 2025-10-27 05:39:47 +0100 | trickard | (~trickard@cpe-55-98-47-163.wireline.com.au) (Read error: Connection reset by peer) |
| 2025-10-27 05:39:11 +0100 | aforemny | (~aforemny@2001:9e8:6cd1:6c00:4f63:56d8:3d93:b87f) (Ping timeout: 244 seconds) |
| 2025-10-27 05:39:09 +0100 | aforemny_ | (~aforemny@2001:9e8:6cf1:1000:4e89:d612:c448:7493) aforemny |
| 2025-10-27 05:35:52 +0100 | merijn | (~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn |
| 2025-10-27 05:32:48 +0100 | chromoblob | (~chromoblo@user/chromob1ot1c) chromoblob\0 |
| 2025-10-27 05:32:22 +0100 | chromoblob | (~chromoblo@user/chromob1ot1c) (Read error: Connection reset by peer) |
| 2025-10-27 05:32:16 +0100 | <hololeap> | so maybe that makes existential quantification behave like universal quantification in this example |
| 2025-10-27 05:29:57 +0100 | <hololeap> | I think the weird thing about my example is that every operation I can do on Hashed and HashSet already has a Hashable constraint |
| 2025-10-27 05:29:20 +0100 | <monochrom> | Yours is different from X, Y, E. Yours is a bonus feature that allows a constraint on a type parameter. |
| 2025-10-27 05:27:00 +0100 | <monochrom> | err, "data E = forall a. Hashable a => E (Hashed a) (HashSet a)" |
| 2025-10-27 05:26:28 +0100 | <monochrom> | Existential type would be like "data E = forall a. Haskable a => ..." |
| 2025-10-27 05:26:26 +0100 | <hololeap> | I would think it means the same thing |
| 2025-10-27 05:26:14 +0100 | <hololeap> | but how is this different: `= Hashable a => NEHashSet (Hashed a) (HashSet a)` |
| 2025-10-27 05:25:20 +0100 | merijn | (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 256 seconds) |
| 2025-10-27 05:25:02 +0100 | <hololeap> | ok |
| 2025-10-27 05:24:43 +0100 | <monochrom> | I will use a toy example. "data X a = X a" vs "data Y = Y (forall a. a)". I can make "x :: X Int; x = X 5". I cannot make a value of Y, short of Y undefined. |
| 2025-10-27 05:23:56 +0100 | <hololeap> | I remember one of them is using ExistentialQuantification, but which one? |
| 2025-10-27 05:23:03 +0100 | <hololeap> | between that and `= Hashable a => NEHashSet (Hashed a) (HashSet a)` |
| 2025-10-27 05:22:30 +0100 | <hololeap> | monochrom: what is the difference? |
| 2025-10-27 05:20:15 +0100 | <hololeap> | that's actually a reason not to use GHC2021 |
| 2025-10-27 05:20:13 +0100 | <monochrom> | RankNTypes would be like "data N = N (forall a. Hashable a => ...)" |
| 2025-10-27 05:20:05 +0100 | merijn | (~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn |
| 2025-10-27 05:19:34 +0100 | <hololeap> | I didn't think of GADTs |
| 2025-10-27 05:19:13 +0100 | <hololeap> | I thought it was using RankNTypes and I wanted to make it explicit |
| 2025-10-27 05:18:47 +0100 | <monochrom> | FWIW, it also means you don't need explicit RankNTypes :) |
| 2025-10-27 05:18:29 +0100 | <monochrom> | :) |
| 2025-10-27 05:18:22 +0100 | <hololeap> | oh... I have GHC2021 turned on |
| 2025-10-27 05:17:51 +0100 | <monochrom> | Oh! It's equivalent to "data N a where N :: Hashable a => N (Hashed a) (HashSet a)". You're using GADTs. |
| 2025-10-27 05:17:21 +0100 | <hololeap> | glguy: what is the difference between on the outside vs the inside? |
| 2025-10-27 05:15:47 +0100 | <hololeap> | so the ordering doesn't really matter. I could do what jackdk says and then remove the inner Foldable constraint on the data type |
| 2025-10-27 05:15:08 +0100 | <hololeap> | it's mostly to be able to use `all` and `any` |
| 2025-10-27 05:14:49 +0100 | <hololeap> | Foldable doesn't make sense? |
| 2025-10-27 05:13:03 +0100 | <Leary> | Yes, that's equivalent to `deriving Foldable`. Not that it really makes sense for unordered containers in the first place. |
| 2025-10-27 05:12:23 +0100 | <jackdk> | Ah, you're correct. Nevertheless, you can define `toList` without constraints (`toList ha hsa = unhash ha : toList hsa`) and then `foldMap f = foldMap f . toList` |
| 2025-10-27 05:09:22 +0100 | <Leary> | Uhh. I don't think that constraint is satisfiable without `instance Hashable a`. |
| 2025-10-27 05:09:07 +0100 | merijn | (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 246 seconds) |
| 2025-10-27 05:09:04 +0100 | <hololeap> | is that QuantifiedConstraints? |
| 2025-10-27 05:08:51 +0100 | <jackdk> | the necessary extensions |
| 2025-10-27 05:08:46 +0100 | <jackdk> | You can write the instance a `instance (forall a. Hashable a) => Foldable NonEmptyHashSet` if you turn on |
| 2025-10-27 05:08:33 +0100 | <hololeap> | it carries two types that both assume Hashable: Hashed and HashSet |
| 2025-10-27 05:08:13 +0100 | <monochrom> | Hrm, you need it. |
| 2025-10-27 05:07:58 +0100 | <jackdk> | You're also asking for the caller to provide the `Hashable a` constraint while also carrying the same dictionary in the ctor |
| 2025-10-27 05:07:44 +0100 | <monochrom> | I wonder if you actually need it. |
| 2025-10-27 05:07:25 +0100 | <hololeap> | *every |
| 2025-10-27 05:07:20 +0100 | <hololeap> | everything function in the module had a Hashable constraint before I added the constraint inside the data type |
| 2025-10-27 05:06:07 +0100 | <Leary> | Since it means carrying the dictionary everywhere. |
| 2025-10-27 05:05:51 +0100 | <Leary> | It's not inherently bad to put a constraint on a *constructor*, but it's something you ought to have a good reason for. |
| 2025-10-27 05:05:36 +0100 | <hololeap> | Leary: my implentation of toList turns it into a HashSet first, but I could have turned it into a list a different way |