{-# OPTIONS_GHC -Wall #-}
module ToySolver.Internal.Util where
import Control.Monad
import Data.Ratio
import Data.Set (Set)
import qualified Data.Set as Set
import System.IO
import GHC.IO.Encoding
combineMaybe :: (a -> a -> a) -> Maybe a -> Maybe a -> Maybe a
combineMaybe :: forall a. (a -> a -> a) -> Maybe a -> Maybe a -> Maybe a
combineMaybe a -> a -> a
_ Maybe a
Nothing Maybe a
y = Maybe a
y
combineMaybe a -> a -> a
_ Maybe a
x Maybe a
Nothing = Maybe a
x
combineMaybe a -> a -> a
f (Just a
x) (Just a
y) = forall a. a -> Maybe a
Just (a -> a -> a
f a
x a
y)
isInteger :: RealFrac a => a -> Bool
isInteger :: forall a. RealFrac a => a -> Bool
isInteger a
x = forall a. Num a => Integer -> a
fromInteger (forall a b. (RealFrac a, Integral b) => a -> b
round a
x) forall a. Eq a => a -> a -> Bool
== a
x
fracPart :: RealFrac a => a -> a
fracPart :: forall a. RealFrac a => a -> a
fracPart a
x = a
x forall a. Num a => a -> a -> a
- forall a. Num a => Integer -> a
fromInteger (forall a b. (RealFrac a, Integral b) => a -> b
floor a
x)
showRational :: Bool -> Rational -> String
showRational :: Bool -> Rational -> String
showRational Bool
asRatio Rational
v
| forall a. Ratio a -> a
denominator Rational
v forall a. Eq a => a -> a -> Bool
== Integer
1 = forall a. Show a => a -> String
show (forall a. Ratio a -> a
numerator Rational
v)
| Bool
asRatio = forall a. Show a => a -> String
show (forall a. Ratio a -> a
numerator Rational
v) forall a. [a] -> [a] -> [a]
++ String
"/" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (forall a. Ratio a -> a
denominator Rational
v)
| Bool
otherwise = forall a. Show a => a -> String
show (forall a. Fractional a => Rational -> a
fromRational Rational
v :: Double)
showRationalAsFiniteDecimal :: Rational -> Maybe String
showRationalAsFiniteDecimal :: Rational -> Maybe String
showRationalAsFiniteDecimal Rational
x = do
let a :: Integer
(Integer
a,Rational
b) = forall a b. (RealFrac a, Integral b) => a -> (b, a)
properFraction (forall a. Num a => a -> a
abs Rational
x)
s1 :: String
s1 = if Rational
x forall a. Ord a => a -> a -> Bool
< Rational
0 then String
"-" else String
""
s2 :: String
s2 = forall a. Show a => a -> String
show Integer
a
String
s3 <- if Rational
b forall a. Eq a => a -> a -> Bool
== Rational
0
then forall (m :: * -> *) a. Monad m => a -> m a
return String
".0"
else forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (String
"." forall a. [a] -> [a] -> [a]
++ ) forall a b. (a -> b) -> a -> b
$ Set Rational -> Rational -> Maybe String
loop forall a. Set a
Set.empty Rational
b
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String
s1 forall a. [a] -> [a] -> [a]
++ String
s2 forall a. [a] -> [a] -> [a]
++ String
s3
where
loop :: Set Rational -> Rational -> Maybe String
loop :: Set Rational -> Rational -> Maybe String
loop Set Rational
_ Rational
0 = forall (m :: * -> *) a. Monad m => a -> m a
return String
""
loop Set Rational
rs Rational
r
| Rational
r forall a. Ord a => a -> Set a -> Bool
`Set.member` Set Rational
rs = forall (m :: * -> *) a. MonadPlus m => m a
mzero
| Bool
otherwise = do
let a :: Integer
(Integer
a,Rational
b) = forall a b. (RealFrac a, Integral b) => a -> (b, a)
properFraction (Rational
r forall a. Num a => a -> a -> a
* Rational
10)
String
s <- Set Rational -> Rational -> Maybe String
loop (forall a. Ord a => a -> Set a -> Set a
Set.insert Rational
r Set Rational
rs) Rational
b
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Integer
a forall a. [a] -> [a] -> [a]
++ String
s
{-# INLINE revSequence #-}
revSequence :: Monad m => [m a] -> m [a]
revSequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a]
revSequence = forall {m :: * -> *} {a}. Monad m => [a] -> [m a] -> m [a]
go []
where
go :: [a] -> [m a] -> m [a]
go [a]
xs [] = forall (m :: * -> *) a. Monad m => a -> m a
return [a]
xs
go [a]
xs (m a
m:[m a]
ms) = do
a
x <- m a
m
[a] -> [m a] -> m [a]
go (a
xforall a. a -> [a] -> [a]
:[a]
xs) [m a]
ms
{-# INLINE revMapM #-}
revMapM :: Monad m => (a -> m b) -> ([a] -> m [b])
revMapM :: forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
revMapM a -> m b
f = forall (m :: * -> *) a. Monad m => [m a] -> m [a]
revSequence forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map a -> m b
f
{-# INLINE revForM #-}
revForM :: Monad m => [a] -> (a -> m b) -> m [b]
revForM :: forall (m :: * -> *) a b. Monad m => [a] -> (a -> m b) -> m [b]
revForM = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
revMapM
setEncodingChar8 :: IO ()
setEncodingChar8 :: IO ()
setEncodingChar8 = do
TextEncoding -> IO ()
setLocaleEncoding TextEncoding
char8
TextEncoding -> IO ()
setForeignEncoding TextEncoding
char8
TextEncoding -> IO ()
setFileSystemEncoding TextEncoding
char8