packages feed

classy-prelude-0.5.1: ClassyPrelude/List.hs

{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
module ClassyPrelude.List () where

import CorePrelude
import ClassyPrelude.Classes
import qualified Data.List as List
import qualified Control.Monad as Monad
import qualified Data.Monoid as Monoid
import qualified Data.Set as Set


instance CanMap [a] [b] a b where
    map = List.map

instance CanConcatMap [a] [b] a [b] where
    concatMap = List.concatMap

instance CanFilter [a] a where
    filter = List.filter

instance CanFilterM [a] a where
    filterM = Monad.filterM

instance CanLength [a] Int where
    length = List.length

instance CanSingleton [a] a where
    singleton = return

instance CanNull [a] where
    null = List.null

instance CanPack [a] a where
    pack = id
    unpack = id
    subsequences = List.subsequences
    permutations = List.permutations

instance CanIntersperse [a] a where
    intersperse = List.intersperse

instance Monad m => CanMapM [i] (m [o]) m i o where
    mapM = Monad.mapM

instance CanMapM_ [a] a where
    mapM_ = Monad.mapM_

instance Eq k => CanLookup [(k, v)] k v where
    lookup = List.lookup

instance Eq k => CanInsertVal [(k, v)] k v where
    insertVal k v c = (k, v) : delete k c

instance Eq k => CanDeleteVal [(k, v)] k where
    deleteVal k = filter ((/= k) . fst)

instance Eq x => CanMember [x] x where
    member x = List.any (== x)

instance Eq a => CanStripPrefix [a] where
    stripPrefix = List.stripPrefix
    isPrefixOf = List.isPrefixOf

instance CanBreak [a] a where
    break = List.break
    span = List.span
    dropWhile = List.dropWhile
    takeWhile = List.takeWhile

instance CanAny [a] a where
    any = List.any
    all = List.all

instance CanSplitAt [c] Int where
    splitAt = List.splitAt

instance CanFold [a] a accum where
    fold = List.foldl'

instance (c ~ Char) => CanWords [c] where
    words = List.words
    unwords = List.unwords

instance (c ~ Char) => CanLines [c] where
    lines = List.lines

instance (c ~ Char) => CanUnlines [c] where
    unlines = List.unlines

instance Eq a => CanIsInfixOf [a] where
    isInfixOf = List.isInfixOf

instance CanReverse [a] where
    reverse = List.reverse

instance CanReplicate [i] i Int where
    replicate = List.replicate

instance CanReplicateM [a] a Int where
    replicateM = Monad.replicateM

instance CanFind [a] a where
    find = List.find

instance (Monoid m) => CanConcat [m] m where
    concat = Monoid.mconcat

instance CanPartition [a] a where
    partition = List.partition

instance CanNubBy [a] a where
    nubBy = List.nubBy

    nub =
        go Set.empty
      where
        go _ [] = []
        go set (x:xs)
            | x `Set.member` set = go set xs
            | otherwise = x : go (Set.insert x set) xs

instance (Eq a) => CanUnion [a] where
    union = List.union

instance (Eq a) => CanDifference [a] where
    difference = (List.\\)

instance (Eq a) => CanIntersection [a] where
    intersection = List.intersect

instance (Ord a) => CanSortBy [] a where
    sortBy = List.sortBy

instance CanCons [a] a where
    cons = (:)

instance CanUncons [a] a where
    uncons (head:tail) = Just (head, tail)
    uncons _ = Nothing

instance CanCompareLength [a] where
    compareLength [] 0 = EQ
    compareLength _ i | i <= 0 = GT
    compareLength [] _ = LT
    compareLength (_:t) i = compareLength t (i-1)