{-# LANGUAGE NoImplicitPrelude #-}
module Data.Digit.Integral(
integralBinaryNoZero
, integralBinary
, integralBinDigits
, binDigitsIntegral
, integralOctalNoZero
, integralOctal
, integralOctDigits
, octDigitsIntegral
, integralDecimal
, integralDecimalNoZero
, integralDecDigits
, decDigitsIntegral
, integralHexadecimalNoZero
, integralHexadecimal
, integralHexDigits
, hexDigitsIntegral
, integralHEXADECIMALNoZero
, integralHEXADECIMAL
, integralHEXDigits
, _HEXDigitsIntegral
, integralHeXaDeCiMaLNoZero
, integralHeXaDeCiMaL
, _HeXDigitsIntegral
) where
import Prelude (error)
import Control.Lens.Extras(is)
import Data.Digit.Binary
import Data.Digit.Decimal
import Data.Digit.Octal
import Data.Digit.Hexadecimal
import Data.Digit.HEXADECIMAL
import Data.Digit.HeXaDeCiMaL
import qualified Data.List.NonEmpty as NonEmpty
import Papa
integralBinaryNoZero ::
(Integral a, BinaryNoZero d) =>
Prism'
a
d
integralBinaryNoZero =
associatePrism (1, d1) []
integralBinary ::
(Integral a, Binary d) =>
Prism'
a
d
integralBinary =
associatePrism (0, d0) [(1, d1)]
integralBinDigits :: Integral a => a -> Either (NonEmpty BinDigit) (NonEmpty BinDigit)
integralBinDigits n =
if n >= 0
then Right . NonEmpty.fromList $ go n []
else Left . NonEmpty.fromList $ go (-n - 1) []
where
go k =
let
(q, r) = quotRem k 2
in
(if q == 0 then id else go q) . ((r ^?! integralBinary) :)
binDigitsIntegral :: Integral a => Either (NonEmpty BinDigit) (NonEmpty BinDigit) -> a
binDigitsIntegral = either (\n -> -(go n) - 1) go
where
go = foldl' (\b a -> (integralBinary # a) + 2 * b) 0
integralOctalNoZero ::
(Integral a, OctalNoZero d) =>
Prism'
a
d
integralOctalNoZero =
associatePrism (1, d1) [(2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7)]
integralOctal ::
(Integral a, Octal d) =>
Prism'
a
d
integralOctal =
associatePrism (0, d0) [(1, d1), (2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7)]
integralOctDigits :: Integral a => a -> Either (NonEmpty OctDigit) (NonEmpty OctDigit)
integralOctDigits n =
if n >= 0
then Right . NonEmpty.fromList $ go n []
else Left . NonEmpty.fromList $ go (-n - 1) []
where
go k =
let
(q, r) = quotRem k 8
in
(if q == 0 then id else go q) . ((r ^?! integralOctal) :)
octDigitsIntegral :: Integral a => Either (NonEmpty OctDigit) (NonEmpty OctDigit) -> a
octDigitsIntegral = either (\n -> -(go n) - 1) go
where
go = foldl' (\b a -> (integralOctal # a) + 8 * b) 0
integralDecimalNoZero ::
(Integral a, DecimalNoZero d) =>
Prism'
a
d
integralDecimalNoZero =
associatePrism (1, d1) [(2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9)]
integralDecimal ::
(Integral a, Decimal d) =>
Prism'
a
d
integralDecimal =
associatePrism (0, d0) [(1, d1), (2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9)]
integralDecDigits :: Integral a => a -> Either (NonEmpty DecDigit) (NonEmpty DecDigit)
integralDecDigits n =
if n >= 0
then Right . NonEmpty.fromList $ go n []
else Left . NonEmpty.fromList $ go (-n - 1) []
where
go k =
let
(q, r) = quotRem k 10
in
(if q == 0 then id else go q) . ((r ^?! integralDecimal) :)
decDigitsIntegral :: Integral a => Either (NonEmpty DecDigit) (NonEmpty DecDigit) -> a
decDigitsIntegral = either (\n -> -(go n) - 1) go
where
go = foldl' (\b a -> (integralDecimal # a) + 10 * b) 0
integralHexadecimalNoZero ::
(Integral a, HexadecimalNoZero d) =>
Prism'
a
d
integralHexadecimalNoZero =
associatePrism (1, d1) [(2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9), (10, da), (11, db), (12, dc), (13, dd), (14, de), (15, df)]
integralHexadecimal ::
(Integral a, Hexadecimal d) =>
Prism'
a
d
integralHexadecimal =
associatePrism (0, d0) [(1, d1), (2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9), (10, da), (11, db), (12, dc), (13, dd), (14, de), (15, df)]
integralHexDigits :: Integral a => a -> Either (NonEmpty HexDigit) (NonEmpty HexDigit)
integralHexDigits n =
if n >= 0
then Right . NonEmpty.fromList $ go n []
else Left . NonEmpty.fromList $ go (-n - 1) []
where
go k =
let
(q, r) = quotRem k 16
in
(if q == 0 then id else go q) . ((r ^?! integralHexadecimal) :)
hexDigitsIntegral :: Integral a => Either (NonEmpty HexDigit) (NonEmpty HexDigit) -> a
hexDigitsIntegral = either (\n -> -(go n) - 1) go
where
go = foldl' (\b a -> (integralHexadecimal # a) + 16 * b) 0
integralHEXADECIMALNoZero ::
(Integral a, HEXADECIMALNoZero d) =>
Prism'
a
d
integralHEXADECIMALNoZero =
associatePrism (1, d1) [(2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9), (10, dA), (11, dB), (12, dC), (13, dD), (14, dE), (15, dF)]
integralHEXADECIMAL ::
(Integral a, HEXADECIMAL d) =>
Prism'
a
d
integralHEXADECIMAL =
associatePrism (0, d0) [(1, d1), (2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9), (10, dA), (11, dB), (12, dC), (13, dD), (14, dE), (15, dF)]
integralHEXDigits :: Integral a => a -> Either (NonEmpty HEXDigit) (NonEmpty HEXDigit)
integralHEXDigits n =
if n >= 0
then Right . NonEmpty.fromList $ go n []
else Left . NonEmpty.fromList $ go (-n - 1) []
where
go k =
let
(q, r) = quotRem k 16
in
(if q == 0 then id else go q) . ((r ^?! integralHEXADECIMAL) :)
_HEXDigitsIntegral :: Integral a => Either (NonEmpty HEXDigit) (NonEmpty HEXDigit) -> a
_HEXDigitsIntegral = either (\n -> -(go n) - 1) go
where
go = foldl' (\b a -> (integralHEXADECIMAL # a) + 16 * b) 0
integralHeXaDeCiMaLNoZero ::
(Integral a, HeXaDeCiMaLNoZero d) =>
Review
a
d
integralHeXaDeCiMaLNoZero =
unto
(outside d1 .~ (\_ -> 1) $
outside d2 .~ (\_ -> 2) $
outside d3 .~ (\_ -> 3) $
outside d4 .~ (\_ -> 4) $
outside d5 .~ (\_ -> 5) $
outside d6 .~ (\_ -> 6) $
outside d7 .~ (\_ -> 7) $
outside d8 .~ (\_ -> 8) $
outside d9 .~ (\_ -> 9) $
outside da .~ (\_ -> 10) $
outside dA .~ (\_ -> 10) $
outside db .~ (\_ -> 11) $
outside dB .~ (\_ -> 11) $
outside dc .~ (\_ -> 12) $
outside dC .~ (\_ -> 12) $
outside dd .~ (\_ -> 13) $
outside dD .~ (\_ -> 13) $
outside de .~ (\_ -> 14) $
outside dE .~ (\_ -> 14) $
outside df .~ (\_ -> 15) $
outside dF .~ (\_ -> 15) $
error "incomplete pattern")
integralHeXaDeCiMaL ::
(Integral a, HeXaDeCiMaL d) =>
Review
a
d
integralHeXaDeCiMaL =
unto
(outside d0 .~ (\_ -> 0) $
outside d1 .~ (\_ -> 1) $
outside d2 .~ (\_ -> 2) $
outside d3 .~ (\_ -> 3) $
outside d4 .~ (\_ -> 4) $
outside d5 .~ (\_ -> 5) $
outside d6 .~ (\_ -> 6) $
outside d7 .~ (\_ -> 7) $
outside d8 .~ (\_ -> 8) $
outside d9 .~ (\_ -> 9) $
outside da .~ (\_ -> 10) $
outside dA .~ (\_ -> 10) $
outside db .~ (\_ -> 11) $
outside dB .~ (\_ -> 11) $
outside dc .~ (\_ -> 12) $
outside dC .~ (\_ -> 12) $
outside dd .~ (\_ -> 13) $
outside dD .~ (\_ -> 13) $
outside de .~ (\_ -> 14) $
outside dE .~ (\_ -> 14) $
outside df .~ (\_ -> 15) $
outside dF .~ (\_ -> 15) $
error "incomplete pattern")
_HeXDigitsIntegral :: Integral a => Either (NonEmpty HeXDigit) (NonEmpty HeXDigit) -> a
_HeXDigitsIntegral = either (\n -> -(go n) - 1) go
where
go = foldl' (\b a -> (integralHeXaDeCiMaL # a) + 16 * b) 0
associatePrism ::
(Eq b, Choice p, Applicative f) =>
(b, APrism a a () ())
-> [(b, APrism a a () ())]
-> p a (f a)
-> p b (f b)
associatePrism def z =
prism'
(\d -> fst (fromMaybe def (find (\(_, w) -> is w d) z)))
(\i -> (\p -> clonePrism p # ()) <$> lookup i (def:z))