Prism to Convert to Bounded Integral

I need Prism to convert Integral a => ato (Integral b, Bounded b) => b, ensuring that it areally fits into the type b. My current definition (below) requires use ScopedTypeVariablesand is pretty verbose.

I would like to know if there is a better (ideally already defined, and I missed) way to check if the number is suitable for the type Boundedor the safe conversion function that I can use to assemble the prism.

Current Definition:

boundedInt :: forall a b. (Integral a, Integral b, Bounded b) => Prism' a b
boundedInt = prism fromIntegral f where
  f n =
    if n >= fromIntegral (minBound :: b) && n <= fromIntegral (maxBound :: b)
    then Right (fromIntegral n)
    else Left n
+4
source share
2 answers

A bit unsatisfactory answer: I don’t think there is a library there that will help you here.

, -

safeIntegerToBoundedIntegral :: (Integral b, Bounded b) => Integer -> Maybe b
safeIntegerToBoundedIntegral = boundedFromInteger (minBound, maxBound)

-- helper function signature lets you avoid `ScopedTypeVariables`
boundedFromInteger :: Integral b => (b,b) -> Integer -> Maybe b
boundedFromInteger (lo,hi) n | toInteger lo <= n && n <= toInteger hi = Just (fromInteger n)
boundedFromInteger _ _ = Nothing

hoogle hayoo, :

integerAsIntegral :: Integral a => Iso' Integer a
integerAsIntegral = iso fromInteger toInteger

integerAsBoundedIntegral :: (Integral a, Bounded a) => Prism' Integer a
integerAsBoundedIntegral = prism toInteger $ \n -> 
  maybe (Left n) Right $ safeIntegerToBoundedIntegral n

integralAsBoundedIntegral :: (Integral a, Integral b, Bounded b) => Prism' a b
integralAsBoundedIntegral = from integerAsIntegral . integerAsBoundedIntegral

, , , fromIntegral ; .. a < bfromIntegral a < fromIntegral b, Integer Integral, .

+2

, " ?" " ?" Bounded:

narrowIntegral :: (Integral a, Integral b) => Prism' a b
narrowIntegral = prism fromIntegral f where
  f n | fromIntegral candidate == n = Right candidate
      | otherwise = Left n
      where candidate = fromIntegral n

, Integral, fromInteger . , - :

narrowIntegral :: (Integral a, NFData a, Integral b, NFData b) => Prism' a b
narrowIntegral = prism fromIntegral f where
  f n = n `deepseq` unsafePerformIO (narrow n)

narrow :: (Integral a, Integral b, NFData b) => a -> IO (Either a b)
narrow n = (evaluate . force) (narrow' n) `catches`
             [Handler (\(_ :: ArithException) -> return (Left n))
             ,Handler (\(_ :: PatternMatchFail) -> return (Left n))
             ,Handler (\(_ :: ErrorCall) -> return (Left n))]

narrow' n
  | fromIntegral candidate == n = Right candidate
  | otherwise = Left n
  where candidate = fromIntegral n
+2

Source: https://habr.com/ru/post/1619352/


All Articles