-- Author: Andy Stewart -- Maintainer: Andy Stewart -- -- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved. -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . module Manatee.Toolkit.General.Seq where import Data.Sequence (Seq, (><), (<|), (|>), findIndexL, adjust) import qualified Data.Sequence as Seq -- | Filter min. filterMin :: (a -> Bool) -> Seq a -> Maybe a filterMin f seq | Seq.null filterSeq = Nothing | otherwise = Just $ Seq.index filterSeq 0 where filterSeq = Seq.filter f seq -- | Maybe index. maybeIndex :: Seq a -> Int -> Maybe a maybeIndex seq index | index < min || index > max = Nothing | otherwise = Just $ Seq.index seq index where min = 0 max = Seq.length seq - 1 -- | Insert element in sequence. insertAt :: Int -> a -> Seq a -> Seq a insertAt n x xs = ys >< (x <| zs) where (ys, zs) = Seq.splitAt n xs -- | Delete element in sequence. deleteAt :: Int -> Seq a -> Seq a deleteAt n xs = ys >< Seq.drop 1 zs where (ys, zs) = Seq.splitAt n xs -- | Swap two element in sequence. swap :: Int -> Int -> Seq a -> Seq a swap deleteId insertId xs | deleteId < min || deleteId > max = xs | insertId < min || insertId > max = xs | otherwise = zs where min = 0 max = Seq.length xs - 1 x = Seq.index xs deleteId ys = deleteAt deleteId xs zs = insertAt insertId x ys -- | Delete match element in sequence. deleteMatch :: (a -> Bool) -> Seq a -> Seq a deleteMatch f seq = newSeq where index = findIndexL f seq newSeq = case index of Just i -> deleteAt i seq Nothing -> seq -- | Replace element if found match. tryReplace :: (a -> Bool) -> a -> Seq a -> Seq a tryReplace f a seq = case findIndexL f seq of Just i -> adjust (const a) i seq Nothing -> seq -- | Replace or add. replaceOrAdd :: (a -> Bool) -> a -> Seq a -> Seq a replaceOrAdd f a seq = case findIndexL f seq of -- Replace old value if found match Just i -> adjust (const a) i seq -- Otherwise add new value to end. Nothing -> (|>) seq a