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