module Music.Theory.Read where
import Data.Char
import Data.List
import Data.Maybe
import Data.Ratio
import Numeric
reads_to_read_precise :: ReadS t -> (String -> Maybe t)
reads_to_read_precise f s =
case f s of
[(r,[])] -> Just r
[(r,[c])] -> if isSpace c then Just r else Nothing
_ -> Nothing
reads_to_read_precise_err :: String -> ReadS t -> String -> t
reads_to_read_precise_err err f =
fromMaybe (error ("reads_to_read_precise_err:" ++ err)) .
reads_to_read_precise f
read_maybe :: Read a => String -> Maybe a
read_maybe = reads_to_read_precise reads
read_def :: Read a => a -> String -> a
read_def x s = maybe x id (read_maybe s)
read_err :: Read a => String -> a
read_err s = maybe (error ("read_err: " ++ s)) id (read_maybe s)
reads_exact :: Read a => String -> Maybe a
reads_exact s =
case reads s of
[(r,"")] -> Just r
_ -> Nothing
reads_exact_err :: Read a => String -> String -> a
reads_exact_err err_txt str =
let err = error ("reads: " ++ err_txt ++ ": " ++ str)
in fromMaybe err (reads_exact str)
read_integral_allow_commas_maybe :: Read i => String -> Maybe i
read_integral_allow_commas_maybe s =
let c = filter ((== ',') . fst) (zip (reverse s) [0..])
in if null c
then read_maybe s
else if map snd c `isPrefixOf` [3::Int,7..]
then read_maybe (filter (not . (== ',')) s)
else Nothing
read_integral_allow_commas_err :: (Integral i,Read i) => String -> i
read_integral_allow_commas_err s =
let err = error ("read_integral_allow_commas: misplaced commas: " ++ s)
in fromMaybe err (read_integral_allow_commas_maybe s)
read_int_allow_commas :: String -> Int
read_int_allow_commas = read_integral_allow_commas_err
read_ratio_with_div_err :: (Integral i, Read i) => String -> Ratio i
read_ratio_with_div_err s =
let f = read_integral_allow_commas_err
in case break (== '/') s of
(n,'/':d) -> f n % f d
_ -> read_integral_allow_commas_err s % 1
read_ratio_allow_commas_err :: (Integral i,Read i) => String -> String -> Ratio i
read_ratio_allow_commas_err n d = let f = read_integral_allow_commas_err in f n % f d
delete_trailing_point :: String -> String
delete_trailing_point s =
case reverse s of
'.':s' -> reverse s'
_ -> s
read_fractional_allow_trailing_point_err :: Read n => String -> n
read_fractional_allow_trailing_point_err = read_err . delete_trailing_point
read_maybe_int :: String -> Maybe Int
read_maybe_int = read_maybe
read_int :: String -> Int
read_int = read_err
read_maybe_double :: String -> Maybe Double
read_maybe_double = read_maybe
read_double :: String -> Double
read_double = read_err
read_maybe_rational :: String -> Maybe Rational
read_maybe_rational = read_maybe
read_rational :: String -> Rational
read_rational = read_err
read_hex_err :: (Eq n,Num n) => String -> n
read_hex_err = reads_to_read_precise_err "readHex" readHex