{-# LANGUAGE MultiParamTypeClasses
           , TypeSynonymInstances
           , FlexibleInstances
  #-}


module Data.ByteString.Nums.Careless.Float where


import Prelude hiding (break, length, null, drop, tail, head)
import Data.ByteString hiding (head, break, pack)
import Data.ByteString.Char8 hiding (inits, elem, last, foldl')
import qualified Data.ByteString.Lazy.Internal as Lazy
import qualified Data.ByteString.Lazy.Char8 as Lazy


import Data.ByteString.Nums.Careless.Int





{-| Types that can be read from floating point strings. A floating point
    string is taken to be a string of digits with up to one comma or period
    mixed in with the digits.
 -}
class (Intable b f, Fractional f) => Floatable b f where
  float                     ::  b -> f

instance Floatable ByteString Float where
  float :: ByteString -> Float
float                      =  forall f. Fractional f => ByteString -> f
strict_float
instance Floatable ByteString Double where
  float :: ByteString -> Double
float                      =  forall f. Fractional f => ByteString -> f
strict_float
instance Floatable ByteString Rational where
  float :: ByteString -> Rational
float                      =  forall f. Fractional f => ByteString -> f
strict_float

instance Floatable Lazy.ByteString Float where
  float :: ByteString -> Float
float                      =  forall f. Fractional f => ByteString -> f
lazy_float
instance Floatable Lazy.ByteString Double where
  float :: ByteString -> Double
float                      =  forall f. Fractional f => ByteString -> f
lazy_float
instance Floatable Lazy.ByteString Rational where
  float :: ByteString -> Rational
float                      =  forall f. Fractional f => ByteString -> f
lazy_float




strict_float                ::  (Fractional f) => ByteString -> f
strict_float :: forall f. Fractional f => ByteString -> f
strict_float ByteString
bytes
  | ByteString -> Bool
null ByteString
bytes               =  f
0
  | ByteString -> Char
head ByteString
bytes forall a. Eq a => a -> a -> Bool
== Char
'-'        =  f -> ByteString -> f
foldn f
0 (HasCallStack => ByteString -> ByteString
tail ByteString
integer) forall a. Num a => a -> a -> a
+ f
nfrac
  | ByteString -> Char
head ByteString
bytes forall a. Eq a => a -> a -> Bool
== Char
'+'        =  f -> ByteString -> f
foldp f
0 (HasCallStack => ByteString -> ByteString
tail ByteString
integer) forall a. Num a => a -> a -> a
+ f
pfrac
  | Bool
otherwise                =  f -> ByteString -> f
foldp f
0 ByteString
integer forall a. Num a => a -> a -> a
+ f
pfrac
 where
  foldn :: f -> ByteString -> f
foldn                      =  forall a. (a -> Word8 -> a) -> a -> ByteString -> a
foldl' forall n. Num n => n -> Word8 -> n
negative
  foldp :: f -> ByteString -> f
foldp                      =  forall a. (a -> Word8 -> a) -> a -> ByteString -> a
foldl' forall n. Num n => n -> Word8 -> n
positive
  (ByteString
integer, ByteString
fractional)      =  (Char -> Bool) -> ByteString -> (ByteString, ByteString)
break Char -> Bool
point ByteString
bytes
  fractional' :: ByteString
fractional'                =  HasCallStack => ByteString -> ByteString
tail ByteString
fractional
  p :: f
p                          =  f
0.1 forall a b. (Num a, Integral b) => a -> b -> a
^ ByteString -> Int
length ByteString
fractional'
  nfrac :: f
nfrac
    | ByteString -> Bool
null ByteString
fractional        =  f
0
    | Bool
otherwise              =  f -> ByteString -> f
foldn f
0 ByteString
fractional' forall a. Num a => a -> a -> a
* f
p
  pfrac :: f
pfrac
    | ByteString -> Bool
null ByteString
fractional        =  f
0
    | Bool
otherwise              =  f -> ByteString -> f
foldp f
0 ByteString
fractional' forall a. Num a => a -> a -> a
* f
p


lazy_float                  ::  (Fractional f) => Lazy.ByteString -> f
lazy_float :: forall f. Fractional f => ByteString -> f
lazy_float ByteString
bytes
  | ByteString -> Bool
Lazy.null ByteString
bytes          =  f
0
  | ByteString -> Char
Lazy.head ByteString
bytes forall a. Eq a => a -> a -> Bool
== Char
'-'   =  f -> ByteString -> f
foldn f
0 (HasCallStack => ByteString -> ByteString
Lazy.tail ByteString
integer) forall a. Num a => a -> a -> a
+ f
nfrac
  | ByteString -> Char
Lazy.head ByteString
bytes forall a. Eq a => a -> a -> Bool
== Char
'+'   =  f -> ByteString -> f
foldp f
0 (HasCallStack => ByteString -> ByteString
Lazy.tail ByteString
integer) forall a. Num a => a -> a -> a
+ f
pfrac
  | Bool
otherwise                =  f -> ByteString -> f
foldp f
0 ByteString
integer forall a. Num a => a -> a -> a
+ f
pfrac
 where
  foldn :: f -> ByteString -> f
foldn                      =  forall a. (a -> ByteString -> a) -> a -> ByteString -> a
Lazy.foldlChunks (forall a. (a -> Word8 -> a) -> a -> ByteString -> a
foldl' forall n. Num n => n -> Word8 -> n
negative)
  foldp :: f -> ByteString -> f
foldp                      =  forall a. (a -> ByteString -> a) -> a -> ByteString -> a
Lazy.foldlChunks (forall a. (a -> Word8 -> a) -> a -> ByteString -> a
foldl' forall n. Num n => n -> Word8 -> n
positive)
  (ByteString
integer, ByteString
fractional)      =  (Char -> Bool) -> ByteString -> (ByteString, ByteString)
Lazy.break Char -> Bool
point ByteString
bytes
  fractional' :: ByteString
fractional'                =  HasCallStack => ByteString -> ByteString
Lazy.tail ByteString
fractional
  p :: f
p                          =  f
0.1 forall a b. (Num a, Integral b) => a -> b -> a
^ ByteString -> Int64
Lazy.length ByteString
fractional'
  nfrac :: f
nfrac
    | ByteString -> Bool
Lazy.null ByteString
fractional   =  f
0
    | Bool
otherwise              =  f -> ByteString -> f
foldn f
0 ByteString
fractional' forall a. Num a => a -> a -> a
* f
p
  pfrac :: f
pfrac
    | ByteString -> Bool
Lazy.null ByteString
fractional   =  f
0
    | Bool
otherwise              =  f -> ByteString -> f
foldp f
0 ByteString
fractional' forall a. Num a => a -> a -> a
* f
p


point                       ::  Char -> Bool
point :: Char -> Bool
point Char
c                      =  Char
c forall a. Eq a => a -> a -> Bool
== Char
'.' Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
','