リストには関数が多数定義されていて便利なのですけれども、速度はVectorにかないません。
そこで Vector を便利に使うための関数を作って集めていきます。
catMaybes を各要素がMaybe型のリストに適用するとNothing の要素は取り除かれ、Just a は a の要素のみになります。
import qualified Data.Vector as V (Vector, null, head, cons, empty, tail) vCatMaybes :: V.Vector (Maybe a) -> V.Vector a vCatMaybes vect | V.null vect = V.empty | otherwise = case V.head vect of Just x -> x `V.cons` vCatMaybes (V.tail vect) Nothing -> vCatMaybes (V.tail vect) -- 同等 vCatMaybes2 = V.foldr (\a acc -> case a of{ Just x->(x `V.cons` acc); Nothing-> acc}) V.empty {- *Main Data.Vector> vCatMaybes (V.fromList [Just 1,Nothing,Just 100,Nothing]) -- => fromList [1,100] *Main Data.Vector> vCatMaybes (V.fromList [Just 1,Nothing]) -- => fromList [1] *Main Data.Vector> vCatMaybes (V.fromList [Nothing,Nothing]) -- => fromList [] *Main Data.Vector> vCatMaybes (V.fromList []) -- => fromList [] -}
import qualified Data.Vector as V (Vector, null, head, cons, empty, tail, map, singleton, fromList) mergesort :: (a -> a -> Ordering) -> V.Vector a -> V.Vector a mergesort cmp = mergesort' cmp . V.map wrap mergesort' :: (a -> a -> Ordering) -> V.Vector (V.Vector a) -> V.Vector a mergesort' cmp vect | V.null vect = V.empty | V.null (V.tail vect) = V.head vect | otherwise = mergesort' cmp (merge_pairs cmp vect) merge_pairs :: (a -> a -> Ordering) -> V.Vector (V.Vector a) -> V.Vector (V.Vector a) merge_pairs cmp vect | V.null vect = V.empty | V.null (V.tail vect) = vect | otherwise = merge cmp xs ys `V.cons` merge_pairs cmp xss where xs = V.head vect rest = V.tail vect ys = V.head rest xss = V.tail rest merge :: (a -> a -> Ordering) -> V.Vector a -> V.Vector a -> V.Vector a merge cmp xxs yys | V.null xxs = yys | V.null yys = xxs | otherwise = let x = V.head xxs y = V.head yys xs = V.tail xxs ys = V.tail yys in case (V.head xxs) `cmp` (V.head yys) of GT -> y `V.cons` merge cmp xxs ys _ -> x `V.cons` merge cmp xs yys wrap :: a -> V.Vector a wrap x = V.singleton x {- > mergesort compare (V.fromList [9,1,100,5,10,99,2]) -- > fromList [1,2,5,9,10,99,100] > mergesort compare (V.fromList [9,1]) -- > fromList [1,9] > mergesort compare (V.fromList [9]) -- > fromList [9] > mergesort compare (V.fromList []) -- > fromList [] -}
- intersperse
import qualified Data.Vector as V (Vector, null, head, cons, empty, tail, map, foldr, (++), fromList) intersperse :: a -> V.Vector a -> V.Vector a intersperse sep vect | V.null vect = V.empty | otherwise = (V.head vect) `V.cons` prependToAll sep (V.tail vect) prependToAll :: a -> V.Vector a -> V.Vector a prependToAll sep vect | V.null vect = V.empty | otherwise = sep `V.cons` ((V.head vect) `V.cons` (prependToAll sep (V.tail vect)))
vGroupBy eq vect | V.null vect = V.empty | otherwise = (x `V.cons` ys) `V.cons` vGroupBy eq zs where (ys,zs) = vSpan (eq x) xs x = V.head vect xs = V.tail vect {- > vGroupBy (==) (V.fromList "Mississippi") fromList [fromList "M",fromList "i",fromList "ss",fromList "i",fromList "ss",fromList "i",fromList "pp",fromList "i"] -} vSpan :: (a -> Bool) -> V.Vector a -> (V.Vector a, V.Vector a) vSpan p vect | V.null vect = (V.empty,V.empty) | p (V.head vect) = let (ys,zs) = vSpan p (V.tail vect) in ((V.head vect) `V.cons` ys,zs) | otherwise = (V.empty,vect) {- > vSpan (< 3) (V.fromList [1,2,3,4,1,2,3,4]) -- > (fromList [1,2],fromList [3,4,1,2,3,4]) > vSpan (< 4) (V.fromList [1,2,3,4,1,2,3,4]) -- > (fromList [1,2,3],fromList [4,1,2,3,4]) > vSpan (< 5) (V.fromList [1,2,3,4,1,2,3,4]) -- > (fromList [1,2,3,4,1,2,3,4],fromList []) > vSpan (< 1) (V.fromList [1,2,3,4,1,2,3,4]) -- > (fromList [],fromList [1,2,3,4,1,2,3,4]) -}