module List.Advanced where
{-
This module contains implementations of list functions
using higher-order functions like foldr.
This allows concise definitions
but looks ugly in the reduction window
and needs usually more reductions.
-}

import ListLive ( cons, append )
import Bool


(++) :: [a] -> [a] -> [a] ;
[a]
xs ++ :: forall a. [a] -> [a] -> [a]
++ [a]
ys = (a -> [a] -> [a]) -> [a] -> [a] -> [a]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> [a] -> [a]
forall a. a -> [a] -> [a]
cons [a]
ys [a]
xs ;

concat :: [[a]] -> [a] ;
concat :: forall a. [[a]] -> [a]
concat = ([a] -> [a] -> [a]) -> [a] -> [[a]] -> [a]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
append [];


take :: Int -> [a] -> [a] ;
take :: forall a. Int -> [a] -> [a]
take Int
n [a]
xs = (a -> (Int -> [a]) -> Int -> [a])
-> (Int -> [a]) -> [a] -> Int -> [a]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> (Int -> [a]) -> Int -> [a]
forall a. a -> (Int -> [a]) -> Int -> [a]
takeElem ([a] -> Int -> [a]
forall a b. a -> b -> a
const []) [a]
xs Int
n ;

takeElem :: a -> (Int -> [a]) -> Int -> [a] ;
takeElem :: forall a. a -> (Int -> [a]) -> Int -> [a]
takeElem a
_ Int -> [a]
_go Int
0 = [] ;
takeElem a
x Int -> [a]
go Int
m = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: Int -> [a]
go (Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) ;


filter :: (a -> Bool) -> [a] -> [a] ;
filter :: forall a. (a -> Bool) -> [a] -> [a]
filter a -> Bool
p =
   (a -> [a] -> [a]) -> [a] -> [a] -> [a]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((a -> Bool) -> a -> [a] -> [a]
forall a. (a -> Bool) -> a -> [a] -> [a]
filterElem a -> Bool
p) [] ;

filterElem :: (a -> Bool) -> a -> [a] -> [a] ;
filterElem :: forall a. (a -> Bool) -> a -> [a] -> [a]
filterElem a -> Bool
p a
x [a]
xs = Bool -> [a] -> [a] -> [a]
forall a. Bool -> a -> a -> a
ifThenElse (a -> Bool
p a
x) (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
xs) [a]
xs ;

takeWhile :: (a -> Bool) -> [a] -> [a] ;
takeWhile :: forall a. (a -> Bool) -> [a] -> [a]
takeWhile a -> Bool
p =
   (a -> [a] -> [a]) -> [a] -> [a] -> [a]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((a -> Bool) -> a -> [a] -> [a]
forall a. (a -> Bool) -> a -> [a] -> [a]
takeWhileElem a -> Bool
p) [] ;

takeWhileElem :: (a -> Bool) -> a -> [a] -> [a] ;
takeWhileElem :: forall a. (a -> Bool) -> a -> [a] -> [a]
takeWhileElem a -> Bool
p a
x [a]
xs = Bool -> [a] -> [a] -> [a]
forall a. Bool -> a -> a -> a
ifThenElse (a -> Bool
p a
x) (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
xs) [] ;