packages feed

free-algebras 0.0.7.0 → 0.0.7.1

raw patch · 12 files changed

+135/−59 lines, 12 filesPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

API changes (from Hackage documentation)

+ Data.Group.Free: consL :: Eq a => Either a a -> FreeGroupL a -> FreeGroupL a

Files

ChangeLog.md view
@@ -1,5 +1,10 @@ # Changelog for free-algebras +## Version 0.0.7.1+- `Data.Group.Free.normalize` and `Data.Group.Free.normalizeL` are not both+  `O(n)`, but the former is implemented using the latter (e.g. transforms+  `DList` to a list).+ ## Version 0.0.7.0 - Poly kinded `Control.Algebra.Free.FreeAlgebra` and   `Control.Algebra.Free2.FreeAlgebra2`
free-algebras.cabal view
@@ -1,5 +1,5 @@ name:           free-algebras-version:        0.0.7.0+version:        0.0.7.1 synopsis:       Free algebras in Haskell. description:    Universal algebra approach to free algebras including higher kinded algebraic structures like functors, applicative functors or monads. category:       Algebra, Control, Monads@@ -7,7 +7,7 @@ bug-reports:    https://github.com/coot/free-algebras/issues author:         Marcin Szamotulski maintainer:     profunctor@pm.me-copyright:      (c) 2018 Marcin Szamotulski+copyright:      (c) 2018-2019 Marcin Szamotulski license:        MPL-2.0 license-file:   LICENSE build-type:     Simple@@ -15,7 +15,7 @@ extra-source-files:     ChangeLog.md     README.md-tested-with:    GHC==8.0.2, GHC==8.2.2, GHC==8.4.3, GHC==8.6.1+tested-with:    GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.3  source-repository head   type: git@@ -36,23 +36,6 @@       Paths_free_algebras   hs-source-dirs:       src-  default-extensions:-      ConstraintKinds-      DataKinds-      DeriveFunctor-      EmptyDataDecls-      FlexibleInstances-      FlexibleContexts-      KindSignatures-      InstanceSigs-      MultiParamTypeClasses-      OverloadedStrings-      PolyKinds-      RankNTypes-      ScopedTypeVariables-      TupleSections-      TypeApplications-      TypeFamilies   build-depends:       base            >= 4.9 && <5     , constraints     >= 0.8 && <0.11.0 
src/Control/Algebra/Free.hs view
@@ -1,5 +1,14 @@ {-# LANGUAGE GADTs                      #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE InstanceSigs               #-}+{-# LANGUAGE PolyKinds                  #-}+{-# LANGUAGE RankNTypes                 #-}+{-# LANGUAGE ScopedTypeVariables        #-}+{-# LANGUAGE TypeFamilies               #-}++-- 'ListT' transformer is depreciated+{-# OPTIONS_GHC -Wno-deprecations       #-}+ module Control.Algebra.Free     ( -- Higher free algebra class       FreeAlgebra1 (..)
src/Control/Algebra/Free2.hs view
@@ -1,4 +1,7 @@ {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE PolyKinds           #-}+{-# LANGUAGE RankNTypes          #-}+ module Control.Algebra.Free2     ( FreeAlgebra2 (..)     , Proof (..)
src/Control/Monad/Action.hs view
@@ -1,5 +1,10 @@+{-# LANGUAGE DeriveFunctor              #-}+{-# LANGUAGE FlexibleInstances          #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE TypeFamilies               #-} {-# LANGUAGE UndecidableInstances       #-}+ module Control.Monad.Action where  import           Control.Monad (join)
src/Data/Algebra/Free.hs view
@@ -1,5 +1,14 @@-{-# LANGUAGE CPP   #-}-{-# LANGUAGE GADTs #-}+{-# LANGUAGE CPP                 #-}+{-# LANGUAGE ConstraintKinds     #-}+{-# LANGUAGE FlexibleInstances   #-}+{-# LANGUAGE GADTs               #-}+{-# LANGUAGE InstanceSigs        #-}+{-# LANGUAGE PolyKinds           #-}+{-# LANGUAGE RankNTypes          #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies        #-}+{-# LANGUAGE TypeApplications    #-}+ module Data.Algebra.Free     ( -- * Free algebra class       FreeAlgebra (..)
src/Data/Algebra/Pointed.hs view
@@ -1,5 +1,7 @@ {-# LANGUAGE CPP                  #-}+{-# LANGUAGE DeriveFunctor        #-} {-# LANGUAGE UndecidableInstances #-}+ module Data.Algebra.Pointed     ( Pointed (..)     , PointedMonoid (..)
src/Data/Group/Free.hs view
@@ -1,4 +1,6 @@-{-# LANGUAGE CPP #-}+{-# LANGUAGE CPP          #-}+{-# LANGUAGE TypeFamilies #-}+ {- |    Free groups @@ -13,6 +15,7 @@     , normalize      , FreeGroupL+    , consL     , fromList     , toList     , normalizeL@@ -59,31 +62,32 @@     FreeGroup as >>= f = FreeGroup $ as >>= runFreeGroup . either f f  -- |--- Normalize a list, i.e. remove adjusten inverses from a word, i.e.--- @ab⁻¹ba⁻¹c = c@+-- Normalize a @Dlist@, i.e. remove adjusten inverses from a word, i.e.+-- @ab⁻¹ba⁻¹c = c@.  Note that this function is implemented using+-- @'normalizeL'@, implemnting it directly on @DList@s would be @O(n^2)@+-- instead of @O(n)@. ----- Complexity: @O(n)@+-- /Complexity:/ @O(n)@ normalize     :: Eq a     => DList (Either a a)     -> DList (Either a a)-normalize = DList.foldr fn DList.empty-    where-    fn a as = case as of-        DList.Nil -> DList.singleton a-        _         ->-            let b  = DList.head as-                bs = DList.tail as-            in case (a, b) of-                (Left x,  Right y) | x == y -> bs-                (Right x, Left y)  | x == y -> bs-                _                           -> DList.cons a as+normalize = DList.fromList . normalizeL . DList.toList  -- |--- Smart constructor which normalizes a list.+-- Smart constructor which normalizes a dlist.+--+-- /Complexity:/ @O(n)@ fromDList :: Eq a => DList (Either a a) -> FreeGroup a-fromDList = FreeGroup . normalize+fromDList = freeGroupFromList . DList.toList +-- |+-- Construct a FreeGroup from a list.+--+-- /Complextiy:/ @O(n)@+freeGroupFromList :: Eq a => [Either a a] -> FreeGroup a+freeGroupFromList = FreeGroup . DList.fromList . normalizeL+ toDList :: FreeGroup a -> DList (Either a a) toDList = runFreeGroup @@ -113,20 +117,40 @@     forget = proof  -- |--- Free group in the class of groups which multiplication is strict on the left, i.e.+-- Free group in the class of groups which multiplication is strict on the+-- left, i.e. -- -- prop> undefined <> a = undefined newtype FreeGroupL a = FreeGroupL { runFreeGroupL :: [Either a a] }     deriving (Show, Eq, Ord) +-- | Like @'normalize'@ but for lists.+--+-- /Complexity:/ @O(n)@ normalizeL     :: Eq a     => [Either a a]     -> [Either a a]-normalizeL = DList.toList . normalize . DList.fromList+normalizeL = foldr consL_ [] +-- | Cons a generator (@'Right' x@) or its inverse (@'Left' x@) to the left+-- hand side of a 'FreeGroupL'.+--+-- /Complexity:/ @O(1)@+consL :: Eq a => Either a a -> FreeGroupL a -> FreeGroupL a+consL a (FreeGroupL as) = FreeGroupL (consL_ a as)++consL_ :: Eq a => Either a a -> [Either a a] -> [Either a a]+consL_ a [] = [a]+consL_ a as@(b:bs) = case (a, b) of+    (Left x,  Right y) | x == y -> bs+    (Right x, Left y)  | x == y -> bs+    _                           -> a : as+ -- |--- Smart constructors+-- Smart constructor which normalizes a list.+--+-- /Complexity:/ @O(n)@ fromList :: Eq a => [Either a a] -> FreeGroupL a fromList = FreeGroupL . normalizeL @@ -134,7 +158,7 @@ toList = runFreeGroupL  instance Eq a => Semigroup (FreeGroupL a) where-    FreeGroupL as <> FreeGroupL bs = FreeGroupL $ normalizeL (as ++ bs)+    FreeGroupL as <> FreeGroupL bs = FreeGroupL $ foldr consL_ bs as  instance Eq a => Monoid (FreeGroupL a) where     mempty = FreeGroupL []
src/Data/Monoid/Abelian.hs view
@@ -1,4 +1,6 @@-{-# LANGUAGE CPP #-}+{-# LANGUAGE CPP          #-}+{-# LANGUAGE TypeFamilies #-}+ module Data.Monoid.Abelian     ( FreeAbelianMonoid (..)     ) where
src/Data/Semigroup/Abelian.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE TypeFamilies #-}+ module Data.Semigroup.Abelian     ( AbelianSemigroup     , FreeAbelianSemigroup
src/Data/Semigroup/SemiLattice.hs view
@@ -1,4 +1,6 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE TypeFamilies               #-}+ module Data.Semigroup.SemiLattice     ( FreeSemiLattice     , fromNonEmpty
test/Test/Data/Group/Free.hs view
@@ -3,8 +3,8 @@     ( tests     ) where -import           Control.Monad (mapM) import           Data.Semigroup (Semigroup (..))+import           Data.Bool (bool) import           Data.Group (invert) import           Data.DList (DList) import qualified Data.DList as DList@@ -13,19 +13,16 @@ import qualified Hedgehog.Gen as Gen import qualified Hedgehog.Range as Range -import           Data.Group.Free (fromDList, normalize)+import           Data.Group.Free (fromDList, normalize, fromList, normalizeL) +genList :: Gen a -> Gen [Either a a]+genList gen =+    Gen.list (Range.linear 0 100) gen'+  where+    gen' = Gen.bool >>= bool (Right <$> gen) (Left <$> gen)+ genDList :: Gen a -> Gen (DList (Either a a))-genDList gen = do-    as <- Gen.list (Range.linear 0 100) gen-    DList.fromList <$> mapM-        (\a -> do-            b <- Gen.bool-            if b-            then return $ Right a-            else return $ Left a-        )-        as+genDList gen = DList.fromList <$> genList gen  prop_normalize :: Property prop_normalize = property $ do@@ -33,7 +30,7 @@      normalize (normalize as) === normalize as     normalize (as `DList.append` rev as) === DList.empty-    where+  where     rev :: DList (Either a a) -> DList (Either a a)     rev = DList.foldr (\a as -> DList.snoc as (either Right Left a)) DList.empty @@ -49,14 +46,47 @@ prop_unit = property $ do     fg <- fromDList <$> H.forAll (genDList Gen.bool) -    fg <> mempty       === fg-    mempty <> fg       === fg+    fg <> mempty === fg+    mempty <> fg === fg  prop_associativity :: Property prop_associativity = property $ do     fg   <- fromDList <$> H.forAll (genDList Gen.bool)     fg'  <- fromDList <$> H.forAll (genDList Gen.bool)     fg'' <- fromDList <$> H.forAll (genDList Gen.bool)++    (fg <> fg') <> fg'' === fg <> (fg' <> fg'')++prop_normalizeL :: Property+prop_normalizeL = property $ do+    as <- H.forAll (genList Gen.bool)++    normalizeL (normalizeL as) === normalizeL as+    normalizeL (as ++ rev as) === []+  where+    rev :: [Either a a] -> [Either a a]+    rev = foldl (\as a -> either Right Left a : as) []++prop_invertL :: Property+prop_invertL = property $ do+    fg <- fromList <$> H.forAll (genList Gen.bool)++    invert (invert fg) === fg+    invert fg <> fg    === mempty+    fg <> invert fg    === mempty++prop_unitL :: Property+prop_unitL = property $ do+    fg <- fromList <$> H.forAll (genList Gen.bool)++    fg <> mempty === fg+    mempty <> fg === fg++prop_associativityL :: Property+prop_associativityL = property $ do+    fg   <- fromList <$> H.forAll (genList Gen.bool)+    fg'  <- fromList <$> H.forAll (genList Gen.bool)+    fg'' <- fromList <$> H.forAll (genList Gen.bool)      (fg <> fg') <> fg'' === fg <> (fg' <> fg'')