{-# OPTIONS -Wall #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TupleSections #-}
module Discokitty.Models.Rel
( Rel
, relation
, fromList
, toList
, relCup
, agrees
)
where
import Data.Maybe
import qualified Data.Set as S
import Discokitty.Dimension
import Discokitty.HasCups
import Discokitty.Words
data Rel u = Rel (S.Set [u])
relation :: (Ord u) => [[u]] -> Rel u
relation = Rel . S.fromList
fromList :: (Ord u) => [[u]] -> Rel u
fromList = relation
toList :: Rel u -> [[u]]
toList (Rel u) = S.toList u
instance (Show u) => Show (Rel u) where
show = show . toList
instance Dim (Rel u) where
dim = dimRel
dimRel :: Rel u -> Int
dimRel = dimList . toList
where
dimList [] = 0
dimList (l : _) = length l
relCup :: (Ord u) => Int -> Rel u -> Rel u -> Rel u
relCup n r s = relation $ catMaybes $ fmap (agrees n) $ do
x <- toList r
y <- toList s
return (x,y)
relCunit :: (Ord u) => Rel u
relCunit = relation [[]]
agrees :: (Eq u) => Int -> ([u] , [u]) -> Maybe [u]
agrees n (x , y) =
if take n (reverse x) == take n y
then Just $ reverse (drop n (reverse x)) ++ drop n y
else Nothing
instance (Ord u) => HasCups (Rel u) where
cup = relCup
cunit = relCunit
instance Dim (Words (Rel u)) where
dim = dim . meaning