{-# LANGUAGE UnicodeSyntax, Rank2Types #-} -- | Collection of functions of more general purpose. module SoccerFun.Prelude where import Data.Maybe import Control.Monad.Identity fst3 (x,y,z) = x snd3 (x,y,z) = y thd3 (x,y,z) = z avg ∷ Fractional a ⇒ [a] → a avg xs = sum xs / fromIntegral (length xs) zero ∷ Num a ⇒ a zero = fromIntegral 0 one ∷ Num a ⇒ a one = fromIntegral 1 iterateStn ∷ Int → (s → (a,s)) → s → ([a],s) iterateStn 0 _ s = ([],s) iterateStn n f s = runIdentity $ do (a, s) ← return $ f s (as,s) ← return $ iterateStn (n-1) f s return $ ((a:as),s) singleOutElems ∷ [a] → [(a,[a])] singleOutElems as = singleOut [] as where singleOut ∷ [a] → [a] → [(a,[a])] singleOut _ [] = [] singleOut prefix (a:as)= ((a,prefix++as) : singleOut (prefix++[a]) as) -- | spanfilter cond xs = (filter cond xs, filter (not . cond) xs) spanfilter ∷ (a → Bool) → [a] → ([a],[a]) spanfilter cond [] = ([],[]) spanfilter cond (x:xs) | cond x = ((x:yes),no) | otherwise = (yes,(x:no)) where (yes,no) = spanfilter cond xs spanfilterSt ∷ (a → s → (Bool,s)) → [a] → s → (([a],[a]),s) spanfilterSt cond [] s = (([],[]),s) spanfilterSt cond (x:xs) s = runIdentity $ do (ok,s) ← return $ cond x s ((yes,no),s) ← return $ spanfilterSt cond xs s return $ if ok then (((x:yes),no),s) else ((yes,(x:no)),s) {-| break cond (A ++ B ++ C) = (A,B,C) where for each x in A: not cond x /\ for each x in B: cond x /\ if C=(x:_): not cond x -} break' ∷ (a → Bool) → [a] → ([a],[a],[a]) break' c xs = let (no,yes) = span (not . c) xs (yes',no') = span c yes in (no,yes',no') {-| break1 cond (A ++ [B] ++ C) = (A,B,C) where for each x in A: not cond x /\ cond B /\ if C=(x:_): not cond x -} break1 ∷ (a → Bool) → [a] → ([a],a,[a]) break1 c xs = case break' c xs of (a,[b],c) → (a,b,c) (a,b,c) → error ("break1: [B] is of length: " ++ show (length b) ++ "\n") -- | unbreak (a,b,c) = a ++ b ++ c unbreak ∷ ([a],[a],[a]) → [a] unbreak (a,b,c) = a ++ b ++ c -- | unbreak1 (a,b,c) = a ++ [b] ++ c unbreak1 ∷ ([a],a,[a]) → [a] unbreak1 (a,b,c) = a ++ [b] ++ c {- [a1..x..aN] x = i where aJ /= x for all j x = low | x > up = up | otherwise = x {-| isbetween x low up returns True iff low <= x <= up -} isbetween ∷ Ord a ⇒ a → a → a → Bool isbetween x low up = low <= x && x <= up -- | minmax (a,b) = (a,b) if a<=b; (b,a) otherwise minmax ∷ Ord a ⇒ (a,a) → (a,a) minmax (a,b) | a<=b = (a,b) | otherwise = (b,a) -- | perhaps p Nothing = False, and perhaps p (Just a) = p a perhaps ∷ (a → Bool) → (Maybe a) → Bool perhaps p = maybe False p removeMember ∷ (Eq a) ⇒ a → [a] → [a] removeMember x = filter (/= x) removeMembers ∷ (Eq a) ⇒ [a] → [a] → [a] removeMembers xs ys = foldr removeMember xs ys