{-# LANGUAGE CPP                  #-}
{-# LANGUAGE FlexibleInstances    #-}
{-# LANGUAGE PackageImports       #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# OPTIONS -fno-warn-missing-methods #-}

module Prelude
  (
  -- Prelude type re-exports
   Base.Char
  ,Base.String
  ,Base.Double
  ,Base.Int
  ,Base.Integer
  ,Base.Bool(..)
  ,Base.Read
  ,Base.Show
  ,Base.Eq
  ,(==)
  ,(/=)
  -- Standard data types
  ,Maybe(..)
  ,maybe
  -- Monads
  ,(>>=)
  ,(>>)
  ,return
  ,fail
  ,when
  ,unless
  ,forM
  ,forM_
  ,mapM
  ,mapM_
  ,(=<<)
  ,sequence
  ,sequence_
  ,void
  ,(>=>)
  ,(<=<)
  -- Num
  ,(*)
  ,(+)
  ,(-)
  -- Ord
  ,Ord
  ,Ordering(..)
  -- An ordering.
  ,(<)
  ,(<=)
  ,(>)
  ,(>=)
  ,compare
  -- Enum
  ,succ
  ,pred
  ,enumFrom
  ,enumFromTo
  ,enumFromBy
  ,enumFromThen
  ,enumFromByTo
  ,enumFromThenTo
  -- Fractional
  ,(/)
  -- Integral
  ,fromIntegral
  ,fromInteger
  -- Bools
  ,(&&)
  ,(||)
  ,not
  ,otherwise
  -- Show
  ,show
  -- Errors
  ,error
  ,undefined
  ,Either(..)
  ,either
  -- Functions
  ,until
  ,($!)
  ,seq
  ,const
  ,id
  ,(.)
  ,($)
  ,flip
  ,curry
  ,uncurry
  ,snd
  ,fst
  -- Numbers
  ,div
  ,mod
  ,divMod
  ,min
  ,max
  ,recip
  ,negate
  ,abs
  ,signum
  ,pi
  ,exp
  ,sqrt
  ,log
  ,(**)
  ,(^^)
  ,unsafePow
  ,(^)
  ,logBase
  ,sin
  ,tan
  ,cos
  ,asin
  ,atan
  ,acos
  ,sinh
  ,tanh
  ,cosh
  ,asinh
  ,atanh
  ,acosh
  ,properFraction
  ,truncate
  ,round
  ,ceiling
  ,floor
  ,subtract
  ,even
  ,odd
  ,gcd
  ,quot
  ,quot'
  ,quotRem
  ,rem
  ,rem'
  ,lcm
  -- Lists
  ,find
  ,filter
  ,null
  ,map
  ,nub
  ,nub'
  ,elem
  ,notElem
  ,sort
  ,sortBy
  ,insertBy
  ,conc
  ,concat
  ,concatMap
  ,foldr
  ,foldr1
  ,foldl
  ,foldl1
  ,(++)
  ,(!!)
  ,head
  ,tail
  ,init
  ,last
  ,iterate
  ,repeat
  ,replicate
  ,cycle
  ,take
  ,drop
  ,splitAt
  ,takeWhile
  ,dropWhile
  ,span
  ,break
  ,zipWith
  ,zipWith3
  ,zip
  ,zip3
  ,unzip
  ,unzip3
  ,lines
  ,unlines
  ,words
  ,unwords
  ,and
  ,or
  ,any
  ,all
  ,intersperse
  ,prependToAll
  ,intercalate
  ,maximum
  ,minimum
  ,product
  ,sum
  ,scanl
  ,scanl1
  ,scanr
  ,scanr1
  ,lookup
  ,length
  ,length'
  ,reverse
  -- IO
  ,print
  ,putStrLn
  ,ifThenElse
  ,Fay
  )
  where

#ifdef FAY
import           Data.Data
#endif
import           Fay.FFI
import           "base" Prelude   (Bool (True, False), Eq, seq, (&&), (/=),
                                   (==), (||))
import qualified "base" Prelude   as Base
#ifndef FAY
import           "base" Prelude   (Either (..), Maybe (..), Ordering (..))
#endif

--------------------------------------------------------------------------------
-- Fixities

infixr 9  .
infixr 8  ^, ^^, **
infixl 7  *, /, `quot`, `rem`, `div`, `mod`
infixl 6  +, -

-- The (:) operator is built-in syntax, and cannot legally be given
-- a fixity declaration; but its fixity is given by:
--   infixr 5  :

-- Provided by base prelude
--   infix  4  ==, /=
--   infixr 3  &&
--   infixr 2  ||
--   infixr 0  $, $!

infixr 4  <, <=, >=, >
infixl 1  >>, >>=
infixr 1  =<<, >=>, <=<
infixr 0  $, $!

-- PreludeList

infixl 9  !!
infixr 5  ++
infix  4  `elem`, `notElem`

--------------------------------------------------------------------------------
-- Aliases of base

type Char    = Base.Char
type Double  = Base.Double
type Int     = Base.Int
type Integer = Base.Integer
type String  = Base.String

--------------------------------------------------------------------------------
-- Standard data types

-- | Maybe type.
#ifdef FAY
data Maybe a = Just a | Nothing
instance Base.Read a => Base.Read (Maybe a)
instance Base.Show a => Base.Show (Maybe a)
instance Typeable a => Typeable (Maybe a)
instance Data a => Data (Maybe a)
#endif

-- | Either type.
#ifdef FAY
data Either a b = Left a | Right b
#endif

maybe :: t -> (t1 -> t) -> Maybe t1 -> t
maybe :: t -> (t1 -> t) -> Maybe t1 -> t
maybe t
m t1 -> t
_ Maybe t1
Nothing = t
m
maybe t
_ t1 -> t
f (Just t1
x) = t1 -> t
f t1
x

--------------------------------------------------------------------------------
-- Monads

-- | Monomorphic bind for Fay.
(>>=) :: Ptr (Fay a) -> Ptr (a -> Fay b) -> Ptr (Fay b)
>>= :: Ptr (Fay a) -> Ptr (a -> Fay b) -> Fay b
(>>=) = [Char] -> Ptr (Fay a) -> Ptr (a -> Fay b) -> Fay b
forall s a. IsString s => s -> a
ffi [Char]
"Fay$$_(Fay$$bind(%1)(%2))"

-- | Monomorphic then for Fay.
(>>) :: Ptr (Fay a) -> Ptr (Fay b) -> Ptr (Fay b)
>> :: Ptr (Fay a) -> Ptr (Fay b) -> Ptr (Fay b)
(>>) = [Char] -> Ptr (Fay a) -> Ptr (Fay b) -> Ptr (Fay b)
forall s a. IsString s => s -> a
ffi [Char]
"Fay$$_(Fay$$then(%1)(%2))"

-- | Monomorphic return for Fay.
return :: a -> Fay a
return :: a -> Fay a
return = [Char] -> a -> Fay a
forall s a. IsString s => s -> a
ffi [Char]
"Fay$$$_return(%1)"

fail :: String -> Fay a
fail :: [Char] -> Fay a
fail = [Char] -> Fay a
forall a. [Char] -> a
error

when :: Bool -> Fay () -> Fay ()
when :: Bool -> Fay () -> Fay ()
when Bool
p Fay ()
m = if Bool
p then Fay ()
m else () -> Fay ()
forall a. a -> Fay a
return ()

unless :: Bool -> Fay () -> Fay ()
unless :: Bool -> Fay () -> Fay ()
unless Bool
p Fay ()
m = if Bool
p then () -> Fay ()
forall a. a -> Fay a
return () else Fay ()
m

forM :: [a] -> (a -> Fay b) -> Fay [b]
forM :: [a] -> (a -> Fay b) -> Fay [b]
forM [a]
lst a -> Fay b
fn = [Fay b] -> Fay [b]
forall a. [Fay a] -> Fay [a]
sequence ([Fay b] -> Fay [b]) -> [Fay b] -> Fay [b]
forall t1 t. (t1 -> t) -> t1 -> t
$ (a -> Fay b) -> [a] -> [Fay b]
forall a b. (a -> b) -> [a] -> [b]
map a -> Fay b
fn [a]
lst

forM_ :: [a] -> (a -> Fay b) -> Fay ()
forM_ :: [a] -> (a -> Fay b) -> Fay ()
forM_ (a
x:[a]
xs) a -> Fay b
m = a -> Fay b
m a
x Fay b -> Fay () -> Fay ()
forall a b. Ptr (Fay a) -> Ptr (Fay b) -> Ptr (Fay b)
>> [a] -> (a -> Fay b) -> Fay ()
forall a b. [a] -> (a -> Fay b) -> Fay ()
forM_ [a]
xs a -> Fay b
m
forM_ []     a -> Fay b
_ = () -> Fay ()
forall a. a -> Fay a
return ()

mapM :: (a -> Fay b) -> [a] -> Fay [b]
mapM :: (a -> Fay b) -> [a] -> Fay [b]
mapM a -> Fay b
fn [a]
lst = [Fay b] -> Fay [b]
forall a. [Fay a] -> Fay [a]
sequence ([Fay b] -> Fay [b]) -> [Fay b] -> Fay [b]
forall t1 t. (t1 -> t) -> t1 -> t
$ (a -> Fay b) -> [a] -> [Fay b]
forall a b. (a -> b) -> [a] -> [b]
map a -> Fay b
fn [a]
lst

mapM_ :: (a -> Fay b) -> [a] -> Fay ()
mapM_ :: (a -> Fay b) -> [a] -> Fay ()
mapM_ a -> Fay b
m (a
x:[a]
xs) = a -> Fay b
m a
x Fay b -> Fay () -> Fay ()
forall a b. Ptr (Fay a) -> Ptr (Fay b) -> Ptr (Fay b)
>> (a -> Fay b) -> [a] -> Fay ()
forall a b. (a -> Fay b) -> [a] -> Fay ()
mapM_ a -> Fay b
m [a]
xs
mapM_ a -> Fay b
_ []     = () -> Fay ()
forall a. a -> Fay a
return ()

(=<<) :: (a -> Fay b) -> Fay a -> Fay b
a -> Fay b
f =<< :: (a -> Fay b) -> Fay a -> Fay b
=<< Fay a
x = Fay a
x Fay a -> (a -> Fay b) -> Fay b
forall a b. Ptr (Fay a) -> Ptr (a -> Fay b) -> Fay b
>>= a -> Fay b
f

void :: Fay a -> Fay ()
void :: Fay a -> Fay ()
void Fay a
f = Fay a
f Fay a -> Fay () -> Fay ()
forall a b. Ptr (Fay a) -> Ptr (Fay b) -> Ptr (Fay b)
>> () -> Fay ()
forall a. a -> Fay a
return ()

(>=>) :: (a -> Fay b) -> (b -> Fay c) -> a -> Fay c
>=> :: (a -> Fay b) -> (b -> Fay c) -> a -> Fay c
(>=>) a -> Fay b
f b -> Fay c
g a
x = a -> Fay b
f a
x Fay b -> (b -> Fay c) -> Fay c
forall a b. Ptr (Fay a) -> Ptr (a -> Fay b) -> Fay b
>>= b -> Fay c
g

(<=<) :: (b -> Fay c) -> (a -> Fay b) -> a -> Fay c
<=< :: (b -> Fay c) -> (a -> Fay b) -> a -> Fay c
(<=<) b -> Fay c
g a -> Fay b
f a
x = a -> Fay b
f a
x Fay b -> (b -> Fay c) -> Fay c
forall a b. Ptr (Fay a) -> Ptr (a -> Fay b) -> Fay b
>>= b -> Fay c
g

-- | Evaluate each action in the sequence from left to right,
-- and collect the results.
sequence :: [Fay a] -> Fay [a]
sequence :: [Fay a] -> Fay [a]
sequence [Fay a]
ms = (Fay a -> Fay [a] -> Fay [a]) -> Fay [a] -> [Fay a] -> Fay [a]
forall t t1. (t -> t1 -> t1) -> t1 -> [t] -> t1
foldr Fay a -> Fay [a] -> Fay [a]
forall a. Fay a -> Fay [a] -> Fay [a]
k ([a] -> Fay [a]
forall a. a -> Fay a
return []) [Fay a]
ms
            where
              k :: Fay a -> Fay [a] -> Fay [a]
k Fay a
m Fay [a]
m' = do { a
x <- Fay a
m; [a]
xs <- Fay [a]
m'; [a] -> Fay [a]
forall a. a -> Fay a
return (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
xs) }

sequence_ :: [Fay a] -> Fay ()
sequence_ :: [Fay a] -> Fay ()
sequence_ []     = () -> Fay ()
forall a. a -> Fay a
return ()
sequence_ (Fay a
m:[Fay a]
ms) = Fay a
m Fay a -> Fay () -> Fay ()
forall a b. Ptr (Fay a) -> Ptr (Fay b) -> Ptr (Fay b)
>> [Fay a] -> Fay ()
forall a. [Fay a] -> Fay ()
sequence_ [Fay a]
ms

--------------------------------------------------------------------------------
-- Num

class Base.Num a => Num a where
  (*) :: a -> a -> a
  (+) :: a -> a -> a
  (-) :: a -> a -> a

instance Num Int
instance Num Double

--------------------------------------------------------------------------------
-- Ord

-- An ordering.
#ifdef FAY
data Ordering = GT | LT | EQ
#endif

class (Eq a) => Ord a where
  (<)  :: a -> a -> Bool
  (<=) :: a -> a -> Bool
  (>)  :: a -> a -> Bool
  (>=) :: a -> a -> Bool

instance Ord Char
instance Ord Double
instance Ord Int
instance Ord Integer

compare :: Ord a => a -> a -> Ordering
compare :: a -> a -> Ordering
compare a
x a
y =
  if a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
y
     then Ordering
GT
     else if a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
y
             then Ordering
LT
             else Ordering
EQ

--------------------------------------------------------------------------------
-- Enum

class (Base.Enum a) => Enum a where

instance Enum Int
-- Integers are represented as JS numbers which aren't arbitrary precision
-- se we shouldn't add an Enum instance.

succ :: Num a => a -> a
succ :: a -> a
succ a
x = a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a
1

pred :: Num a => a -> a
pred :: a -> a
pred a
x = a
x a -> a -> a
forall a. Num a => a -> a -> a
- a
1

enumFrom :: Num a => a -> [a]
enumFrom :: a -> [a]
enumFrom a
i = a
i a -> [a] -> [a]
forall a. a -> [a] -> [a]
: a -> [a]
forall a. Num a => a -> [a]
enumFrom (a
i a -> a -> a
forall a. Num a => a -> a -> a
+ a
1)

enumFromTo :: (Ord t, Num t) => t -> t -> [t]
enumFromTo :: t -> t -> [t]
enumFromTo t
i t
n =
  if t
i t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
n then [] else t
i t -> [t] -> [t]
forall a. a -> [a] -> [a]
: t -> t -> [t]
forall t. (Ord t, Num t) => t -> t -> [t]
enumFromTo (t
i t -> t -> t
forall a. Num a => a -> a -> a
+ t
1) t
n

enumFromBy :: (Num t) => t -> t -> [t]
enumFromBy :: t -> t -> [t]
enumFromBy t
fr t
by = t
fr t -> [t] -> [t]
forall a. a -> [a] -> [a]
: t -> t -> [t]
forall t. Num t => t -> t -> [t]
enumFromBy (t
fr t -> t -> t
forall a. Num a => a -> a -> a
+ t
by) t
by

enumFromThen :: (Num t) => t -> t -> [t]
enumFromThen :: t -> t -> [t]
enumFromThen t
fr t
th = t -> t -> [t]
forall t. Num t => t -> t -> [t]
enumFromBy t
fr (t
th t -> t -> t
forall a. Num a => a -> a -> a
- t
fr)

enumFromByTo :: (Ord t, Num t) => t -> t -> t -> [t]
enumFromByTo :: t -> t -> t -> [t]
enumFromByTo t
fr t
by t
to = if t
by t -> t -> Bool
forall a. Ord a => a -> a -> Bool
< t
0 then t -> [t]
neg t
fr else t -> [t]
pos t
fr
  where neg :: t -> [t]
neg t
x = if t
x t -> t -> Bool
forall a. Ord a => a -> a -> Bool
< t
to then [] else t
x t -> [t] -> [t]
forall a. a -> [a] -> [a]
: t -> [t]
neg (t
x t -> t -> t
forall a. Num a => a -> a -> a
+ t
by)
        pos :: t -> [t]
pos t
x = if t
x t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
to then [] else t
x t -> [t] -> [t]
forall a. a -> [a] -> [a]
: t -> [t]
pos (t
x t -> t -> t
forall a. Num a => a -> a -> a
+ t
by)

enumFromThenTo :: (Ord t, Num t) => t -> t -> t -> [t]
enumFromThenTo :: t -> t -> t -> [t]
enumFromThenTo t
fr t
th t
to = t -> t -> t -> [t]
forall t. (Ord t, Num t) => t -> t -> t -> [t]
enumFromByTo t
fr (t
th t -> t -> t
forall a. Num a => a -> a -> a
- t
fr) t
to

--------------------------------------------------------------------------------
-- Fractional

class (Num a,Base.Fractional a) => Fractional a where
  (/) :: a -> a -> a

instance Fractional Double

--------------------------------------------------------------------------------
-- Integral

class (Enum a,Base.Integral a) => Integral a

instance Integral Int
-- Can't add Integer instance since Integer isn't an Enum (see Enum above).

fromIntegral :: (Num a, Num b) => Ptr a -> Ptr b
fromIntegral :: Ptr a -> Ptr b
fromIntegral = [Char] -> Ptr a -> Ptr b
forall s a. IsString s => s -> a
ffi [Char]
"%1"

fromInteger :: Num a => Ptr Integer -> Ptr a
fromInteger :: Integer -> Ptr a
fromInteger = [Char] -> Integer -> Ptr a
forall s a. IsString s => s -> a
ffi [Char]
"%1"

--------------------------------------------------------------------------------
-- Bools

not :: Bool -> Bool
not :: Bool -> Bool
not Bool
p = if Bool
p then Bool
False else Bool
True

otherwise :: Bool
otherwise :: Bool
otherwise = Bool
True

--------------------------------------------------------------------------------
-- Show

-- | Uses JSON.stringify.
show :: Automatic a -> String
show :: Automatic a -> [Char]
show = [Char] -> Automatic a -> [Char]
forall s a. IsString s => s -> a
ffi [Char]
"JSON.stringify(%1)"

--------------------------------------------------------------------------------
-- Errors

-- | Throws a JavaScript error.
error :: String -> a
error :: [Char] -> a
error = [Char] -> [Char] -> a
forall s a. IsString s => s -> a
ffi [Char]
"(function() { throw %1 })()"

-- | Throws "undefined" via "error".
undefined :: a
undefined :: a
undefined = [Char] -> a
forall a. [Char] -> a
error [Char]
"Prelude.undefined"

either :: (a -> c) -> (b -> c) -> Either a b -> c
either :: (a -> c) -> (b -> c) -> Either a b -> c
either a -> c
f b -> c
_ (Left a
a) = a -> c
f a
a
either a -> c
_ b -> c
g (Right b
b) = b -> c
g b
b

--------------------------------------------------------------------------------
-- Functions

until :: (a -> Bool) -> (a -> a) -> a -> a
until :: (a -> Bool) -> (a -> a) -> a -> a
until a -> Bool
p a -> a
f a
x = if a -> Bool
p a
x then a
x else (a -> Bool) -> (a -> a) -> a -> a
forall a. (a -> Bool) -> (a -> a) -> a -> a
until a -> Bool
p a -> a
f (a -> a
f a
x)

($!) :: (a -> b) -> a -> b
a -> b
f $! :: (a -> b) -> a -> b
$! a
x = a
x a -> b -> b
`seq` a -> b
f a
x

const :: a -> b -> a
const :: a -> b -> a
const a
a b
_ = a
a

id :: a -> a
id :: a -> a
id a
x = a
x

(.) :: (t1 -> t) -> (t2 -> t1) -> t2 -> t
(t1 -> t
f . :: (t1 -> t) -> (t2 -> t1) -> t2 -> t
. t2 -> t1
g) t2
x = t1 -> t
f (t2 -> t1
g t2
x)

($) :: (t1 -> t) -> t1 -> t
t1 -> t
f $ :: (t1 -> t) -> t1 -> t
$ t1
x = t1 -> t
f t1
x

flip :: (t1 -> t2 -> t) -> t2 -> t1 -> t
flip :: (t1 -> t2 -> t) -> t2 -> t1 -> t
flip t1 -> t2 -> t
f t2
x t1
y = t1 -> t2 -> t
f t1
y t2
x

curry :: ((a, b) -> c) -> a -> b -> c
curry :: ((a, b) -> c) -> a -> b -> c
curry (a, b) -> c
f a
x b
y = (a, b) -> c
f (a
x, b
y)

uncurry :: (a -> b -> c) -> (a, b) -> c
uncurry :: (a -> b -> c) -> (a, b) -> c
uncurry a -> b -> c
f (a, b)
p = case (a, b)
p of (a
x, b
y) -> a -> b -> c
f a
x b
y

snd :: (t, t1) -> t1
snd :: (t, t1) -> t1
snd (t
_,t1
x) = t1
x

fst :: (t, t1) -> t
fst :: (t, t1) -> t
fst (t
x,t1
_) = t
x

--------------------------------------------------------------------------------
-- Numbers

div :: Int -> Int -> Int
div :: Int -> Int -> Int
div Int
x Int
y
  | Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Int -> Int -> Int
quot (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
  | Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
&& Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = Int -> Int -> Int
quot (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
div Int
x Int
y            = Int -> Int -> Int
quot Int
x Int
y

mod :: Int -> Int -> Int
mod :: Int -> Int -> Int
mod Int
x Int
y
  | Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Int -> Int -> Int
rem (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
  | Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
&& Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = Int -> Int -> Int
rem (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
mod Int
x Int
y            = Int -> Int -> Int
rem Int
x Int
y

divMod :: Int -> Int -> (Int, Int)
divMod :: Int -> Int -> (Int, Int)
divMod Int
x Int
y
  | Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = case (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int -> Int -> (Int, Int)
`quotRem` Int
y of (Int
q,Int
r) -> (Int
qInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1, Int
rInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
  | Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
&& Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 = case (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Int -> Int -> (Int, Int)
`quotRem` Int
y of (Int
q,Int
r) -> (Int
qInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1, Int
rInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
divMod Int
x Int
y         = Int -> Int -> (Int, Int)
quotRem Int
x Int
y

min :: (Num a) => a -> a -> a
min :: a -> a -> a
min = [Char] -> a -> a -> a
forall s a. IsString s => s -> a
ffi [Char]
"Math.min(Fay$$_(%1),Fay$$_(%2))"

max :: (Num a) => a -> a -> a
max :: a -> a -> a
max = [Char] -> a -> a -> a
forall s a. IsString s => s -> a
ffi [Char]
"Math.max(Fay$$_(%1),Fay$$_(%2))"

recip :: Double -> Double
recip :: Double -> Double
recip Double
x = Double
1 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
x

-- | Implemented in Fay.
negate :: Num a => a -> a
negate :: a -> a
negate a
x = (-a
x)

-- | Implemented in Fay.
abs :: (Num a, Ord a) => a -> a
abs :: a -> a
abs a
x = if a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 then a -> a
forall a. Num a => a -> a
negate a
x else a
x

-- | Implemented in Fay.
signum :: (Num a, Ord a) => a -> a
signum :: a -> a
signum a
x = if a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
0 then a
1 else if a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 then a
0 else -a
1

-- | Uses Math.PI.
pi :: Double
pi :: Double
pi = [Char] -> Double
forall s a. IsString s => s -> a
ffi [Char]
"Math.PI"

-- | Uses Math.exp.
exp :: Double -> Double
exp :: Double -> Double
exp = [Char] -> Double -> Double
forall s a. IsString s => s -> a
ffi [Char]
"Math.exp(%1)"

-- | Uses Math.sqrt.
sqrt :: Double -> Double
sqrt :: Double -> Double
sqrt = [Char] -> Double -> Double
forall s a. IsString s => s -> a
ffi [Char]
"Math.sqrt(%1)"

-- | Uses Math.log.
log :: Double -> Double
log :: Double -> Double
log = [Char] -> Double -> Double
forall s a. IsString s => s -> a
ffi [Char]
"Math.log(%1)"

-- | Uses Math.pow.
(**) :: Double -> Double -> Double
** :: Double -> Double -> Double
(**) = Double -> Double -> Double
forall a b. (Num a, Num b) => a -> b -> a
unsafePow

-- | Uses Math.pow.
(^^) :: Double -> Int -> Double
^^ :: Double -> Int -> Double
(^^) = Double -> Int -> Double
forall a b. (Num a, Num b) => a -> b -> a
unsafePow

-- | Uses Math.pow.
unsafePow :: (Num a,Num b) => a -> b -> a
unsafePow :: a -> b -> a
unsafePow = [Char] -> a -> b -> a
forall s a. IsString s => s -> a
ffi [Char]
"Math.pow(Fay$$_(%1),Fay$$_(%2))"

-- | Implemented in Fay, it's not fast.
(^) :: Num a => a -> Int -> a
a
a ^ :: a -> Int -> a
^ Int
b | Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0  = [Char] -> a
forall a. [Char] -> a
error [Char]
"(^): negative exponent"
      | Int
b Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = a
1
      | Int -> Bool
even Int
b = let x :: a
x = a
a a -> Int -> a
forall a. Num a => a -> Int -> a
^ (Int
b Int -> Int -> Int
`quot` Int
2) in a
x a -> a -> a
forall a. Num a => a -> a -> a
* a
x
a
a ^ Int
b          = a
a a -> a -> a
forall a. Num a => a -> a -> a
* a
a a -> Int -> a
forall a. Num a => a -> Int -> a
^ (Int
b Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)

-- | Implemented in Fay, not fast.
logBase :: Double -> Double -> Double
logBase :: Double -> Double -> Double
logBase Double
b Double
x = Double -> Double
log Double
x Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double -> Double
log Double
b

-- | Uses Math.sin.
sin :: Double -> Double
sin :: Double -> Double
sin = [Char] -> Double -> Double
forall s a. IsString s => s -> a
ffi [Char]
"Math.sin(%1)"

-- | Uses Math.tan.
tan :: Double -> Double
tan :: Double -> Double
tan = [Char] -> Double -> Double
forall s a. IsString s => s -> a
ffi [Char]
"Math.tan(%1)"

-- | Uses Math.cos.
cos :: Double -> Double
cos :: Double -> Double
cos = [Char] -> Double -> Double
forall s a. IsString s => s -> a
ffi [Char]
"Math.cos(%1)"

-- | Uses Math.asin.
asin :: Double -> Double
asin :: Double -> Double
asin = [Char] -> Double -> Double
forall s a. IsString s => s -> a
ffi [Char]
"Math.asin(%1)"

-- | Uses Math.atan.
atan :: Double -> Double
atan :: Double -> Double
atan = [Char] -> Double -> Double
forall s a. IsString s => s -> a
ffi [Char]
"Math.atan(%1)"

-- | Uses Math.acos.
acos :: Double -> Double
acos :: Double -> Double
acos = [Char] -> Double -> Double
forall s a. IsString s => s -> a
ffi [Char]
"Math.acos(%1)"

-- | Implemented in Fay, not fast.
sinh :: Double -> Double
sinh :: Double -> Double
sinh Double
x = (Double -> Double
exp Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double -> Double
exp (-Double
x)) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
2

-- | Implemented in Fay, not fast.
tanh :: Double -> Double
tanh :: Double -> Double
tanh Double
x = let a :: Double
a = Double -> Double
exp Double
x ; b :: Double
b = Double -> Double
exp (-Double
x) in (Double
a Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
b) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
a Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
b)

-- | Implemented in Fay, not fast.
cosh :: Double -> Double
cosh :: Double -> Double
cosh Double
x = (Double -> Double
exp Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
exp (-Double
x)) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
2

-- | Implemented in Fay, not fast.
asinh :: Double -> Double
asinh :: Double -> Double
asinh Double
x = Double -> Double
log (Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
sqrt(Double
xDouble -> Double -> Double
**Double
2 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
1))

-- | Implemented in Fay, not fast.
atanh :: Double -> Double
atanh :: Double -> Double
atanh Double
x = Double -> Double
log ((Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
x) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
x)) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
2

-- | Implemented in Fay, not fast.
acosh :: Double -> Double
acosh :: Double -> Double
acosh Double
x = Double -> Double
log (Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
sqrt (Double
xDouble -> Double -> Double
**Double
2 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
1))

-- | Implemented in Fay, not fast.
properFraction :: Double -> (Int, Double)
properFraction :: Double -> (Int, Double)
properFraction Double
x = let a :: Int
a = Double -> Int
truncate Double
x in (Int
a, Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
- Int -> Double
forall a b. (Num a, Num b) => a -> b
fromIntegral Int
a)

-- | Implemented in Fay, not fast.
truncate :: Double -> Int
truncate :: Double -> Int
truncate Double
x = if Double
x Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
0 then Double -> Int
ceiling Double
x else Double -> Int
floor Double
x

-- | Uses Math.round.
round :: Double -> Int
round :: Double -> Int
round = [Char] -> Double -> Int
forall s a. IsString s => s -> a
ffi [Char]
"Math.round(%1)"

-- | Uses Math.ceil.
ceiling :: Double -> Int
ceiling :: Double -> Int
ceiling = [Char] -> Double -> Int
forall s a. IsString s => s -> a
ffi [Char]
"Math.ceil(%1)"

-- | Uses Math.floor.
floor :: Double -> Int
floor :: Double -> Int
floor = [Char] -> Double -> Int
forall s a. IsString s => s -> a
ffi [Char]
"Math.floor(%1)"

-- | Flip (-).
subtract :: Num a => a -> a -> a
subtract :: a -> a -> a
subtract = (a -> a -> a) -> a -> a -> a
forall t1 t2 t. (t1 -> t2 -> t) -> t2 -> t1 -> t
flip (-)

-- | Implemented in Fay, not fast.
even :: Int -> Bool
even :: Int -> Bool
even Int
x = Int
x Int -> Int -> Int
`rem` Int
2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0

-- | not (even x)
odd :: Int -> Bool
odd :: Int -> Bool
odd Int
x = Bool -> Bool
not (Int -> Bool
even Int
x)

-- | Implemented in Fay, not fast.
gcd :: Int -> Int -> Int
gcd :: Int -> Int -> Int
gcd Int
a Int
b = Int -> Int -> Int
go (Int -> Int
forall a. (Num a, Ord a) => a -> a
abs Int
a) (Int -> Int
forall a. (Num a, Ord a) => a -> a
abs Int
b)
  where go :: Int -> Int -> Int
go Int
x Int
0 = Int
x
        go Int
x Int
y = Int -> Int -> Int
go Int
y (Int
x Int -> Int -> Int
`rem` Int
y)

-- | Uses quot'.
quot :: Int -> Int -> Int
quot :: Int -> Int -> Int
quot Int
x Int
y = if Int
y Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then [Char] -> Int
forall a. [Char] -> a
error [Char]
"Division by zero" else Int -> Int -> Int
quot' Int
x Int
y

-- | Uses ~~(a/b).
quot' :: Int -> Int -> Int
quot' :: Int -> Int -> Int
quot' = [Char] -> Int -> Int -> Int
forall s a. IsString s => s -> a
ffi [Char]
"~~(%1/%2)"

-- | (quot x y, rem x y)
quotRem :: Int -> Int -> (Int, Int)
quotRem :: Int -> Int -> (Int, Int)
quotRem Int
x Int
y = (Int -> Int -> Int
quot Int
x Int
y, Int -> Int -> Int
rem Int
x Int
y)

-- | Uses rem'.
rem :: Int -> Int -> Int
rem :: Int -> Int -> Int
rem Int
x Int
y = if Int
y Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then [Char] -> Int
forall a. [Char] -> a
error [Char]
"Division by zero" else Int -> Int -> Int
rem' Int
x Int
y

-- | Uses %%.
rem' :: Int -> Int -> Int
rem' :: Int -> Int -> Int
rem' = [Char] -> Int -> Int -> Int
forall s a. IsString s => s -> a
ffi [Char]
"%1 %% %2"

lcm :: Int -> Int -> Int
lcm :: Int -> Int -> Int
lcm Int
_ Int
0 = Int
0
lcm Int
0 Int
_ = Int
0
lcm Int
a Int
b = Int -> Int
forall a. (Num a, Ord a) => a -> a
abs ((Int
a Int -> Int -> Int
`quot` (Int -> Int -> Int
gcd Int
a Int
b)) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
b)

--------------------------------------------------------------------------------
-- Lists

find :: (a -> Bool) -> [a] -> Maybe a
find :: (a -> Bool) -> [a] -> Maybe a
find a -> Bool
p (a
x:[a]
xs) = if a -> Bool
p a
x then a -> Maybe a
forall a. a -> Maybe a
Just a
x else (a -> Bool) -> [a] -> Maybe a
forall a. (a -> Bool) -> [a] -> Maybe a
find a -> Bool
p [a]
xs
find a -> Bool
_ [] = Maybe a
forall a. Maybe a
Nothing

filter :: (a -> Bool) -> [a] -> [a]
filter :: (a -> Bool) -> [a] -> [a]
filter a -> Bool
p (a
x:[a]
xs) = if a -> Bool
p a
x then a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter a -> Bool
p [a]
xs else (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter a -> Bool
p [a]
xs
filter a -> Bool
_ []     = []

null :: [t] -> Bool
null :: [t] -> Bool
null [] = Bool
True
null [t]
_ = Bool
False

map :: (a -> b) -> [a] -> [b]
map :: (a -> b) -> [a] -> [b]
map a -> b
_ []     = []
map a -> b
f (a
x:[a]
xs) = a -> b
f a
x b -> [b] -> [b]
forall a. a -> [a] -> [a]
: (a -> b) -> [a] -> [b]
forall a b. (a -> b) -> [a] -> [b]
map a -> b
f [a]
xs

nub :: Eq a => [a] -> [a]
nub :: [a] -> [a]
nub [a]
ls = [a] -> [a] -> [a]
forall a. Eq a => [a] -> [a] -> [a]
nub' [a]
ls []

nub' :: Eq a => [a] -> [a] -> [a]
nub' :: [a] -> [a] -> [a]
nub' []     [a]
_ = []
nub' (a
x:[a]
xs) [a]
ls =
  if a -> [a] -> Bool
forall a. Eq a => a -> [a] -> Bool
elem a
x [a]
ls
     then [a] -> [a] -> [a]
forall a. Eq a => [a] -> [a] -> [a]
nub' [a]
xs [a]
ls
     else a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a] -> [a] -> [a]
forall a. Eq a => [a] -> [a] -> [a]
nub' [a]
xs (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
ls)

elem :: Eq a => a -> [a] -> Bool
elem :: a -> [a] -> Bool
elem a
x (a
y:[a]
ys)   = a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
y Bool -> Bool -> Bool
|| a -> [a] -> Bool
forall a. Eq a => a -> [a] -> Bool
elem a
x [a]
ys
elem a
_ []       = Bool
False

notElem :: Eq a => a -> [a] -> Bool
notElem :: a -> [a] -> Bool
notElem a
x [a]
ys = Bool -> Bool
not (a -> [a] -> Bool
forall a. Eq a => a -> [a] -> Bool
elem a
x [a]
ys)

sort :: Ord a => [a] -> [a]
sort :: [a] -> [a]
sort = (a -> a -> Ordering) -> [a] -> [a]
forall t. (t -> t -> Ordering) -> [t] -> [t]
sortBy a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare

sortBy :: (t -> t -> Ordering) -> [t] -> [t]
sortBy :: (t -> t -> Ordering) -> [t] -> [t]
sortBy t -> t -> Ordering
cmp = (t -> [t] -> [t]) -> [t] -> [t] -> [t]
forall t t1. (t -> t1 -> t1) -> t1 -> [t] -> t1
foldr ((t -> t -> Ordering) -> t -> [t] -> [t]
forall a. (a -> a -> Ordering) -> a -> [a] -> [a]
insertBy t -> t -> Ordering
cmp) []

insertBy :: (a -> a -> Ordering) -> a -> [a] -> [a]
insertBy :: (a -> a -> Ordering) -> a -> [a] -> [a]
insertBy a -> a -> Ordering
_   a
x [] = [a
x]
insertBy a -> a -> Ordering
cmp a
x [a]
ys =
  case [a]
ys of
    [] -> [a
x]
    a
y:[a]
ys' ->
      case a -> a -> Ordering
cmp a
x a
y of
         Ordering
GT -> a
y a -> [a] -> [a]
forall a. a -> [a] -> [a]
: (a -> a -> Ordering) -> a -> [a] -> [a]
forall a. (a -> a -> Ordering) -> a -> [a] -> [a]
insertBy a -> a -> Ordering
cmp a
x [a]
ys'
         Ordering
_  -> a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
ys

-- | Append two lists.
conc :: [a] -> [a] -> [a]
conc :: [a] -> [a] -> [a]
conc (a
x:[a]
xs) [a]
ys = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
conc [a]
xs [a]
ys
conc []     [a]
ys = [a]
ys

concat :: [[a]] -> [a]
concat :: [[a]] -> [a]
concat = ([a] -> [a] -> [a]) -> [a] -> [[a]] -> [a]
forall t t1. (t -> t1 -> t1) -> t1 -> [t] -> t1
foldr [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
conc []

concatMap :: (a -> [b]) -> [a] -> [b]
concatMap :: (a -> [b]) -> [a] -> [b]
concatMap a -> [b]
f = (a -> [b] -> [b]) -> [b] -> [a] -> [b]
forall t t1. (t -> t1 -> t1) -> t1 -> [t] -> t1
foldr ([b] -> [b] -> [b]
forall a. [a] -> [a] -> [a]
(++) ([b] -> [b] -> [b]) -> (a -> [b]) -> a -> [b] -> [b]
forall t1 t t2. (t1 -> t) -> (t2 -> t1) -> t2 -> t
. a -> [b]
f) []

foldr :: (t -> t1 -> t1) -> t1 -> [t] -> t1
foldr :: (t -> t1 -> t1) -> t1 -> [t] -> t1
foldr t -> t1 -> t1
_ t1
z []     = t1
z
foldr t -> t1 -> t1
f t1
z (t
x:[t]
xs) = t -> t1 -> t1
f t
x ((t -> t1 -> t1) -> t1 -> [t] -> t1
forall t t1. (t -> t1 -> t1) -> t1 -> [t] -> t1
foldr t -> t1 -> t1
f t1
z [t]
xs)

foldr1 :: (a -> a -> a) -> [a] -> a
foldr1 :: (a -> a -> a) -> [a] -> a
foldr1 a -> a -> a
_ [a
x]    = a
x
foldr1 a -> a -> a
f (a
x:[a]
xs) = a -> a -> a
f a
x ((a -> a -> a) -> [a] -> a
forall a. (a -> a -> a) -> [a] -> a
foldr1 a -> a -> a
f [a]
xs)
foldr1 a -> a -> a
_ []     = [Char] -> a
forall a. [Char] -> a
error [Char]
"foldr1: empty list"

foldl :: (t1 -> t -> t1) -> t1 -> [t] -> t1
foldl :: (t1 -> t -> t1) -> t1 -> [t] -> t1
foldl t1 -> t -> t1
_ t1
z []     = t1
z
foldl t1 -> t -> t1
f t1
z (t
x:[t]
xs) = (t1 -> t -> t1) -> t1 -> [t] -> t1
forall t1 t. (t1 -> t -> t1) -> t1 -> [t] -> t1
foldl t1 -> t -> t1
f (t1 -> t -> t1
f t1
z t
x) [t]
xs

foldl1 :: (a -> a -> a) -> [a] -> a
foldl1 :: (a -> a -> a) -> [a] -> a
foldl1 a -> a -> a
f (a
x:[a]
xs) = (a -> a -> a) -> a -> [a] -> a
forall t1 t. (t1 -> t -> t1) -> t1 -> [t] -> t1
foldl a -> a -> a
f a
x [a]
xs
foldl1 a -> a -> a
_ []     = [Char] -> a
forall a. [Char] -> a
error [Char]
"foldl1: empty list"

(++) :: [a] -> [a] -> [a]
[a]
x ++ :: [a] -> [a] -> [a]
++ [a]
y = [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
conc [a]
x [a]
y

(!!) :: [a] -> Int -> a
[a]
a !! :: [a] -> Int -> a
!! Int
b = if Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then [Char] -> a
forall a. [Char] -> a
error [Char]
"(!!): negative index" else [a] -> Int -> a
forall t p. (Eq t, Num t) => [p] -> t -> p
go [a]
a Int
b
  where go :: [p] -> t -> p
go []    t
_ = [Char] -> p
forall a. [Char] -> a
error [Char]
"(!!): index too large"
        go (p
h:[p]
_) t
0 = p
h
        go (p
_:[p]
t) t
n = [p] -> t -> p
go [p]
t (t
nt -> t -> t
forall a. Num a => a -> a -> a
-t
1)

head :: [a] -> a
head :: [a] -> a
head []    = [Char] -> a
forall a. [Char] -> a
error [Char]
"head: empty list"
head (a
h:[a]
_) = a
h

tail :: [a] -> [a]
tail :: [a] -> [a]
tail []    = [Char] -> [a]
forall a. [Char] -> a
error [Char]
"tail: empty list"
tail (a
_:[a]
t) = [a]
t

init :: [a] -> [a]
init :: [a] -> [a]
init []    = [Char] -> [a]
forall a. [Char] -> a
error [Char]
"init: empty list"
init [a
_]   = []
init (a
h:[a]
t) = a
h a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a] -> [a]
forall a. [a] -> [a]
init [a]
t

last :: [a] -> a
last :: [a] -> a
last []    = [Char] -> a
forall a. [Char] -> a
error [Char]
"last: empty list"
last [a
a]   = a
a
last (a
_:[a]
t) = [a] -> a
forall a. [a] -> a
last [a]
t

iterate :: (a -> a) -> a -> [a]
iterate :: (a -> a) -> a -> [a]
iterate a -> a
f a
x = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: (a -> a) -> a -> [a]
forall a. (a -> a) -> a -> [a]
iterate a -> a
f (a -> a
f a
x)

repeat :: a -> [a]
repeat :: a -> [a]
repeat a
x = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: a -> [a]
forall a. a -> [a]
repeat a
x

replicate :: Int -> a -> [a]
replicate :: Int -> a -> [a]
replicate Int
0 a
_ = []
replicate Int
n a
x = if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then []
                         else a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: Int -> a -> [a]
forall a. Int -> a -> [a]
replicate (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) a
x

cycle :: [a] -> [a]
cycle :: [a] -> [a]
cycle [] = [Char] -> [a]
forall a. [Char] -> a
error [Char]
"cycle: empty list"
cycle [a]
xs = [a]
xs' where xs' :: [a]
xs' = [a]
xs [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a]
xs'

take :: Int -> [a] -> [a]
take :: Int -> [a] -> [a]
take Int
0 [a]
_  = []
take Int
_ [] = []
take Int
n (a
x:[a]
xs) = if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then []
                         else a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) [a]
xs

drop :: Int -> [a] -> [a]
drop :: Int -> [a] -> [a]
drop Int
0 [a]
xs = [a]
xs
drop Int
_ [] = []
drop Int
n xss :: [a]
xss@(a
_:[a]
xs) = if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then [a]
xss
                             else Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) [a]
xs

splitAt :: Int -> [a] -> ([a], [a])
splitAt :: Int -> [a] -> ([a], [a])
splitAt Int
0 [a]
xs     = ([], [a]
xs)
splitAt Int
_ []     = ([], [])
splitAt Int
n (a
x:[a]
xs) = if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then ([],a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
xs)
                            else case Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) [a]
xs of ([a]
a,[a]
b) -> (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
a, [a]
b)

takeWhile :: (a -> Bool) -> [a] -> [a]
takeWhile :: (a -> Bool) -> [a] -> [a]
takeWhile a -> Bool
_ []     = []
takeWhile a -> Bool
p (a
x:[a]
xs) = if a -> Bool
p a
x then a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile a -> Bool
p [a]
xs else []

dropWhile :: (a -> Bool) -> [a] -> [a]
dropWhile :: (a -> Bool) -> [a] -> [a]
dropWhile a -> Bool
_ []     = []
dropWhile a -> Bool
p (a
x:[a]
xs) = if a -> Bool
p a
x then (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile a -> Bool
p [a]
xs else a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
xs

span :: (a -> Bool) -> [a] -> ([a], [a])
span :: (a -> Bool) -> [a] -> ([a], [a])
span a -> Bool
_ []     = ([], [])
span a -> Bool
p (a
x:[a]
xs) = if a -> Bool
p a
x then case (a -> Bool) -> [a] -> ([a], [a])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span a -> Bool
p [a]
xs of ([a]
a,[a]
b) -> (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
a, [a]
b) else ([], a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
xs)

break :: (a -> Bool) -> [a] -> ([a], [a])
break :: (a -> Bool) -> [a] -> ([a], [a])
break a -> Bool
p = (a -> Bool) -> [a] -> ([a], [a])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span (Bool -> Bool
not (Bool -> Bool) -> (a -> Bool) -> a -> Bool
forall t1 t t2. (t1 -> t) -> (t2 -> t1) -> t2 -> t
. a -> Bool
p)

zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith a -> b -> c
f (a
a:[a]
as) (b
b:[b]
bs) = a -> b -> c
f a
a b
b c -> [c] -> [c]
forall a. a -> [a] -> [a]
: (a -> b -> c) -> [a] -> [b] -> [c]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith a -> b -> c
f [a]
as [b]
bs
zipWith a -> b -> c
_ [a]
_      [b]
_      = []

zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3 a -> b -> c -> d
f (a
a:[a]
as) (b
b:[b]
bs) (c
c:[c]
cs) = a -> b -> c -> d
f a
a b
b c
c d -> [d] -> [d]
forall a. a -> [a] -> [a]
: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3 a -> b -> c -> d
f [a]
as [b]
bs [c]
cs
zipWith3 a -> b -> c -> d
_ [a]
_      [b]
_      [c]
_      = []

zip :: [a] -> [b] -> [(a,b)]
zip :: [a] -> [b] -> [(a, b)]
zip (a
a:[a]
as) (b
b:[b]
bs) = (a
a,b
b) (a, b) -> [(a, b)] -> [(a, b)]
forall a. a -> [a] -> [a]
: [a] -> [b] -> [(a, b)]
forall a b. [a] -> [b] -> [(a, b)]
zip [a]
as [b]
bs
zip [a]
_      [b]
_      = []

zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]
zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]
zip3 (a
a:[a]
as) (b
b:[b]
bs) (c
c:[c]
cs) = (a
a,b
b,c
c) (a, b, c) -> [(a, b, c)] -> [(a, b, c)]
forall a. a -> [a] -> [a]
: [a] -> [b] -> [c] -> [(a, b, c)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [a]
as [b]
bs [c]
cs
zip3 [a]
_      [b]
_      [c]
_      = []

unzip :: [(a, b)] -> ([a], [b])
unzip :: [(a, b)] -> ([a], [b])
unzip ((a
x,b
y):[(a, b)]
ps) = case [(a, b)] -> ([a], [b])
forall a b. [(a, b)] -> ([a], [b])
unzip [(a, b)]
ps of ([a]
xs,[b]
ys) -> (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
xs, b
yb -> [b] -> [b]
forall a. a -> [a] -> [a]
:[b]
ys)
unzip []         = ([], [])

unzip3 :: [(a, b, c)] -> ([a], [b], [c])
unzip3 :: [(a, b, c)] -> ([a], [b], [c])
unzip3 ((a
x,b
y,c
z):[(a, b, c)]
ps) = case [(a, b, c)] -> ([a], [b], [c])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 [(a, b, c)]
ps of ([a]
xs,[b]
ys,[c]
zs) -> (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
xs, b
yb -> [b] -> [b]
forall a. a -> [a] -> [a]
:[b]
ys, c
zc -> [c] -> [c]
forall a. a -> [a] -> [a]
:[c]
zs)
unzip3 []           = ([], [], [])

lines :: String -> [String]
lines :: [Char] -> [[Char]]
lines []   = []
lines [Char]
s    = case (Char -> Bool) -> [Char] -> ([Char], [Char])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break Char -> Bool
isLineBreak [Char]
s of ([Char]
a, [])   -> [[Char]
a]
                                         ([Char]
a, Char
_:[Char]
cs) -> [Char]
a [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: [Char] -> [[Char]]
lines [Char]
cs
  where isLineBreak :: Char -> Bool
isLineBreak Char
c = Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\r' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n'

unlines :: [String] -> String
unlines :: [[Char]] -> [Char]
unlines [] = []
unlines ([Char]
l:[[Char]]
ls) = [Char]
l [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Char
'\n' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [[Char]] -> [Char]
unlines [[Char]]
ls

words :: String -> [String]
words :: [Char] -> [[Char]]
words [Char]
str = [Char] -> [[Char]]
words' ((Char -> Bool) -> [Char] -> [Char]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace [Char]
str)
  where words' :: [Char] -> [[Char]]
words' []  = []
        words' [Char]
s = case (Char -> Bool) -> [Char] -> ([Char], [Char])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break Char -> Bool
isSpace [Char]
s of ([Char]
a,[Char]
b) -> [Char]
a [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: [Char] -> [[Char]]
words [Char]
b
        isSpace :: Char -> Bool
isSpace Char
c  = Char
c Char -> [Char] -> Bool
forall a. Eq a => a -> [a] -> Bool
`elem` [Char]
" \t\r\n\f\v"

unwords :: [String] -> String
unwords :: [[Char]] -> [Char]
unwords = [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
" "

and :: [Bool] -> Bool
and :: [Bool] -> Bool
and []     = Bool
True
and (Bool
x:[Bool]
xs) = Bool
x Bool -> Bool -> Bool
&& [Bool] -> Bool
and [Bool]
xs

or :: [Bool] -> Bool
or :: [Bool] -> Bool
or []     = Bool
False
or (Bool
x:[Bool]
xs) = Bool
x Bool -> Bool -> Bool
|| [Bool] -> Bool
or [Bool]
xs

any :: (a -> Bool) -> [a] -> Bool
any :: (a -> Bool) -> [a] -> Bool
any a -> Bool
_ []     = Bool
False
any a -> Bool
p (a
x:[a]
xs) = a -> Bool
p a
x Bool -> Bool -> Bool
|| (a -> Bool) -> [a] -> Bool
forall a. (a -> Bool) -> [a] -> Bool
any a -> Bool
p [a]
xs

all :: (a -> Bool) -> [a] -> Bool
all :: (a -> Bool) -> [a] -> Bool
all a -> Bool
_ []     = Bool
True
all a -> Bool
p (a
x:[a]
xs) = a -> Bool
p a
x Bool -> Bool -> Bool
&& (a -> Bool) -> [a] -> Bool
forall a. (a -> Bool) -> [a] -> Bool
all a -> Bool
p [a]
xs

intersperse :: a -> [a] -> [a]
intersperse :: a -> [a] -> [a]
intersperse a
_   []      = []
intersperse a
sep (a
x:[a]
xs)  = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: a -> [a] -> [a]
forall a. a -> [a] -> [a]
prependToAll a
sep [a]
xs

prependToAll :: a -> [a] -> [a]
prependToAll :: a -> [a] -> [a]
prependToAll a
_   []     = []
prependToAll a
sep (a
x:[a]
xs) = a
sep a -> [a] -> [a]
forall a. a -> [a] -> [a]
: a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: a -> [a] -> [a]
forall a. a -> [a] -> [a]
prependToAll a
sep [a]
xs

intercalate :: [a] -> [[a]] -> [a]
intercalate :: [a] -> [[a]] -> [a]
intercalate [a]
xs [[a]]
xss = [[a]] -> [a]
forall a. [[a]] -> [a]
concat ([a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
intersperse [a]
xs [[a]]
xss)

maximum :: (Num a) => [a] -> a
maximum :: [a] -> a
maximum [] = [Char] -> a
forall a. [Char] -> a
error [Char]
"maximum: empty list"
maximum [a]
xs = (a -> a -> a) -> [a] -> a
forall a. (a -> a -> a) -> [a] -> a
foldl1 a -> a -> a
forall a. Num a => a -> a -> a
max [a]
xs

minimum :: (Num a) => [a] -> a
minimum :: [a] -> a
minimum [] = [Char] -> a
forall a. [Char] -> a
error [Char]
"minimum: empty list"
minimum [a]
xs = (a -> a -> a) -> [a] -> a
forall a. (a -> a -> a) -> [a] -> a
foldl1 a -> a -> a
forall a. Num a => a -> a -> a
min [a]
xs

product :: Num a => [a] -> a
product :: [a] -> a
product [a]
xs = (a -> a -> a) -> a -> [a] -> a
forall t1 t. (t1 -> t -> t1) -> t1 -> [t] -> t1
foldl a -> a -> a
forall a. Num a => a -> a -> a
(*) a
1 [a]
xs

sum :: Num a => [a] -> a
sum :: [a] -> a
sum [a]
xs = (a -> a -> a) -> a -> [a] -> a
forall t1 t. (t1 -> t -> t1) -> t1 -> [t] -> t1
foldl a -> a -> a
forall a. Num a => a -> a -> a
(+) a
0 [a]
xs

scanl :: (a -> b -> a) -> a -> [b] -> [a]
scanl :: (a -> b -> a) -> a -> [b] -> [a]
scanl a -> b -> a
f a
z [b]
l = a
z a -> [a] -> [a]
forall a. a -> [a] -> [a]
: case [b]
l of [] -> []
                            (b
x:[b]
xs) -> (a -> b -> a) -> a -> [b] -> [a]
forall a b. (a -> b -> a) -> a -> [b] -> [a]
scanl a -> b -> a
f (a -> b -> a
f a
z b
x) [b]
xs

scanl1 :: (a -> a -> a) -> [a] -> [a]
scanl1 :: (a -> a -> a) -> [a] -> [a]
scanl1 a -> a -> a
_ [] = []
scanl1 a -> a -> a
f (a
x:[a]
xs) = (a -> a -> a) -> a -> [a] -> [a]
forall a b. (a -> b -> a) -> a -> [b] -> [a]
scanl a -> a -> a
f a
x [a]
xs

scanr :: (a -> b -> b) -> b -> [a] -> [b]
scanr :: (a -> b -> b) -> b -> [a] -> [b]
scanr a -> b -> b
_ b
z [] = [b
z]
scanr a -> b -> b
f b
z (a
x:[a]
xs) = case (a -> b -> b) -> b -> [a] -> [b]
forall a b. (a -> b -> b) -> b -> [a] -> [b]
scanr a -> b -> b
f b
z [a]
xs of (b
h:[b]
t) -> a -> b -> b
f a
x b
h b -> [b] -> [b]
forall a. a -> [a] -> [a]
: b
h b -> [b] -> [b]
forall a. a -> [a] -> [a]
: [b]
t
                                        [b]
_     -> [b]
forall a. a
undefined

scanr1 :: (a -> a -> a) -> [a] -> [a]
scanr1 :: (a -> a -> a) -> [a] -> [a]
scanr1 a -> a -> a
_ []     = []
scanr1 a -> a -> a
_ [a
x]    = [a
x]
scanr1 a -> a -> a
f (a
x:[a]
xs) = case (a -> a -> a) -> [a] -> [a]
forall a. (a -> a -> a) -> [a] -> [a]
scanr1 a -> a -> a
f [a]
xs of (a
h:[a]
t) -> a -> a -> a
f a
x a
h a -> [a] -> [a]
forall a. a -> [a] -> [a]
: a
h a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
t
                                      [a]
_     -> [a]
forall a. a
undefined

lookup :: Eq a1 => a1 -> [(a1, a)] -> Maybe a
lookup :: a1 -> [(a1, a)] -> Maybe a
lookup a1
_key []          =  Maybe a
forall a. Maybe a
Nothing
lookup  a1
key ((a1
x,a
y):[(a1, a)]
xys) =
  if a1
key a1 -> a1 -> Bool
forall a. Eq a => a -> a -> Bool
== a1
x
     then a -> Maybe a
forall a. a -> Maybe a
Just a
y
     else a1 -> [(a1, a)] -> Maybe a
forall a1 a. Eq a1 => a1 -> [(a1, a)] -> Maybe a
lookup a1
key [(a1, a)]
xys

length :: [a] -> Int
length :: [a] -> Int
length [a]
xs = Int -> [a] -> Int
forall a. Int -> [a] -> Int
length' Int
0 [a]
xs

length' :: Int -> [a] -> Int
length' :: Int -> [a] -> Int
length' Int
acc (a
_:[a]
xs) = Int -> [a] -> Int
forall a. Int -> [a] -> Int
length' (Int
accInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) [a]
xs
length' Int
acc [a]
_ = Int
acc

reverse :: [a] -> [a]
reverse :: [a] -> [a]
reverse (a
x:[a]
xs) = [a] -> [a]
forall a. [a] -> [a]
reverse [a]
xs [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a
x]
reverse [] = []

--------------------------------------------------------------------------------
-- IO

print :: Automatic a -> Fay ()
print :: Automatic a -> Fay ()
print = [Char] -> Automatic a -> Fay ()
forall s a. IsString s => s -> a
ffi [Char]
"(function(x) { if (console && console.log) console.log(x) })(%1)"

putStrLn :: String -> Fay ()
putStrLn :: [Char] -> Fay ()
putStrLn = [Char] -> [Char] -> Fay ()
forall s a. IsString s => s -> a
ffi [Char]
"(function(x) { if (console && console.log) console.log(x) })(%1)"

--------------------------------------------------------------------------------
-- Additions

-- | Default definition for using RebindableSyntax.
ifThenElse :: Bool -> t -> t -> t
ifThenElse :: Bool -> t -> t -> t
ifThenElse Bool
p t
a t
b = if Bool
p then t
a else t
b