<commit_before>--{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype State s a = State { runState :: s -> (a,s) };

instance Functor (State s) where
  fmap f (State s) = State (\s' -> let (x,s'') = s s'
                                   in (f x, s''))

instance Applicative (State s) where
  pure x = State $ \s -> (x,s)
  (State mf) <*> (State mx) = State (\s -> let (f,s')  = mf s
                                               (x,s'') = mx s'
                                           in (f x, s''))

instance Monad (State s) where
  return x = State $ \s -> (x,s)
  (State mx) >>= f = State (\s -> let (x, s') = mx s
                                  in runState (f x) s')

get :: State s s 
get = State $ \s -> (s,s)

put :: s -> State s ()
put s = State $ \_ -> ((),s)

modify :: (s -> s) -> State s ()
modify f = do { x <- get; put (f x); }

gets :: (s -> a) -> State s a
gets f = get >>= \x -> return (f x);
-- gets f = do { x<-get; return (f x); }

{-
     get >>= \x -> return (f x)

 ==  State (\s -> (s,s)) >>= (\x -> return (f x))
 
==  State (\s -> (s,s)) >>= (\x -> State (\s -> (f x, s)))

 ==  (>>=) State (\s -> (s,s)) (\x -> (State (\s -> (f x,s))) )

 ==  State (\s -> let (x,s') = (\s -> (s,s)) s
                  in runState (\x -> (State (\s -> (f x,s)))) x  s')

 == State (\s -> let (x,s') = (s,s)  
                 in runState (State \s -> (f x, s)) s')

 == State (\s -> let (x,s') = (s,s)
                 in (\s -> (f x, s)) s')

 == State (\s -> let (x,s') = (s,s)
                 in (f x, s'))

 == State (\s -> (f s , s))

 -}

evalState :: State s a -> s -> a
evalState act = fst . runState act

execState :: State s a -> s -> s
execState act = snd . runState act

data State' s a = State' (s->a) ( s->s)
runState' (State' f tr) s = (f s, tr s)

instance Functor (State' s) where
  fmap f (State' g tr) = State' (f.g) tr

instance Applicative (State' s) where
  pure x = State' (const x) id
  State' fg tr1 <*> State' fx tr2 = State' ff (tr1 . tr2)
    where
      ff st = let g = fg st
                  x = fx (tr1 st)
              in g x

instance Monad (State' s) where
  return x = State' (const x) id
  State' fx tr >>= k = State' ff ttr
    where
      ff st  = let x   = fx st
                   st' = tr st
                   State' fy tr' = k x
               in fy st'
      ttr st = let x   = fx st
                   st' = tr st
                   State' fy tr' = k x
               in tr' st'

join :: State' s (State' s a) -> State' s a
join (State' ff ttr) = State' f' tr'
  where
    f' st  = let State' f tr = ff st
                 st'         = ttr st
             in f st'
    tr' st = let State' f tr = ff st
                 st'         = ttr st
             in tr st'

     
  

returnState :: a -> State s a
returnState a = State $ \s -> (a,s)

bindState :: State s a -> (a -> State s b) -> State s b
bindState m k = State $ \s -> let (a, s') = runState m s
                              in runState (k a) s'

----------
--
type Seed = Int
drand48val :: Seed -> Double
drand48val s = realToFrac(s `mod` 281474976710656)*(1.0/281474976710656.0);

nextSeed :: Seed -> Seed
nextSeed s = s * 0x5DEECE66D + 0xB;

type DRand48 = State Seed Double

getNextRand48 :: DRand48
getNextRand48 = State (\s -> (drand48val(s), nextSeed(s)))


rand48 :: Int -> DRand48
rand48 count | count == 1 = do { getNextRand48; } 
             |otherwise  = do { getNextRand48; rand48 (count-1); }
  
 
getRand :: Seed -> Int -> Double
getRand  seed count = evalState (rand48 count) seed


{-
 
  struct Rand48
  {
    double drand()
    {
      update();
      return (stat&0xFFFFFFFFFFFF)*(1.0/281474976710656.0);
    }
    long lrand()
    {
      update();<commit_msg>don't use do notation. easier<commit_after>--{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype State s a = State { runState :: s -> (a,s) };

instance Functor (State s) where
  fmap f (State s) = State (\s' -> let (x,s'') = s s'
                                   in (f x, s''))

instance Applicative (State s) where
  pure x = State $ \s -> (x,s)
  (State mf) <*> (State mx) = State (\s -> let (f,s')  = mf s
                                               (x,s'') = mx s'
                                           in (f x, s''))

instance Monad (State s) where
  return x = State $ \s -> (x,s)
  (State mx) >>= f = State (\s -> let (x, s') = mx s
                                  in runState (f x) s')

get :: State s s 
get = State $ \s -> (s,s)

put :: s -> State s ()
put s = State $ \_ -> ((),s)

modify :: (s -> s) -> State s ()
modify f = do { x <- get; put (f x); }

gets :: (s -> a) -> State s a
gets f = get >>= \x -> return (f x);
-- gets f = do { x<-get; return (f x); }

{-
     get >>= \x -> return (f x)

 ==  State (\s -> (s,s)) >>= (\x -> return (f x))
 
==  State (\s -> (s,s)) >>= (\x -> State (\s -> (f x, s)))

 ==  (>>=) State (\s -> (s,s)) (\x -> (State (\s -> (f x,s))) )

 ==  State (\s -> let (x,s') = (\s -> (s,s)) s
                  in runState (\x -> (State (\s -> (f x,s)))) x  s')

 == State (\s -> let (x,s') = (s,s)  
                 in runState (State \s -> (f x, s)) s')

 == State (\s -> let (x,s') = (s,s)
                 in (\s -> (f x, s)) s')

 == State (\s -> let (x,s') = (s,s)
                 in (f x, s'))

 == State (\s -> (f s , s))

 -}

evalState :: State s a -> s -> a
evalState act = fst . runState act

execState :: State s a -> s -> s
execState act = snd . runState act

data State' s a = State' (s->a) ( s->s)
runState' (State' f tr) s = (f s, tr s)

instance Functor (State' s) where
  fmap f (State' g tr) = State' (f.g) tr

instance Applicative (State' s) where
  pure x = State' (const x) id
  State' fg tr1 <*> State' fx tr2 = State' ff (tr1 . tr2)
    where
      ff st = let g = fg st
                  x = fx (tr1 st)
              in g x

instance Monad (State' s) where
  return x = State' (const x) id
  State' fx tr >>= k = State' ff ttr
    where
      ff st  = let x   = fx st
                   st' = tr st
                   State' fy tr' = k x
               in fy st'
      ttr st = let x   = fx st
                   st' = tr st
                   State' fy tr' = k x
               in tr' st'

join :: State' s (State' s a) -> State' s a
join (State' ff ttr) = State' f' tr'
  where
    f' st  = let State' f tr = ff st
                 st'         = ttr st
             in f st'
    tr' st = let State' f tr = ff st
                 st'         = ttr st
             in tr st'

     
  

returnState :: a -> State s a
returnState a = State $ \s -> (a,s)

bindState :: State s a -> (a -> State s b) -> State s b
bindState m k = State $ \s -> let (a, s') = runState m s
                              in runState (k a) s'

---------- drand48 ()

type Seed = Int
drand48val :: Seed -> Double
drand48val s = realToFrac(s `mod` 281474976710656)*(1.0/281474976710656.0);

nextSeed :: Seed -> Seed
nextSeed s = s * 0x5DEECE66D + 0xB;

type DRand48 = State Seed Double

getNextRand48 :: DRand48
getNextRand48 = State (\s -> (drand48val(s), nextSeed(s)))

rand48 :: Int -> DRand48
rand48 count | count == 1 = getNextRand48
             | otherwise =  getNextRand48 >> rand48 (count-1)
  
 
getRand :: Seed -> Int -> Double
getRand  seed count = evalState (rand48 count) seed


{-
 
  struct Rand48
  {
    double drand()
    {
      update();
      return (stat&0xFFFFFFFFFFFF)*(1.0/281474976710656.0);
    }
    long lrand()
    {
      update();
{'fraction_non_alphanumeric': 0.17725437415881562, 'fraction_numerical': 0.02557200538358008, 'mean_word_length': 1.5396445659603555, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 141, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2233325', 'n_tokens_mistral': 2914, 'n_tokens_neox': 2724, 'n_words': 1004}