sequence-0.9.3: Data/SequenceClass.hs
{-# LANGUAGE UndecidableInstances, GADTs,TypeSynonymInstances,FlexibleInstances,Rank2Types #-}
-----------------------------------------------------------------------------
-- |
-- Module : Data.SequenceClass
-- Copyright : (c) Atze van der Ploeg 2014
-- License : BSD-style
-- Maintainer : atzeus@gmail.org
-- Stability : provisional
-- Portability : portable
-- A type class for sequences.
--
-- See the package type-aligned for a generalization of this type class sequences.
--
-----------------------------------------------------------------------------
module Data.SequenceClass(Sequence(..), ViewL(..), ViewR(..)) where
import Data.Monoid
import Data.Foldable
import qualified Data.Sequence as S
infixr 5 <|
infixl 5 |>
infix 5 ><
{- | A type class for (finite) sequences
Minimal complete defention: 'empty' and 'singleton' and ('viewl' or 'viewr') and ('><' or '|>' or '<|')
Instances should satisfy the following laws:
Monoid laws:
> empty >< x == x
> x >< empty == x
> (x >< y) >< z = x >< (y >< z)
Observation laws:
> viewl (singleton e >< s) == e :< s
> viewl empty == EmptyL
The behaviour of '<|','|>', and 'viewr' is implied by the above laws and their default definitions.
-}
class (Functor s, Foldable s) => Sequence s where
empty :: s c
singleton :: c -> s c
-- | Append two sequences
(><) :: s c -> s c -> s c
-- | View a sequence from the left
viewl :: s c -> ViewL s c
-- | View a sequence from the right
--
-- Default definition:
-- > viewr q = case viewl q of
-- > EmptyL -> EmptyR
-- > h :< t -> case viewr t of
-- > EmptyR -> empty :> h
-- > p :> l -> (h <| p) :> l
viewr :: s c -> ViewR s c
-- | Append a single element to the right
--
-- Default definition:
-- > l |> r = l >< singleton r
(|>) :: s c -> c -> s c
-- | Append a single element to the left
--
-- Default definition:
-- > l <| r = singleton l >< r
(<|) :: c -> s c -> s c
l |> r = l >< singleton r
l <| r = singleton l >< r
l >< r = case viewl l of
EmptyL -> r
h :< t -> h <| (t >< r)
viewl q = case viewr q of
EmptyR -> EmptyL
p :> l -> case viewl p of
EmptyL -> l :< empty
h :< t -> h :< (t |> l)
viewr q = case viewl q of
EmptyL -> EmptyR
h :< t -> case viewr t of
EmptyR -> empty :> h
p :> l -> (h <| p) :> l
data ViewL s c where
EmptyL :: ViewL s c
(:<) :: c -> s c -> ViewL s c
data ViewR s c where
EmptyR :: ViewR s c
(:>) :: s c -> c -> ViewR s c
instance Sequence S.Seq where
empty = S.empty
singleton = S.singleton
(<|) = (S.<|)
(|>) = (S.|>)
(><) = (S.><)
viewl s = case S.viewl s of
S.EmptyL -> EmptyL
h S.:< t -> h :< t
viewr s = case S.viewr s of
S.EmptyR -> EmptyR
t S.:> h -> t :> h
instance Sequence [] where
empty = []
singleton x = [x]
(<|) = (:)
viewl [] = EmptyL
viewl (h : t) = h :< t