Home liberachat/#haskell: Logs Calendar

Logs: liberachat/#haskell

←Prev  Next→ 1,801,364 events total
2025-12-16 10:48:16 <dminuoso> Is `Enum` the typeclass of things that are countable?
2025-12-16 10:48:21 <dminuoso> Is Rational Enum?
2025-12-16 10:48:38 <tomsmeding> Enum is nothing, essentially, as it has no sensible laws and the methods are nonsense too (can you only enumerate things that are Int-large?)
2025-12-16 10:49:23 <tomsmeding> no, because Rational is at least as large as Integer, and Integer is bigger than Int, and you must define fromEnum
2025-12-16 10:49:38 <tomsmeding> but that just shows that the Enum class is nonsense, not any kind of enumerability of Rational
2025-12-16 10:49:47 <tomsmeding> because Rational is very countable indeed
2025-12-16 10:49:53 somemathguy joins (~somemathg@user/somemathguy)
2025-12-16 10:50:22 <tomsmeding> (Enum is useful as a base for [..] syntax, but that's not under discussion here)
2025-12-16 10:52:09 <dminuoso> tomsmeding: I think Enum is in a weird state in that it feels like its *meant* to represent things that are countable, since the ability to enumerate seems to align with the mathematical notion of countability. But the [..] and relatedly fromEnum/toEnum make it a somewhat adhoc thing.
2025-12-16 10:52:25 <tomsmeding> right
2025-12-16 10:53:19 <tomsmeding> it's actually useful for [..] (apart from not being able to enumerate stuff that's bigger than Int, which is nonsense), and it's _almost_ useful for describing enumerability in general, but then falls short
2025-12-16 10:53:36 <tomsmeding> it's like Arrow with `arr`, except that Enum actually has some use still
2025-12-16 10:53:43 <dminuoso> So we would need a kind of `class Countable a => fromNat :: Natural -> a`
2025-12-16 10:54:07 <tomsmeding> I'd like a mapping in the other direction too with a law saying that they are inverses
2025-12-16 10:54:22 <haskellbridge> <loonycyborg> I don't see how it represents countability in mathematical sense
2025-12-16 10:54:22 <haskellbridge> <loonycyborg> it's merely prerequisite
2025-12-16 10:54:31 <haskellbridge> <loonycyborg> but there are many ways of counting the same thing
2025-12-16 10:54:47 <dminuoso> loonycyborg: The fromEnum/toEnum are really the same essence.
2025-12-16 10:55:01 Googulator71 is now known as Googulator
2025-12-16 10:55:01 <dminuoso> Except it's constrained to Int instead of Natural
2025-12-16 10:55:03 <haskellbridge> <loonycyborg> that is making a mapping of Thing -> Natural
2025-12-16 10:55:46 <tomsmeding> (another problem is that fromEnum and toEnum are not declared in the documentation to be inverses of each other, although we can reasonably say that they "obviously" must be)
2025-12-16 10:56:01 <dminuoso> Being countable really means a one-to-one mapping to ℕ
2025-12-16 10:56:27 <dminuoso> loonycyborg: It does not matter *how* you count it.
2025-12-16 10:56:38 <dminuoso> As long as you *can* provide any way to map to ℕ
2025-12-16 10:56:47 <haskellbridge> <loonycyborg> Enum represents only one way that is deemed useful for whatever reason
2025-12-16 10:58:03 <lucabtz> dminuoso: countable = finite or 1-1 mapping to N
2025-12-16 10:58:14 <tomsmeding> countable = injective mapping to N
2025-12-16 10:58:19 × arandombit quits (~arandombi@user/arandombit) (Ping timeout: 260 seconds)
2025-12-16 10:58:21 <lucabtz> if finite there is not 1-1 mapping with N, but still countable
2025-12-16 10:58:21 <dminuoso> Given that `toEnum, fromEnum` are the minimal methods, and `toEnum` is in principle derivable from `fromEnum`... the loose description in the Haskell report really implies that its something along the lines of Countability.
2025-12-16 10:58:43 arandombit joins (~arandombi@user/arandombit)
2025-12-16 10:58:52 <dminuoso> lucabtz: Yes, Enum lacks the ability to talk about infinite sets.
2025-12-16 10:59:00 <merijn> and sparse sets
2025-12-16 10:59:14 <tomsmeding> merijn: we're talking about countability here, not usefulness
2025-12-16 10:59:32 <dminuoso> But that really goes into the line of "Haskell has Int in a lot of places where, morally, it should use Integer or Natural" instead.
2025-12-16 10:59:34 <lucabtz> tomsmeding: yeah i suppose dropping surjectivity is the same
2025-12-16 10:59:42 <dminuoso> The choice of `Int` in most places is because of history and performance.
2025-12-16 11:00:09 <dminuoso> So if we squint a bit, Enum is meant to be that Countable typeclass...
2025-12-16 11:01:11 <probie> and also reasonability, `(!!) :: [a] -> Integer -> a` doesn't gain you anything, because you don't have time to walk that very large list (nor enough memory unless it has a cycle)
2025-12-16 11:01:37 <tomsmeding> walking Int is also not particularly practical
2025-12-16 11:01:52 <tomsmeding> (on modern 64-bit machines)
2025-12-16 11:02:27 <dminuoso> probie: That's the other side of it. The [] structure is so pervasive because it both represents control flow *and* data. When its used for data, its a really poor fit because it results in terrible access patterns.
2025-12-16 11:02:52 × trickard_ quits (~trickard@cpe-81-98-47-163.wireline.com.au) (Read error: Connection reset by peer)
2025-12-16 11:02:56 <dminuoso> So on one hand we favour Int because its much faster due to direct mapping into machine registers, but then we drag those singly linked lists around everywhere.
2025-12-16 11:03:00 <dminuoso> A weird state we are in.
2025-12-16 11:03:06 trickard_ joins (~trickard@cpe-81-98-47-163.wireline.com.au)
2025-12-16 11:03:29 <probie> but for Enum, it's quite possible to want `[a..b]` where `fromEnum a - fromEnum b` is small, but `fromEnum a` is bigger than int
2025-12-16 11:03:53 <dminuoso> probie: Given that `fromEnum/toEnum` are minimal, one could assume that they should not be partial.
2025-12-16 11:04:05 <dminuoso> But there's so many bottoms flying around in base...
2025-12-16 11:04:42 <probie> Sorry, I was unclear. I mean for things that "should" be `Enum`, if there weren't too many of them
2025-12-16 11:04:48 <dminuoso> At least for `fromEnum` an argument could be made that it should behave in a cyclic fashion.
2025-12-16 11:04:59 <dminuoso> Or no, I meant `toEnum`
2025-12-16 11:05:37 <haskellbridge> <magic_rb> Singly linked lists make sense in many cases due to laziness, but generally one should use vector yes
2025-12-16 11:06:37 <probie> as in `Integer` is genuinely a better chouce needed for {to,from}Enum in a way that isn't the case in other places `Int` is used instead (like `(!!)`)
2025-12-16 11:06:38 <merijn> magic_rb: I don't think "generally you should use vector" is right.
2025-12-16 11:06:51 deptype joins (~deptype@2406:b400:3a:9d2f:476c:a58e:3471:ff37)
2025-12-16 11:06:53 <merijn> Don't get me wrong, Vector is *often* right, but I'm not sure I'd ever recommend defaulting to it
2025-12-16 11:07:01 <probie> Vector requires me to copy the whole thing to "change" a single element. This is often not desirable
2025-12-16 11:07:23 <dminuoso> I sometimes wish there was a kind of Vector/[] polymorphism, that I could myself decide what I want.
2025-12-16 11:07:29 <dminuoso> But something without typeclasses
2025-12-16 11:07:34 <merijn> probie: Vector doesn't always copy the whole thing, and also mutable Vector exists :)
2025-12-16 11:07:48 <dminuoso> What was that cabal feature along the lines of OCaml functors called again?
2025-12-16 11:07:51 <haskellbridge> <loonycyborg> in ST monad?
2025-12-16 11:07:51 <haskellbridge> <magic_rb> ^
2025-12-16 11:07:54 <merijn> dminuoso: backpack
2025-12-16 11:07:55 <probie> dminuoso: backpack
2025-12-16 11:07:57 <haskellbridge> <magic_rb> Yeah vector in ST
2025-12-16 11:08:03 <dminuoso> Right backpack.
2025-12-16 11:08:17 <merijn> loonycyborg: Vector has a bunch, there's ST, but also IO
2025-12-16 11:08:26 <merijn> Depending on your usecase
2025-12-16 11:08:30 <dminuoso> Yeah if via backpack I could just swap between vector or list for a given package that would be ideal.
2025-12-16 11:08:50 <dminuoso> Of course it's completely unreasonable for 2 major reasons.
2025-12-16 11:09:06 <merijn> tbh, I'm a big fan of "just thinking about your data type choices" :p
2025-12-16 11:09:07 <haskellbridge> <loonycyborg> But still it's procedural state, in haskell you'd want a persistent structure in general. Unless you wanna go all out for a hotspot.
2025-12-16 11:09:30 <merijn> Vector is very good for lots of things, and List good for lots of other things
2025-12-16 11:09:46 <dminuoso> merijn: For a library thats tought unless you like to duplicate interfaces. And with duplicated things you get the typical `toLazy/fromLazy` nonsense when passing text between library portions.
2025-12-16 11:10:13 <haskellbridge> <magic_rb> Generally List is fine if you dont care about performance and arent storing it around or traversing it in any other direction than linearly forward
2025-12-16 11:10:15 <probie> Vector is very good for lots of things, and GHC does some very heavy lifting to make List good for lots of other things :p
2025-12-16 11:10:42 <merijn> dminuoso: A library should use whatever's best for said library
2025-12-16 11:10:51 <merijn> especially since Vector.toList is super cheap
2025-12-16 11:11:06 <merijn> So someone wanting to pass a vector can easily convert to a list on demand
2025-12-16 11:12:54 <haskellbridge> <loonycyborg> There's also Seq, and Set and lots of other containers depending on your needs
2025-12-16 11:13:17 <probie> Let's just cut out the middle man and pass the fold `data List a = forall b . List ((a -> b -> b) -> b -> b)`
2025-12-16 11:13:24 <dminuoso> Maybe it depends a bit on your problem domain, but in one of our projects there's quite a bit of `pack/unpack`, `fromStrict/ToString` or even combinations going on.
2025-12-16 11:13:43 <dminuoso> There's just so much impedance mismatching going on when interfacing with more than one library at a time.
2025-12-16 11:13:54 Pixi joins (~Pixi@user/pixi)
2025-12-16 11:14:00 <probie> (to clarify, my above statement is a joke, since that meets even fewer use cases than a list)
2025-12-16 11:14:03 <dminuoso> And those problems are exactly the same as the above vector/list problems.
2025-12-16 11:14:11 <haskellbridge> <magic_rb> Sounds to me like things need to get more generic :)
2025-12-16 11:14:31 <dminuoso> probie: Joke is on you, thats precisely what GHC does behind the scenes for you in a lot of places.
2025-12-16 11:15:21 <dminuoso> Its what the whole build/foldr fusion works.
2025-12-16 11:15:57 <dminuoso> Or is that what you were hinting at?
2025-12-16 11:18:48 × ljdarj quits (~Thunderbi@user/ljdarj) (Read error: Connection reset by peer)
2025-12-16 11:20:03 xff0x joins (~xff0x@2405:6580:b080:900:4560:111e:4edd:d178)
2025-12-16 11:23:05 wootehfoot joins (~wootehfoo@user/wootehfoot)
2025-12-16 11:28:13 × merijn quits (~merijn@77.242.116.146) (Ping timeout: 264 seconds)
2025-12-16 11:28:27 × wootehfoot quits (~wootehfoo@user/wootehfoot) (Quit: Leaving)
2025-12-16 11:35:23 trickard_ is now known as trickard
2025-12-16 11:39:40 × Maxdamantus quits (~Maxdamant@user/maxdamantus) (Ping timeout: 255 seconds)

All times are in UTC.