packages feed

exotic-list-monads 1.1.1 → 1.2.0

raw patch · 6 files changed

+148/−17 lines, 6 files

Files

CHANGELOG.md view
@@ -1,24 +1,28 @@ # exotic-list-monad changelog +## v1.2.0++- Add the `AlphaNOmegaK` monad+ ## v1.1.1 -- Refactor to avoid the noncanonical-monad-instances and star-is-type warnings+- Refactor to avoid the `noncanonical-monad-instances` and `star-is-type` warnings -- Add Eq and Show instances to DualListMonad+- Add `Eq` and `Show` instances to `DualListMonad`  - Fixes in documentation  ## v1.1.0 -- Add the AtMost monad+- Add the `AtMost` monad -- Add the NumericalMonoidMonad monad+- Add the `NumericalMonoidMonad` monad -- Fixed the documentation to make Mini and Odd instances of NumericalMonoidMonad+- Fixed the documentation to make `Mini` and `Odd` instances of `NumericalMonoidMonad` -- Add AtLeast as another instance of NumericalMonoidMonad+- Add `AtLeast` as another instance of `NumericalMonoidMonad` -- Add the ContinuumOfMonads construction+- Add the `ContinuumOfMonads` construction  ## v1.0.1 
README.md view
@@ -8,7 +8,7 @@  * [Degrading Lists](https://raw.githubusercontent.com/maciejpirog/exotic-list-monads/master/degrading-lists.pdf) by Dylan McDermott, Maciej Piróg, Tarmo Uustalu (PPDP 2020), -* [Counting Monads on Lists](https://cla.tcs.uj.edu.pl/pdfs/McDermott-Pirog-Uustalu-Abstract.pdf) by Dylan McDermott, Maciej Piróg, Tarmo Uustalu (CLA 2023),+* [Counting Monads on Lists](http://cla.tcs.uj.edu.pl/history/2023/pdfs/McDermott-Pirog-Uustalu-Abstract.pdf) by Dylan McDermott, Maciej Piróg, Tarmo Uustalu (CLA 2023),  * [Hybrid Programs](http://alfa.di.uminho.pt/~nevrenato/pdfs/thesis.pdf) by Renato Neves (PhD Thesis, 2018). 
exotic-list-monads.cabal view
@@ -1,13 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.33.0.+-- This file has been generated from package.yaml by hpack version 0.37.0. -- -- see: https://github.com/sol/hpack------ hash: 5b5385de8f22ca1f51a19de7b8b393b9012fded676d9ea7412ac96fde7fc9d83  name:           exotic-list-monads-version:        1.1.1+version:        1.2.0 synopsis:       Non-standard monads on lists and non-empty lists description:    The usual list monad is only one of infinitely many ways to turn the list functor into a monad. The same applies to the usual non-empty list monad and the non-empty list functor. This library collects such non-standard "list" and "non-empty list" monads. category:       List, Monads@@ -15,11 +13,12 @@ bug-reports:    http://github.com/maciejpirog/exotic-list-monads/issues author:         Maciej Piróg <maciej.adam.pirog@gmial.com> maintainer:     Maciej Piróg <maciej.adam.pirog@gmail.com>-copyright:      (c) 2020 Dylan McDermott, Maciej Piróg, Tarmo Uustalu+copyright:      (c) 2020-2025 Dylan McDermott, Maciej Piróg, Tarmo Uustalu license:        MIT license-file:   LICENSE-tested-with:    GHC ==8.0.2 || ==8.2.2 || ==8.4.4 || ==8.6.5 || ==8.8.3 || ==8.10.1 build-type:     Simple+tested-with:+    GHC ==9.4.8 extra-source-files:     README.md     CHANGELOG.md
src/Control/Monad/List/Exotic.hs view
@@ -169,7 +169,6 @@   -- ** The Short Stutter-Keeper monad (?)    , ShortStutterKeeper(..)-   ) where  import Prelude hiding ((<>))
src/Control/Monad/List/NonEmpty/Exotic.hs view
@@ -13,8 +13,10 @@ {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE TypeOperators #-} {-# LANGUAGE OverloadedLists #-} + -- {-# LANGUAGE OverloadedStrings #-}  -- |@@ -144,6 +146,10 @@    , AlphaOmega(..) +  -- ** The ΑⁿΩᵏ monad (?)++  , AlphaNOmegaK(..)+   -- * Constructions on non-empty monads    -- ** The dual non-empty list monad@@ -172,7 +178,8 @@ import Control.Monad (ap, join) import Data.Kind (Type) import GHC.Exts (IsList(..), IsString(..), Constraint)-import GHC.TypeLits+-- import GHC.TypeLits+import GHC.TypeNats import Data.Proxy import qualified Data.Semigroup (Semigroup) import Control.Monad.List.Exotic (ListMonad, palindromize)@@ -863,6 +870,64 @@ instance IsString (AlphaOmega Char) where   fromString = fromList +-----------------------+-- The Α^n-Ω^k monad --+-----------------------++-- | A generalisation of the ΑΩ monad in which we replicate the first element+-- @n@ times and the last element @k@ times. It is a monad when @n + k >= 2@.+--+-- @+-- join xss | isSingle xss || nonEmptyAll isSingle xss+--          = nonEmptyConcat xss+--          | otherwise+--          = fromList $+--              replicate n (NonEmpty.head $ NonEmpty.head xss) +++--              replicate k (NonEmpty.last $ NonEmpty.last xss)+-- @+--+-- For example:+--+-- >>> toList $ unwrap (join ["John", "Paul", "George", "Ringo"] :: AlphaOmega 2 3 Char)+-- "JJooo"+-- >>> toList $ unwrap (join ["John", "Paul", "George", "Ringo"] :: AlphaOmega 0 6 Char)+-- "oooooo"+newtype AlphaNOmegaK (n :: Nat) (k :: Nat) a = AlphaNOmegaK { unAlphaNOmegaK :: NonEmpty a }+ deriving (Functor, Show, Eq)++instance (KnownNat n, KnownNat k, 2 <= n + k) => Applicative (AlphaNOmegaK n k) where+  pure a = AlphaNOmegaK [a]                         -- OverloadedLists+  (<*>)  = ap++instance (KnownNat n, KnownNat k, 2 <= n + k) => Monad (AlphaNOmegaK n k) where+  AlphaNOmegaK xs >>= f = AlphaNOmegaK $ join $ NonEmpty.map (unAlphaNOmegaK . f) xs+   where+    join xss | isSingle xss || nonEmptyAll isSingle xss+             = nonEmptyConcat xss+             | otherwise+             = let n = fromIntegral $ natVal (Proxy :: Proxy n)+                   k = fromIntegral $ natVal (Proxy :: Proxy k)+               in fromList $+                    replicate n (NonEmpty.head $ NonEmpty.head xss) +++                    replicate k (NonEmpty.last $ NonEmpty.last xss)++instance (KnownNat n, KnownNat k, 2 <= n + k) => IsNonEmpty (AlphaNOmegaK n k a) where+  type ItemNE (AlphaNOmegaK n k a) = a+  fromNonEmpty = AlphaNOmegaK+  toNonEmpty = unAlphaNOmegaK++instance (KnownNat n, KnownNat k, 2 <= n + k) => NonEmptyMonad (AlphaNOmegaK n k)++instance (KnownNat n, KnownNat k, 2 <= n + k) => IsList (AlphaNOmegaK n k a) where+  type Item (AlphaNOmegaK n k a) = a+  fromList = fromNonEmpty . fromList+  toList = toList . toNonEmpty++-- The following is needed for the examples in the docs:++instance (KnownNat n, KnownNat k, 2 <= n + k) => IsString (AlphaNOmegaK n k Char) where+  fromString = fromList+ ------------------------------- -- Dual non-empty list monad -- -------------------------------@@ -960,6 +1025,8 @@ -- | (?) instance HasShortFront AlphaOmega +instance (KnownNat n, KnownNat k, 2 <= n + k) => HasShortFront (AlphaNOmegaK n k)+ instance (HasShortRear m) => HasShortFront (DualNonEmptyMonad m)  -- | This is a transformer for a number of monads (instances of the@@ -1044,6 +1111,8 @@  -- | (?) instance HasShortRear AlphaOmega++instance (KnownNat n, KnownNat k, 2 <= n + k) => HasShortRear (AlphaNOmegaK n k)  instance (HasShortFront m) => HasShortRear (DualNonEmptyMonad m) 
test/Control/Monad/List/NonEmpty/ExoticSpec.hs view
@@ -45,6 +45,7 @@ deriving instance (Arbitrary a) => Arbitrary (HeadTails a) deriving instance (Arbitrary a) => Arbitrary (HeadsTail a) deriving instance (Arbitrary a) => Arbitrary (AlphaOmega a)+deriving instance (Arbitrary a) => Arbitrary (AlphaNOmegaK n k a) deriving instance (Arbitrary (m a)) => Arbitrary (ShortFront m 0 a) deriving instance (Arbitrary (m a)) => Arbitrary (ShortFront m 1 a) deriving instance (Arbitrary (m a)) => Arbitrary (ShortFront m 2 a)@@ -54,6 +55,9 @@ deriving instance (Arbitrary (m a)) => Arbitrary (ShortRear m 2 a) deriving instance (Arbitrary (m a)) => Arbitrary (ShortRear m 5 a) +assocTests :: Int+assocTests = 250+ testMonad :: forall m. (Monad m, Eq (m Int), Arbitrary (m Int),                         Arbitrary (m (m (m Int))),                         Show (m Int), Show (m (m (m Int))))@@ -64,7 +68,7 @@       \xs -> join (fmap return xs) == (xs :: m Int)     it "right unit:" $ property $       \xs -> join (return xs)      == (xs :: m Int)-    modifyMaxSuccess (const 100) $ it "associativity:" $ property $+    modifyMaxSuccess (const assocTests) $ it "associativity:" $ property $       \xsss -> join (join xsss)    == (join (fmap join xsss) :: m Int)  spec :: Spec@@ -138,6 +142,20 @@    testMonad "AlphaOmega" (Proxy :: Proxy AlphaOmega) +  testMonad "AlphaNOmegaK 1 1" (Proxy :: Proxy (AlphaNOmegaK 1 1))+  testMonad "AlphaNOmegaK 2 0" (Proxy :: Proxy (AlphaNOmegaK 2 0))+  testMonad "AlphaNOmegaK 0 2" (Proxy :: Proxy (AlphaNOmegaK 0 2))+  testMonad "AlphaNOmegaK 2 1" (Proxy :: Proxy (AlphaNOmegaK 2 1))+  testMonad "AlphaNOmegaK 1 2" (Proxy :: Proxy (AlphaNOmegaK 1 2))+  testMonad "AlphaNOmegaK 2 2" (Proxy :: Proxy (AlphaNOmegaK 2 2))+  testMonad "AlphaNOmegaK 3 1" (Proxy :: Proxy (AlphaNOmegaK 3 1))+  testMonad "AlphaNOmegaK 1 3" (Proxy :: Proxy (AlphaNOmegaK 1 3))+  testMonad "AlphaNOmegaK 3 2" (Proxy :: Proxy (AlphaNOmegaK 3 2))+  testMonad "AlphaNOmegaK 2 3" (Proxy :: Proxy (AlphaNOmegaK 2 3))+  testMonad "AlphaNOmegaK 3 3" (Proxy :: Proxy (AlphaNOmegaK 3 3))+  testMonad "AlphaNOmegaK 6 8" (Proxy :: Proxy (AlphaNOmegaK 6 8))+  testMonad "AlphaNOmegaK 9 3" (Proxy :: Proxy (AlphaNOmegaK 9 3))+   testMonad "ShortFront NonEmpty 0" (Proxy :: Proxy (ShortFront NonEmpty 0))   testMonad "ShortFront NonEmpty 1" (Proxy :: Proxy (ShortFront NonEmpty 1))   testMonad "ShortFront NonEmpty 2" (Proxy :: Proxy (ShortFront NonEmpty 2))@@ -183,6 +201,27 @@   testMonad "ShortFront AlphaOmega 2" (Proxy :: Proxy (ShortFront AlphaOmega 2))   testMonad "ShortFront AlphaOmega 5" (Proxy :: Proxy (ShortFront AlphaOmega 5)) +  testMonad "ShortFront (AlphaNOmegaK 1 1) 0" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 1 1) 0))+  testMonad "ShortFront (AlphaNOmegaK 1 1) 1" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 1 1) 1))+  testMonad "ShortFront (AlphaNOmegaK 1 1) 2" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 1 1) 2))+  testMonad "ShortFront (AlphaNOmegaK 1 1) 5" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 1 1) 5))+  testMonad "ShortFront (AlphaNOmegaK 2 0) 0" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 2 0) 0))+  testMonad "ShortFront (AlphaNOmegaK 2 0) 1" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 2 0) 1))+  testMonad "ShortFront (AlphaNOmegaK 2 0) 2" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 2 0) 2))+  testMonad "ShortFront (AlphaNOmegaK 2 0) 5" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 2 0) 5))+  testMonad "ShortFront (AlphaNOmegaK 0 2) 0" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 0 2) 0))+  testMonad "ShortFront (AlphaNOmegaK 0 2) 0" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 0 2) 0))+  testMonad "ShortFront (AlphaNOmegaK 0 2) 1" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 0 2) 1))+  testMonad "ShortFront (AlphaNOmegaK 0 2) 2" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 0 2) 2))+  testMonad "ShortFront (AlphaNOmegaK 2 3) 5" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 2 3) 5))+  testMonad "ShortFront (AlphaNOmegaK 2 3) 1" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 2 3) 1))+  testMonad "ShortFront (AlphaNOmegaK 2 3) 2" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 2 3) 2))+  testMonad "ShortFront (AlphaNOmegaK 2 3) 5" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 2 3) 5))+  testMonad "ShortFront (AlphaNOmegaK 12 3) 5" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 12 3) 5))+  testMonad "ShortFront (AlphaNOmegaK 12 3) 1" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 12 3) 1))+  testMonad "ShortFront (AlphaNOmegaK 12 3) 2" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 12 3) 2))+  testMonad "ShortFront (AlphaNOmegaK 12 3) 5" (Proxy :: Proxy (ShortFront (AlphaNOmegaK 12 3) 5))+   testMonad "ShortFront (DualNonEmptyMonad DiscreteHybridNE) 0" (Proxy :: Proxy (ShortFront (DualNonEmptyMonad DiscreteHybridNE) 0))   testMonad "ShortFront (DualNonEmptyMonad DiscreteHybridNE) 1" (Proxy :: Proxy (ShortFront (DualNonEmptyMonad DiscreteHybridNE) 1))   testMonad "ShortFront (DualNonEmptyMonad DiscreteHybridNE) 2" (Proxy :: Proxy (ShortFront (DualNonEmptyMonad DiscreteHybridNE) 2))@@ -202,6 +241,27 @@   testMonad "ShortRear AlphaOmega 1" (Proxy :: Proxy (ShortRear AlphaOmega 1))   testMonad "ShortRear AlphaOmega 2" (Proxy :: Proxy (ShortRear AlphaOmega 2))   testMonad "ShortRear AlphaOmega 5" (Proxy :: Proxy (ShortRear AlphaOmega 5))++  testMonad "ShortRear (AlphaNOmegaK 1 1) 0" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 1 1) 0))+  testMonad "ShortRear (AlphaNOmegaK 1 1) 1" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 1 1) 1))+  testMonad "ShortRear (AlphaNOmegaK 1 1) 2" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 1 1) 2))+  testMonad "ShortRear (AlphaNOmegaK 1 1) 5" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 1 1) 5))+  testMonad "ShortRear (AlphaNOmegaK 2 0) 0" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 2 0) 0))+  testMonad "ShortRear (AlphaNOmegaK 2 0) 1" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 2 0) 1))+  testMonad "ShortRear (AlphaNOmegaK 2 0) 2" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 2 0) 2))+  testMonad "ShortRear (AlphaNOmegaK 2 0) 5" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 2 0) 5))+  testMonad "ShortRear (AlphaNOmegaK 0 2) 0" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 0 2) 0))+  testMonad "ShortRear (AlphaNOmegaK 0 2) 0" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 0 2) 0))+  testMonad "ShortRear (AlphaNOmegaK 0 2) 1" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 0 2) 1))+  testMonad "ShortRear (AlphaNOmegaK 0 2) 2" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 0 2) 2))+  testMonad "ShortRear (AlphaNOmegaK 2 3) 5" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 2 3) 5))+  testMonad "ShortRear (AlphaNOmegaK 2 3) 1" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 2 3) 1))+  testMonad "ShortRear (AlphaNOmegaK 2 3) 2" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 2 3) 2))+  testMonad "ShortRear (AlphaNOmegaK 2 3) 5" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 2 3) 5))+  testMonad "ShortRear (AlphaNOmegaK 12 3) 5" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 12 3) 5))+  testMonad "ShortRear (AlphaNOmegaK 12 3) 1" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 12 3) 1))+  testMonad "ShortRear (AlphaNOmegaK 12 3) 2" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 12 3) 2))+  testMonad "ShortRear (AlphaNOmegaK 12 3) 5" (Proxy :: Proxy (ShortRear (AlphaNOmegaK 12 3) 5))    testMonad "ShortRear (DualNonEmptyMonad Keeper) 0" (Proxy :: Proxy (ShortRear (DualNonEmptyMonad Keeper) 0))   testMonad "ShortRear (DualNonEmptyMonad Keeper) 1" (Proxy :: Proxy (ShortRear (DualNonEmptyMonad Keeper) 1))