PROPOSAL: toBoundedIntegral: an adaptation of fromIntegral that respects bounds
Inspired by conversations recent [1] and not-so-recent [2] and by my own past wish for this, I propose adding the following function to base: toBoundedIntegral :: (Integral a, Integral b, Bounded b) => a -> Maybe b toBoundedIntegral x | y > toInteger (maxBound `asTypeOf` z) = Nothing | y < toInteger (minBound `asTypeOf` z) = Nothing | otherwise = Just $! z where y = toInteger x z = fromInteger y This includes rules to optimize for many cases where we know the bounds at compile time. See the gist for the full implementation: https://gist.github.com/spl/1986c9ff0b2416948957 I'm not particularly concerned with the precise location of this function. It could start out in GHC.Int if there's controversy. Otherwise, Data.Int would be an option to avoid polluting the Prelude. I chose the name to be descriptive of the result type, which is the more constrained type. The function that I started from [2] was called fromIntegralSafe, but I think “safe” is too ambiguous here. I did not find “toBoundedIntegral” in any package on Hackage. I welcome review of the implementation and rules. Discussion period: ~10 days if there is a strong desire to get it in GHC 7.10. (I would certainly like to see it get in.) Otherwise, I can make a package, and we can revisit the issue at another time. Regards, Sean [1] Evan Laforge: http://thread.gmane.org/gmane.comp.lang.haskell.cafe/113600/focus=113648 [2] Stephen Paul Weber: http://thread.gmane.org/gmane.comp.lang.haskell.cafe/102613/focus=64686
On 2014-11-12 at 08:14:49 +0100, Sean Leather wrote:
Inspired by conversations recent [1] and not-so-recent [2] and by my own past wish for this, I propose adding the following function to base:
toBoundedIntegral :: (Integral a, Integral b, Bounded b) => a -> Maybe b toBoundedIntegral x | y > toInteger (maxBound `asTypeOf` z) = Nothing | y < toInteger (minBound `asTypeOf` z) = Nothing | otherwise = Just $! z where y = toInteger x z = fromInteger y
Btw, a somewhat related approach I tuned heavily (but relies on 'Bits' rather than 'Bounded') http://hackage.haskell.org/package/int-cast-0.1.1.0/docs/Data-IntCast.html#v...
On 2014-11-12 at 08:14:49 +0100, Sean Leather wrote:
Inspired by conversations recent [1] and not-so-recent [2] and by my own past wish for this, I propose adding the following function to base:
toBoundedIntegral :: (Integral a, Integral b, Bounded b) => a -> Maybe b toBoundedIntegral x | y > toInteger (maxBound `asTypeOf` z) = Nothing | y < toInteger (minBound `asTypeOf` z) = Nothing | otherwise = Just $! z where y = toInteger x z = fromInteger y
This includes rules to optimize for many cases where we know the bounds at compile time. See the gist for the full implementation:
I'm a worried about the implementation requiring all those RULEs defined in order to get GHC to optimize it away. That looks like the wrong way to approach this, as by that you get something of an O(n^2) complexity when you need to add new integral types to the RULE set to account for all the potential direct conversion-paths between each pair. Moreover, you limit yourself to 'Bounded' types (which is why I resorted `Bits` rather than 'Bounded' for 'intCastMaybe' after noticing that I couldn't convert from (half)unbounded 'Integer' or 'Natural' to/from bounded types). So I'm on the fence about 'toBoundedIntegral', as for one I want such a facility for conversion, but OTOH, I'm not happy with the limitations 'toBoundedIntegral' exhibits. I'd like to see a more general solution. PS: While working on the `int-cast` package (as well as experimenting with type-level int literal-indexed integers[1]), I couldn't help but wonder if we benefit from some GHC-provided facility for reflecting integral boundary information at the type-level. One of the things I was wishing for was for Haskell to support arbitrary statically-typed (contiguous) sub-ranges of 'Integer' where GHC could then pick the most efficient underlying type. [1]: https://github.com/hvr/fixed-width-integers/blob/master/Data/Int/Fixed.hs
On Wed, Nov 12, 2014 at 12:18 PM, Herbert Valerio Riedel wrote:
Btw, a somewhat related approach I tuned heavily (but relies on 'Bits' rather than 'Bounded')
http://hackage.haskell.org/package/int-cast-0.1.1.0/docs/Data-IntCast.html#v...
Nice. I had admittedly forgotten about int-cast when I went looking for this kind of thing. I'm a worried about the implementation requiring all those RULEs defined
in order to get GHC to optimize it away. That looks like the wrong way to approach this, as by that you get something of an O(n^2) complexity when you need to add new integral types to the RULE set to account for all the potential direct conversion-paths between each pair.
That's a valid concern. Just so you know, this is nearly the same set of RULEs defined for fromIntegral. The fromIntegral RULEs just happen to be spread around different modules: Foreign.C.Types, GHC.Float, GHC.Int, GHC.Real, and GHC.Word. toBoundedIntegral has 101 vs. fromIntegral's 88 RULEs. The extra RULEs account for some 32-/64-bit special cases (with some alternatives behind #if's) and a few other cases that are not accounted for by the fromIntegral RULEs. For adding a numerical type to base, it effectively adds the same burden that fromIntegral requires in terms of RULEs. I'd love to be able to depend on the fromIntegral RULEs instead of adding toBoundedIntegral RULEs, but I found cases where the fromIntegral RULEs were not firing. So I thought I would make GHC's job easier by including all of the RULEs. If there's a better way, I'm all for it. Moreover, you limit yourself to 'Bounded' types (which is why I resorted
`Bits` rather than 'Bounded' for 'intCastMaybe' after noticing that I couldn't convert from (half)unbounded 'Integer' or 'Natural' to/from bounded types).
I'm not sure how the function is “limited” by using Bounded. Aren't they just different constraints? If your type doesn't have a Bits instance but does have a Bounded, then you would use the function that required Bounded. How often this happens in practice, I don't know. Anyway, I don't see a reason why we couldn't have both toBoundedIntegral and intCaseMaybe. Or, if you prefer intCaseMaybe, let's use that instead. I'm not strongly tied to toBoundedIntegral, but it would be nice to see something in base because more people will see it. So I'm on the fence about 'toBoundedIntegral', as for one I want such a
facility for conversion, but OTOH, I'm not happy with the limitations 'toBoundedIntegral' exhibits. I'd like to see a more general solution.
Just to be clear, I understand one limitation you've presented: the RULEs. You mentioned limiting to Bounded, but I'm not clear how that's a limitation compared to using Bits, as you do. What do you mean by a more general solution? IMHO, this is simply a “better” fromIntegral, and fromIntegral is used a lot for bounded types. I don't see how having toBoundedIntegral or intCaseMaybe precludes or diminishes other developments, esp. ones that deal with more type information. These functions are useful as they are now for many types. PS: While working on the `int-cast` package (as well as experimenting
with type-level int literal-indexed integers[1]), I couldn't help but wonder if we benefit from some GHC-provided facility for reflecting integral boundary information at the type-level. One of the things I was wishing for was for Haskell to support arbitrary statically-typed (contiguous) sub-ranges of 'Integer' where GHC could then pick the most efficient underlying type.
[1]: https://github.com/hvr/fixed-width-integers/blob/master/Data/Int/Fixed.hs
Also nice. Regards, Sean
On 2014-11-12 at 12:57:16 +0100, Sean Leather wrote: [...]
I'd love to be able to depend on the fromIntegral RULEs instead of adding toBoundedIntegral RULEs, but I found cases where the fromIntegral RULEs were not firing. So I thought I would make GHC's job easier by including all of the RULEs. If there's a better way, I'm all for it.
I didn't realise fromIntegral suffered from the same issue. I'm afraid I don't know a better way with the current infrastructure either :-/
Moreover, you limit yourself to 'Bounded' types (which is why I resorted `Bits` rather than 'Bounded' for 'intCastMaybe' after noticing that I couldn't convert from (half)unbounded 'Integer' or 'Natural' to/from bounded types).
I'm not sure how the function is “limited” by using Bounded.
I meant limited in that it excludes converting to/from integral types such as 'Integer'.
Aren't they just different constraints? If your type doesn't have a Bits instance but does have a Bounded, then you would use the function that required Bounded. How often this happens in practice, I don't know.
IMHO, It happens quite a lot actually that you go via 'Integer' to make sure you don't silently incur arithemtic overflows. I personally tend to do that in code where I'm interested in using checked conversions like `toBoundedIntegral` in the first place.
Anyway, I don't see a reason why we couldn't have both toBoundedIntegral and intCastMaybe. Or, if you prefer intCastMaybe, let's use that instead. I'm not strongly tied to toBoundedIntegral, but it would be nice to see something in base because more people will see it.
I guess that if we add toBoundedIntegral, I'd like to see toBitsIntegral as well. (IOW, I'd be +0.5 for adding both functions up to bikeshed-isomorphism)
So I'm on the fence about 'toBoundedIntegral', as for one I want such a facility for conversion, but OTOH, I'm not happy with the limitations 'toBoundedIntegral' exhibits. I'd like to see a more general solution.
Just to be clear, I understand one limitation you've presented: the RULEs. You mentioned limiting to Bounded, but I'm not clear how that's a limitation compared to using Bits, as you do.
What do you mean by a more general solution? IMHO, this is simply a “better” fromIntegral, and fromIntegral is used a lot for bounded types. I don't see how having toBoundedIntegral or intCastMaybe precludes or diminishes other developments, esp. ones that deal with more type information. These functions are useful as they are now for many types.
As stated above, if it's on the table to add both, I'm +0.5. As you say, they are indeed useful given the current infrastructure (which only gives us Integral/Enum/Num/Bounded/Bits to work with at this point) I'm curious though, if it's supposed to be a better 'fromIntegral', why did you chose the name 'toBoundedIntegral' rather than 'fromIntegralBounded' which has more resemblance to 'fromIntegral' (and has a closer tab-complete-distance to it as well)? Cheers, hvr PS: I've s/intCaseMaybe/intCastMaybe/ in the quoted parts to avoid confusion
On Wed, Nov 12, 2014 at 3:04 PM, Herbert Valerio Riedel wrote:
On 2014-11-12 at 12:57:16 +0100, Sean Leather wrote:
Moreover, you limit yourself to 'Bounded' types (which is why I resorted `Bits` rather than 'Bounded' for 'intCastMaybe' after noticing that I couldn't convert from (half)unbounded 'Integer' or 'Natural' to/from bounded types).
I'm not sure how the function is “limited” by using Bounded.
I meant limited in that it excludes converting to/from integral types such as 'Integer'.
I see, that's true. As far as I'm concerned, toInteger works well for the ->Integer direction and toBoundedIntegral works well for the Integer-> direction. My primary use for toBoundedIntegral is for larger-to-smaller integral type conversions.
Aren't they just different constraints? If your type doesn't have a
Bits instance but does have a Bounded, then you would use the function that required Bounded. How often this happens in practice, I don't know.
IMHO, It happens quite a lot actually that you go via 'Integer' to make sure you don't silently incur arithemtic overflows. I personally tend to do that in code where I'm interested in using checked conversions like `toBoundedIntegral` in the first place.
I meant that I don't know how often having a Bounded instance and no Bits instance (or vice versa) happens in practice. In other words, I'm not sure which is more likely needed – a function with a Bounded constraint or a function with a Bits constraint – or if it really matters much at all.
Anyway, I don't see a reason why we couldn't have both toBoundedIntegral
and intCastMaybe. Or, if you prefer intCastMaybe, let's use that instead. I'm not strongly tied to toBoundedIntegral, but it would be nice to see something in base because more people will see it.
I guess that if we add toBoundedIntegral, I'd like to see toBitsIntegral as well. (IOW, I'd be +0.5 for adding both functions up to bikeshed-isomorphism)
Works for me. I'd be happy with either one or both.
What do you mean by a more general solution? IMHO, this is simply a
“better” fromIntegral, and fromIntegral is used a lot for bounded types. I don't see how having toBoundedIntegral or intCastMaybe precludes or diminishes other developments, esp. ones that deal with more type information. These functions are useful as they are now for many types.
As stated above, if it's on the table to add both, I'm +0.5. As you say, they are indeed useful given the current infrastructure (which only gives us Integral/Enum/Num/Bounded/Bits to work with at this point)
Exactly. I'm curious though, if it's supposed to be a better 'fromIntegral', why
did you chose the name 'toBoundedIntegral' rather than 'fromIntegralBounded' which has more resemblance to 'fromIntegral' (and has a closer tab-complete-distance to it as well)?
Good bike-shedding question. In short, minimum ambiguity. To me, 'fromIntegralBounded' can be read as if the argument and not the result is Bounded. I felt 'toBoundedIntegral' used the convenient “adjective-ness” of 'Bounded' and 'Integral' to unambiguously describe the result. PS: I've s/intCaseMaybe/intCastMaybe/ in the quoted parts to avoid confusion
Thanks. My fingers have a tendency to type 'case' instead of 'cast'. Too much pattern-matching and too little conversion? Who knows. ;) Regards, Sean
I'm personally weakly +1 on this.
I've needed and duplicated the functionality before, and its just tricky
enough to cross the Fairbairn threshold, and baroque enough to be centrally
maintained with all the rewrite RULES to make it fast.
I don't have a strong preference over just doing this / doing both this and
fromBitsIntegral.
-Edward
On Wed, Nov 12, 2014 at 8:36 AM, Sean Leather
On Wed, Nov 12, 2014 at 3:04 PM, Herbert Valerio Riedel wrote:
On 2014-11-12 at 12:57:16 +0100, Sean Leather wrote:
Moreover, you limit yourself to 'Bounded' types (which is why I resorted `Bits` rather than 'Bounded' for 'intCastMaybe' after noticing that I couldn't convert from (half)unbounded 'Integer' or 'Natural' to/from bounded types).
I'm not sure how the function is “limited” by using Bounded.
I meant limited in that it excludes converting to/from integral types such as 'Integer'.
I see, that's true. As far as I'm concerned, toInteger works well for the ->Integer direction and toBoundedIntegral works well for the Integer-> direction. My primary use for toBoundedIntegral is for larger-to-smaller integral type conversions.
Aren't they just different constraints? If your type doesn't have a
Bits instance but does have a Bounded, then you would use the function that required Bounded. How often this happens in practice, I don't know.
IMHO, It happens quite a lot actually that you go via 'Integer' to make sure you don't silently incur arithemtic overflows. I personally tend to do that in code where I'm interested in using checked conversions like `toBoundedIntegral` in the first place.
I meant that I don't know how often having a Bounded instance and no Bits instance (or vice versa) happens in practice. In other words, I'm not sure which is more likely needed – a function with a Bounded constraint or a function with a Bits constraint – or if it really matters much at all.
Anyway, I don't see a reason why we couldn't have both toBoundedIntegral
and intCastMaybe. Or, if you prefer intCastMaybe, let's use that instead. I'm not strongly tied to toBoundedIntegral, but it would be nice to see something in base because more people will see it.
I guess that if we add toBoundedIntegral, I'd like to see toBitsIntegral as well. (IOW, I'd be +0.5 for adding both functions up to bikeshed-isomorphism)
Works for me. I'd be happy with either one or both.
What do you mean by a more general solution? IMHO, this is simply a
“better” fromIntegral, and fromIntegral is used a lot for bounded types. I don't see how having toBoundedIntegral or intCastMaybe precludes or diminishes other developments, esp. ones that deal with more type information. These functions are useful as they are now for many types.
As stated above, if it's on the table to add both, I'm +0.5. As you say, they are indeed useful given the current infrastructure (which only gives us Integral/Enum/Num/Bounded/Bits to work with at this point)
Exactly.
I'm curious though, if it's supposed to be a better 'fromIntegral', why
did you chose the name 'toBoundedIntegral' rather than 'fromIntegralBounded' which has more resemblance to 'fromIntegral' (and has a closer tab-complete-distance to it as well)?
Good bike-shedding question. In short, minimum ambiguity. To me, 'fromIntegralBounded' can be read as if the argument and not the result is Bounded. I felt 'toBoundedIntegral' used the convenient “adjective-ness” of 'Bounded' and 'Integral' to unambiguously describe the result.
PS: I've s/intCaseMaybe/intCastMaybe/ in the quoted parts to avoid
confusion
Thanks. My fingers have a tendency to type 'case' instead of 'cast'. Too much pattern-matching and too little conversion? Who knows. ;)
Regards, Sean
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
On Wed, Nov 12, 2014 at 3:04 PM, Herbert Valerio Riedel wrote:
As stated above, if it's on the table to add both, I'm +0.5. As you say, they are indeed useful given the current infrastructure (which only gives us Integral/Enum/Num/Bounded/Bits to work with at this point)
On Fri, Nov 14, 2014 at 7:17 PM, Edward Kmett wrote:
I'm personally weakly +1 on this.
I've needed and duplicated the functionality before, and its just tricky enough to cross the Fairbairn threshold, and baroque enough to be centrally maintained with all the rewrite RULES to make it fast.
I don't have a strong preference over just doing this / doing both this and fromBitsIntegral.
Okay. Assuming the lack of response implies lack of interest, there doesn't seem to be a lot of interest. But of those who responded, there is weak positive interest. So I'm going to push a bit more to gauge interest and to see what to do next. We have now two options on the table: 1. toBoundedIntegral :: (Integral a, Integral b, Bounded b) => a -> Maybe b 2. intCastMaybe :: (Integral a, Integral b, Bits a, Bits b) => a -> Maybe b As a user of these functions, I read the first type as a conversion from a possibly unbounded integral type to a bounded integral type, while the second type isn't as explicit (to me) about its implementation or intended purpose. But it is clear that the second offers conversions between unbounded types, while the first does not. (This is important considering the new addition of Natural.) We also have the Natural type being discussed in a separate thread. My impression of that thread is that people are enthusiastic about the inclusion, if only concerned about how to deal with partial operations. With that in mind, I think this is an appropriate time to extend the base library to add support for converting between integral types while respecting bounds and sizes. Therefore, I unambiguously propose adding both functions. I think they are both useful in their own ways (which are obviously overlapping but can be separate). I do, however, suggest renaming intCastMaybe. Edward mentioned fromBitsIntegral. I would suggest toSizedIntegral (or fromSizedIntegral/fromIntegralSized, but I think toSizedIntegral is meaningful since it describes the result, not the argument), since that indicates the real usage of Bits in the function (which use bitSizeMaybe). Other bikeshed colors? Also, assuming there is enough interest (how much is enough?), I'd like to know what the next steps should be. Should someone create a Phab diff for it? (I can try it; however, I haven't yet used Phab, so, Herbert, if you want to do it with your code and mine, you can.) Also, we have to consider the Natural proposal and the toBoundedIntegral RULEs for it. Where should the functions go? intCastMaybe/toSizedIntegral could go in Data.Bits. What about toBoundedIntegral? Regards, Sean
On 2014-11-16 at 11:51:11 +0100, Sean Leather wrote: [...]
I do, however, suggest renaming intCastMaybe. Edward mentioned fromBitsIntegral. I would suggest toSizedIntegral (or fromSizedIntegral/fromIntegralSized, but I think toSizedIntegral is meaningful since it describes the result, not the argument), since that indicates the real usage of Bits in the function (which use bitSizeMaybe). Other bikeshed colors?
Fwiw, I'd be fine with all of `{to,from}{SizedIntegral,IntegralSized}`. (my only concern would about the (mathematical) term 'integral' which is a bit overloaded (try searching for "bounded integral"), but given Haskell already established a precedent by 'fromIntegral' I guess there's little risk of confusion here)
Also, assuming there is enough interest (how much is enough?), I'd like to know what the next steps should be.
Should someone create a Phab diff for it? (I can try it; however, I haven't yet used Phab, so, Herbert, if you want to do it with your code and mine, you can.) Also, we have to consider the Natural proposal and the toBoundedIntegral RULEs for it.
about the RULEs... do we really need them for `toBoundedIntegral`? If you make `toBoundedIntegral` INLINEABLE, shouldn't you be able to inherit the ones from 'fromIntegral' (which is what `intCastMaybe` exploits)?
Where should the functions go? intCastMaybe/toSizedIntegral could go in Data.Bits. What about toBoundedIntegral?
There's also http://hackage.haskell.org/package/base-4.7.0.1/docs/Numeric.html as a candidate
On Mon, Nov 17, 2014 at 10:42 AM, Herbert Valerio Riedel wrote:
On 2014-11-16 at 11:51:11 +0100, Sean Leather wrote:
I do, however, suggest renaming intCastMaybe. Edward mentioned fromBitsIntegral. I would suggest toSizedIntegral (or fromSizedIntegral/fromIntegralSized, but I think toSizedIntegral is meaningful since it describes the result, not the argument), since that indicates the real usage of Bits in the function (which use bitSizeMaybe). Other bikeshed colors?
Fwiw, I'd be fine with all of `{to,from}{SizedIntegral,IntegralSized}`.
Excellent. I do think it's more useful to use a name that identifies the direction to or from the more restrictive type and/or constraints. For example, 'fromIntegral :: (Integral a, Num b) => a -> b' identifies that it's converting from a more restrictive constraint to a less restrictive. 'toBoundedIntegral' does the reverse; therefore, I think it's useful to use 'to' instead of 'from'. Whereas, for 'toSizedIntegral', the constraints are equivalent, but the size of the result type may be smaller. So, I think 'to' is better than 'from' in this case. (my only concern would about the (mathematical) term 'integral' which is
a bit overloaded (try searching for "bounded integral"), but given Haskell already established a precedent by 'fromIntegral' I guess there's little risk of confusion here)
I can see that "bounded integral" and "sized integral" are somewhat ambiguous if you are not trained in the 'fromIntegral' thinking. And putting something in the middle of 'to' and 'Integral' may make it less obvious that these functions are related to 'fromIntegral'. So is there any reason not to settle on 'toIntegralBounded' and 'toIntegralSized'?
Also, assuming there is enough interest (how much is enough?), I'd like to
know what the next steps should be.
Should someone create a Phab diff for it? (I can try it; however, I haven't yet used Phab, so, Herbert, if you want to do it with your code and mine, you can.) Also, we have to consider the Natural proposal and the toBoundedIntegral RULEs for it.
about the RULEs... do we really need them for `toBoundedIntegral`? If you make `toBoundedIntegral` INLINEABLE, shouldn't you be able to inherit the ones from 'fromIntegral' (which is what `intCastMaybe` exploits)?
I didn't try that. I'll give it a shot.
Where should the functions go? intCastMaybe/toSizedIntegral could go in
Data.Bits. What about toBoundedIntegral?
There's also
http://hackage.haskell.org/package/base-4.7.0.1/docs/Numeric.html
as a candidate
Works for me. We could rename the section “Miscellaneous” to “Conversion” and put both functions there. Also, we should probably revise the module description since there is already a lot more than “functions for reading and showing RealFloat-like kind of values.” Regards, Sean
"Sized" seems kind of strangely named to me.
On Mon, Nov 17, 2014 at 4:10 AM, Sean Leather
On Mon, Nov 17, 2014 at 10:42 AM, Herbert Valerio Riedel wrote:
On 2014-11-16 at 11:51:11 +0100, Sean Leather wrote:
I do, however, suggest renaming intCastMaybe. Edward mentioned fromBitsIntegral. I would suggest toSizedIntegral (or fromSizedIntegral/fromIntegralSized, but I think toSizedIntegral is meaningful since it describes the result, not the argument), since that indicates the real usage of Bits in the function (which use bitSizeMaybe). Other bikeshed colors?
Fwiw, I'd be fine with all of `{to,from}{SizedIntegral,IntegralSized}`.
Excellent.
I do think it's more useful to use a name that identifies the direction to or from the more restrictive type and/or constraints. For example, 'fromIntegral :: (Integral a, Num b) => a -> b' identifies that it's converting from a more restrictive constraint to a less restrictive. 'toBoundedIntegral' does the reverse; therefore, I think it's useful to use 'to' instead of 'from'. Whereas, for 'toSizedIntegral', the constraints are equivalent, but the size of the result type may be smaller. So, I think 'to' is better than 'from' in this case.
(my only concern would about the (mathematical) term 'integral' which is
a bit overloaded (try searching for "bounded integral"), but given Haskell already established a precedent by 'fromIntegral' I guess there's little risk of confusion here)
I can see that "bounded integral" and "sized integral" are somewhat ambiguous if you are not trained in the 'fromIntegral' thinking. And putting something in the middle of 'to' and 'Integral' may make it less obvious that these functions are related to 'fromIntegral'.
So is there any reason not to settle on 'toIntegralBounded' and 'toIntegralSized'?
Also, assuming there is enough interest (how much is enough?), I'd like to
know what the next steps should be.
Should someone create a Phab diff for it? (I can try it; however, I haven't yet used Phab, so, Herbert, if you want to do it with your code and mine, you can.) Also, we have to consider the Natural proposal and the toBoundedIntegral RULEs for it.
about the RULEs... do we really need them for `toBoundedIntegral`? If you make `toBoundedIntegral` INLINEABLE, shouldn't you be able to inherit the ones from 'fromIntegral' (which is what `intCastMaybe` exploits)?
I didn't try that. I'll give it a shot.
Where should the functions go? intCastMaybe/toSizedIntegral could go in
Data.Bits. What about toBoundedIntegral?
There's also
http://hackage.haskell.org/package/base-4.7.0.1/docs/Numeric.html
as a candidate
Works for me. We could rename the section “Miscellaneous” to “Conversion” and put both functions there. Also, we should probably revise the module description since there is already a lot more than “functions for reading and showing RealFloat-like kind of values.”
Regards, Sean
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
On Wed, Nov 12, 2014 at 9:14 AM, Sean Leather wrote:
Inspired by conversations recent [1] and not-so-recent [2] and by my own past wish for this, I propose adding the following function to base:
toBoundedIntegral :: (Integral a, Integral b, Bounded b) => a -> Maybe b
[...] Discussion period: ~10 days if there is a strong desire to get it in GHC
7.10. (I would certainly like to see it get in.)
Almost over. Here are some follow-ups on Trac and Phab. GHC Trac: https://ghc.haskell.org/trac/ghc/ticket/9816 Phab Diff: https://phabricator.haskell.org/D512 On Mon, Nov 17, 2014 at 11:10 AM, Sean Leather wrote:
So is there any reason not to settle on 'toIntegralBounded' and 'toIntegralSized'?
I decided to drop 'toIntegralBounded' go with only 'toIntegralSized' in my proposal. I realized that the former was not handling Int<->Word-like cases optimally and would require special attention to them while the latter provides them for free. Herbert: It was nice that 'intCastMaybe' was an easy copy-paste into another module. I did a bit of rewriting the comments and code formatting. Hope you don't mind, or bash me on Phab if you prefer. ;) Also, it would be nice to have your tests in the library. Any thoughts on how to do that? I haven't looked into it, yet. about the RULEs... do we really need them for `toBoundedIntegral`? If
you make `toBoundedIntegral` INLINEABLE, shouldn't you be able to inherit the ones from 'fromIntegral' (which is what `intCastMaybe` exploits)?
I didn't try that. I'll give it a shot.
I did try it, and I'm not sure how to make that work. 'toBoundedIntegral' splits the 'toInteger' and 'fromInteger' and puts the bounds check in the middle, so 'fromIntegral' is not used. If it were used, then I believe there would be redundant 'toInteger' conversions for types that weren't covered by RULEs.
Where should the functions go? intCastMaybe/toSizedIntegral could go in
Data.Bits. What about toBoundedIntegral?
There's also
http://hackage.haskell.org/package/base-4.7.0.1/docs/Numeric.html
as a candidate
Works for me. We could rename the section “Miscellaneous” to “Conversion” and put both functions there. Also, we should probably revise the module description since there is already a lot more than “functions for reading and showing RealFloat-like kind of values.”
I decided on Data.Bits since it seemed to be the most obvious place for 'toIntegralSized' alone. Also, I think there might be an import cycle if I put it into Numeric. But if others have a preference and want to make it work somewhere else, that's fine with me. Regards, Sean
That bitSizeMaybe makes me a bit nervous. Would it actually hurt anyone to
make this thing a subclass of FiniteBits?
On Thu, Nov 20, 2014 at 4:46 PM, Sean Leather
On Wed, Nov 12, 2014 at 9:14 AM, Sean Leather wrote:
Inspired by conversations recent [1] and not-so-recent [2] and by my own past wish for this, I propose adding the following function to base:
toBoundedIntegral :: (Integral a, Integral b, Bounded b) => a -> Maybe b
[...]
Discussion period: ~10 days if there is a strong desire to get it in GHC
7.10. (I would certainly like to see it get in.)
Almost over. Here are some follow-ups on Trac and Phab.
GHC Trac: https://ghc.haskell.org/trac/ghc/ticket/9816 Phab Diff: https://phabricator.haskell.org/D512
On Mon, Nov 17, 2014 at 11:10 AM, Sean Leather wrote:
So is there any reason not to settle on 'toIntegralBounded' and 'toIntegralSized'?
I decided to drop 'toIntegralBounded' go with only 'toIntegralSized' in my proposal. I realized that the former was not handling Int<->Word-like cases optimally and would require special attention to them while the latter provides them for free.
Herbert: It was nice that 'intCastMaybe' was an easy copy-paste into another module. I did a bit of rewriting the comments and code formatting. Hope you don't mind, or bash me on Phab if you prefer. ;) Also, it would be nice to have your tests in the library. Any thoughts on how to do that? I haven't looked into it, yet.
about the RULEs... do we really need them for `toBoundedIntegral`? If
you make `toBoundedIntegral` INLINEABLE, shouldn't you be able to inherit the ones from 'fromIntegral' (which is what `intCastMaybe` exploits)?
I didn't try that. I'll give it a shot.
I did try it, and I'm not sure how to make that work. 'toBoundedIntegral' splits the 'toInteger' and 'fromInteger' and puts the bounds check in the middle, so 'fromIntegral' is not used. If it were used, then I believe there would be redundant 'toInteger' conversions for types that weren't covered by RULEs.
Where should the functions go? intCastMaybe/toSizedIntegral could go in
Data.Bits. What about toBoundedIntegral?
There's also
http://hackage.haskell.org/package/base-4.7.0.1/docs/Numeric.html
as a candidate
Works for me. We could rename the section “Miscellaneous” to “Conversion” and put both functions there. Also, we should probably revise the module description since there is already a lot more than “functions for reading and showing RealFloat-like kind of values.”
I decided on Data.Bits since it seemed to be the most obvious place for 'toIntegralSized' alone. Also, I think there might be an import cycle if I put it into Numeric. But if others have a preference and want to make it work somewhere else, that's fine with me.
Regards, Sean
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
Er... Obviously, I mean give this a FiniteBits *context*.
On Thu, Nov 20, 2014 at 6:08 PM, David Feuer
That bitSizeMaybe makes me a bit nervous. Would it actually hurt anyone to make this thing a subclass of FiniteBits?
On Thu, Nov 20, 2014 at 4:46 PM, Sean Leather
wrote: On Wed, Nov 12, 2014 at 9:14 AM, Sean Leather wrote:
Inspired by conversations recent [1] and not-so-recent [2] and by my own past wish for this, I propose adding the following function to base:
toBoundedIntegral :: (Integral a, Integral b, Bounded b) => a -> Maybe b
[...]
Discussion period: ~10 days if there is a strong desire to get it in GHC
7.10. (I would certainly like to see it get in.)
Almost over. Here are some follow-ups on Trac and Phab.
GHC Trac: https://ghc.haskell.org/trac/ghc/ticket/9816 Phab Diff: https://phabricator.haskell.org/D512
On Mon, Nov 17, 2014 at 11:10 AM, Sean Leather wrote:
So is there any reason not to settle on 'toIntegralBounded' and 'toIntegralSized'?
I decided to drop 'toIntegralBounded' go with only 'toIntegralSized' in my proposal. I realized that the former was not handling Int<->Word-like cases optimally and would require special attention to them while the latter provides them for free.
Herbert: It was nice that 'intCastMaybe' was an easy copy-paste into another module. I did a bit of rewriting the comments and code formatting. Hope you don't mind, or bash me on Phab if you prefer. ;) Also, it would be nice to have your tests in the library. Any thoughts on how to do that? I haven't looked into it, yet.
about the RULEs... do we really need them for `toBoundedIntegral`? If
you make `toBoundedIntegral` INLINEABLE, shouldn't you be able to inherit the ones from 'fromIntegral' (which is what `intCastMaybe` exploits)?
I didn't try that. I'll give it a shot.
I did try it, and I'm not sure how to make that work. 'toBoundedIntegral' splits the 'toInteger' and 'fromInteger' and puts the bounds check in the middle, so 'fromIntegral' is not used. If it were used, then I believe there would be redundant 'toInteger' conversions for types that weren't covered by RULEs.
Where should the functions go? intCastMaybe/toSizedIntegral could go in
Data.Bits. What about toBoundedIntegral?
There's also
http://hackage.haskell.org/package/base-4.7.0.1/docs/Numeric.html
as a candidate
Works for me. We could rename the section “Miscellaneous” to “Conversion” and put both functions there. Also, we should probably revise the module description since there is already a lot more than “functions for reading and showing RealFloat-like kind of values.”
I decided on Data.Bits since it seemed to be the most obvious place for 'toIntegralSized' alone. Also, I think there might be an import cycle if I put it into Numeric. But if others have a preference and want to make it work somewhere else, that's fine with me.
Regards, Sean
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
On Fri, Nov 21, 2014 at 1:08 AM, David Feuer wrote:
That bitSizeMaybe makes me a bit nervous.
Can you clarify what makes you nervous about it? Is it the assumption that when bitSizeMaybe == Nothing, the size is infinite? Would it actually hurt anyone to make this thing a subclass of FiniteBits? Er... Obviously, I mean give this a FiniteBits *context*.
Yes, it would reduce the usefulness of the function to finite types in the result, whereas now it can be used, for example, to convert Integer to Natural. Regards, Sean
Yes, it would.
The use of bitSizeMaybe is deliberate.
That way it doesn't have to bound itself when converting an infinite type.
The whole point of this is that it works for infinite cases.
-Edward
On Thu, Nov 20, 2014 at 6:08 PM, David Feuer
That bitSizeMaybe makes me a bit nervous. Would it actually hurt anyone to make this thing a subclass of FiniteBits?
On Thu, Nov 20, 2014 at 4:46 PM, Sean Leather
wrote: On Wed, Nov 12, 2014 at 9:14 AM, Sean Leather wrote:
Inspired by conversations recent [1] and not-so-recent [2] and by my own past wish for this, I propose adding the following function to base:
toBoundedIntegral :: (Integral a, Integral b, Bounded b) => a -> Maybe b
[...]
Discussion period: ~10 days if there is a strong desire to get it in GHC
7.10. (I would certainly like to see it get in.)
Almost over. Here are some follow-ups on Trac and Phab.
GHC Trac: https://ghc.haskell.org/trac/ghc/ticket/9816 Phab Diff: https://phabricator.haskell.org/D512
On Mon, Nov 17, 2014 at 11:10 AM, Sean Leather wrote:
So is there any reason not to settle on 'toIntegralBounded' and 'toIntegralSized'?
I decided to drop 'toIntegralBounded' go with only 'toIntegralSized' in my proposal. I realized that the former was not handling Int<->Word-like cases optimally and would require special attention to them while the latter provides them for free.
Herbert: It was nice that 'intCastMaybe' was an easy copy-paste into another module. I did a bit of rewriting the comments and code formatting. Hope you don't mind, or bash me on Phab if you prefer. ;) Also, it would be nice to have your tests in the library. Any thoughts on how to do that? I haven't looked into it, yet.
about the RULEs... do we really need them for `toBoundedIntegral`? If
you make `toBoundedIntegral` INLINEABLE, shouldn't you be able to inherit the ones from 'fromIntegral' (which is what `intCastMaybe` exploits)?
I didn't try that. I'll give it a shot.
I did try it, and I'm not sure how to make that work. 'toBoundedIntegral' splits the 'toInteger' and 'fromInteger' and puts the bounds check in the middle, so 'fromIntegral' is not used. If it were used, then I believe there would be redundant 'toInteger' conversions for types that weren't covered by RULEs.
Where should the functions go? intCastMaybe/toSizedIntegral could go in
Data.Bits. What about toBoundedIntegral?
There's also
http://hackage.haskell.org/package/base-4.7.0.1/docs/Numeric.html
as a candidate
Works for me. We could rename the section “Miscellaneous” to “Conversion” and put both functions there. Also, we should probably revise the module description since there is already a lot more than “functions for reading and showing RealFloat-like kind of values.”
I decided on Data.Bits since it seemed to be the most obvious place for 'toIntegralSized' alone. Also, I think there might be an import cycle if I put it into Numeric. But if others have a preference and want to make it work somewhere else, that's fine with me.
Regards, Sean
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
On Thu, Nov 20, 2014 at 11:46 PM, Sean Leather wrote:
Almost over. Here are some follow-ups on Trac and Phab.
GHC Trac: https://ghc.haskell.org/trac/ghc/ticket/9816 Phab Diff: https://phabricator.haskell.org/D512
Just to follow up, this proposal has been accepted and merged (02f8f6ad7bd3d792459a1d33e8d0d57dcf1ea424). Thanks for the discussion, everyone! Regards, Sean
participants (4)
-
David Feuer -
Edward Kmett -
Herbert Valerio Riedel -
Sean Leather