free 5.1.6 → 5.1.7
raw patch · 12 files changed
+79/−52 lines, 12 filesdep ~template-haskelldep ~transformers-compatPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: template-haskell, transformers-compat
API changes (from Hackage documentation)
Files
- CHANGELOG.markdown +5/−0
- examples/Cabbage.lhs +17/−16
- examples/MandelbrotIter.lhs +1/−0
- examples/NewtonCoiter.lhs +8/−5
- examples/PerfTH.hs +6/−11
- examples/Teletype.lhs +3/−1
- examples/free-examples.cabal +14/−14
- free.cabal +7/−4
- src/Control/Comonad/Cofree/Class.hs +1/−1
- src/Control/Monad/Free.hs +8/−0
- src/Control/Monad/Free/Ap.hs +8/−0
- src/Control/Monad/Trans/Free/Church.hs +1/−0
CHANGELOG.markdown view
@@ -1,3 +1,8 @@+5.1.7 [2021.04.30]+------------------+* Enable `FlexibleContexts` in `Control.Monad.Trans.Free.Church` to allow+ building with GHC 9.2.+ 5.1.6 [2020.12.31] ------------------ * Explicitly mark modules as `Safe`.
examples/Cabbage.lhs view
@@ -1,7 +1,6 @@ > {-# LANGUAGE ViewPatterns #-} > module Cabbage where- -> import Control.Applicative+ > import Control.Monad > import Control.Monad.State > import Control.Monad.Trans.Iter@@ -9,23 +8,25 @@ > import Data.Functor.Identity > import Data.Maybe > import Data.Tuple-> import Data.List+> import Data.List (inits, tails)+> import Prelude ()+> import Prelude.Compat Consider the following problem: -A farmer must cross a river with a wolf, a sheep and a cabbage. -He owns a boat, which can only carry himself and one other item. +A farmer must cross a river with a wolf, a sheep and a cabbage.+He owns a boat, which can only carry himself and one other item. The sheep must not be left alone with the wolf, or with the cabbage:-if that happened, one of them would eat the other. +if that happened, one of them would eat the other. > data Item = Wolf | Sheep | Cabbage | Farmer deriving (Ord, Show, Eq)-> +> > eats :: Item -> Item -> Bool > Sheep `eats` Cabbage = True > Wolf `eats` Sheep = True > _ `eats` _ = False -The problem can be represented as the set of items on each side of the river. +The problem can be represented as the set of items on each side of the river. > type Situation = ([Item],[Item]) @@ -35,7 +36,7 @@ First, some helper functions to extract single elements from lists, leaving the rest intact: -> plusTailOf :: [a] -> [a] -> (Maybe a, [a]) +> plusTailOf :: [a] -> [a] -> (Maybe a, [a]) > a `plusTailOf` b = (listToMaybe b, a ++ drop 1 b) > singleOut1 :: (a -> Bool) -> [a] -> (Maybe a,[a])@@ -61,11 +62,11 @@ > move :: Situation -> [Situation] > move = move2-> where +> where > move2 (singleOut1 (== Farmer) -> (Just Farmer,as), bs) = move1 as bs > move2 (bs, singleOut1 (== Farmer) -> (Just Farmer,as)) = map swap $ move1 as bs > move2 _ = []-> +> > move1 as bs = [(as', [Farmer] ++ maybeToList b ++ bs) | > (b, as') <- singleOutAll as, > and [not $ x `eats` y | x <- as', y <- as']]@@ -74,15 +75,15 @@ *Cabbage> move initial [([Wolf,Cabbage],[Farmer,Sheep])] @- + When the starting side becomes empty, the farmer succeeds. > success :: Situation -> Bool > success ([],_) = True > success _ = False -A straightforward implementation to solve the problem could use the -list monad, trying all possible solutions and +A straightforward implementation to solve the problem could use the+list monad, trying all possible solutions and > solution1 :: Situation > solution1 = head $ solutions' initial@@ -96,8 +97,8 @@ To guarantee termination, we can use the 'Iter' monad with its MonadPlus instance. As long as one of the possible execution paths finds a solution, the program-will terminate: the solution is looked for _in breadth_. - +will terminate: the solution is looked for _in breadth_.+ > solution2 :: Iter Situation > solution2 = solution' initial > where
examples/MandelbrotIter.lhs view
@@ -3,6 +3,7 @@ For example: @ghc -o 'mandelbrot_iter' -O2 MandelbrotIter.lhs ; ./mandelbrot_iter@ > {-# LANGUAGE PackageImports #-}+> module Main where > import Control.Arrow hiding (loop) > import Control.Monad.Trans.Iter
examples/NewtonCoiter.lhs view
@@ -5,11 +5,13 @@ to find zeroes of a function is one such algorithm. > {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-}+> module Main where > import Control.Comonad.Trans.Coiter > import Control.Comonad.Env-> import Control.Applicative > import Data.Foldable (toList, find)+> import Prelude+> import Prelude.Compat () > data Function = Function { > -- Function to find zeroes of@@ -62,7 +64,8 @@ > estimateError :: Solution Double -> Result > estimateError s =-> let a:a':_ = toList s in+> let (a, s') = extract $ runCoiterT s in+> let a' = extract s' in > let f = asks function s in > Result { value = a, > xerror = abs $ a - a',@@ -75,9 +78,9 @@ > estimateOutlook :: Int -> Solution Result -> Outlook > estimateOutlook sampleSize solution = > let sample = map ferror $ take sampleSize $ tail $ toList solution in-> let result = extract solution in-> Outlook { result = result,-> progress = ferror result > minimum sample }+> let result' = extract solution in+> Outlook { result = result',+> progress = ferror result' > minimum sample } To compute the square root of @c@, we solve the equation @x*x - c = 0@. We will stop whenever the accuracy of the result doesn't improve in the next 5 steps.
examples/PerfTH.hs view
@@ -6,21 +6,15 @@ module Main where import System.CPUTime.Rdtsc-import System.IO import System.IO.Unsafe import Data.IORef import Data.Word import Control.Monad import Control.Monad.State.Strict-import Control.Monad.Fail (MonadFail)+import qualified Control.Monad.Fail as Fail (MonadFail) import Control.Monad.Free import Control.Monad.Free.TH import qualified Control.Monad.Free.Church as Church-import Control.Monad.IO.Class-import Control.Monad.Trans.Maybe-import Control.Category ((>>>))-import qualified Data.Foldable as F-import Text.Read.Compat (readMaybe) import Text.Printf -- | A data type representing basic commands for our performance-testing eDSL.@@ -57,7 +51,7 @@ runPerfFree :: (MonadIO m) => [String] -> Free PerfF () -> m () runPerfFree [] _ = return () runPerfFree (s:ss) x = case x of- Free (Output o next) -> do+ Free (Output _o next) -> do runPerfFree (s:ss) next Free (Input next) -> do g_print_time_since_prev_call@@ -66,12 +60,12 @@ return a -- | Church-based interpreter-runPerfF :: (MonadFail m, MonadIO m) => [String] -> Church.F PerfF () -> m ()+runPerfF :: (Fail.MonadFail m, MonadIO m) => [String] -> Church.F PerfF () -> m () runPerfF [] _ = return () runPerfF ss0 f = fst `liftM` do flip runStateT ss0 $ Church.iterM go f where- go (Output o next) = do+ go (Output _o next) = do next go (Input next) = do g_print_time_since_prev_call@@ -80,7 +74,8 @@ next (read s) -- | Test input is the same for all cases-test_input = [show i | i<-([1..9999] ++ [0])]+test_input :: [String]+test_input = [show i | i<-([1..9999] ++ [0 :: Int])] -- | Tail-recursive program test_tail :: (MonadFree PerfF m) => m ()
examples/Teletype.lhs view
@@ -1,11 +1,13 @@ > {-# LANGUAGE DeriveFunctor, TemplateHaskell, FlexibleContexts #-} --+> module Main where > import qualified Control.Exception as E (catch) > import Control.Monad (mfilter) > import Control.Monad.Loops (unfoldM) > import Control.Monad.Free (liftF, Free, iterM, MonadFree) > import Control.Monad.Free.TH (makeFree)-> import Control.Applicative ((<$>))+> import Prelude ()+> import Prelude.Compat > import System.IO (isEOF) > import System.IO.Error (ioeGetErrorString) > import System.Exit (exitSuccess)
examples/free-examples.cabal view
@@ -18,8 +18,9 @@ , GHC == 8.2.2 , GHC == 8.4.4 , GHC == 8.6.5- , GHC == 8.8.3- , GHC == 8.10.1+ , GHC == 8.8.4+ , GHC == 8.10.4+ , GHC == 9.0.1 synopsis: Monads for free description: Examples projects using @free@ build-type: Simple@@ -39,13 +40,11 @@ ghc-options: -Wall build-depends: base == 4.*,+ base-compat >= 0.6, free, mtl >= 2.0.1 && < 2.3, transformers >= 0.2 && < 0.6 --- This example depends on the HGL library which, unfortunately, fails to--- compile on GHC 8.4 or later. (See https://github.com/xpika/hgl/issues/3.)--- Build at your own risk. executable free-mandelbrot-iter if !flag(mandelbrot-iter) buildable: False@@ -56,7 +55,7 @@ build-depends: base == 4.*, free,- HGL,+ HGL >= 3.2.3.2, mtl >= 2.0.1 && < 2.3, transformers >= 0.2 && < 0.6 @@ -66,8 +65,9 @@ main-is: NewtonCoiter.lhs ghc-options: -Wall build-depends:- base == 4.*,- comonad >= 4 && < 6,+ base == 4.*,+ base-compat >= 0.6,+ comonad >= 4 && < 6, free executable free-perf-th@@ -77,7 +77,6 @@ ghc-options: -Wall build-depends: base == 4.*,- base-compat, fail == 4.9.*, free, mtl >= 2.0.1 && < 2.3,@@ -91,7 +90,7 @@ ghc-options: -Wall -fno-warn-orphans build-depends: base == 4.*,- base-compat,+ base-compat >= 0.6, fail == 4.9.*, free, transformers >= 0.2 && < 0.6,@@ -103,7 +102,8 @@ main-is: Teletype.lhs ghc-options: -Wall build-depends:- base == 4.*,+ base == 4.*,+ base-compat >= 0.6, free, monad-loops @@ -113,7 +113,7 @@ main-is: ValidationForm.hs ghc-options: -Wall build-depends:- base == 4.*,- base-compat,+ base == 4.*,+ base-compat >= 0.6, free,- mtl >= 2.0.1 && < 2.3+ mtl >= 2.0.1 && < 2.3
free.cabal view
@@ -1,6 +1,6 @@ name: free category: Control, Monads-version: 5.1.6+version: 5.1.7 license: BSD3 cabal-version: 1.18 license-file: LICENSE@@ -18,8 +18,9 @@ , GHC == 8.2.2 , GHC == 8.4.4 , GHC == 8.6.5- , GHC == 8.8.3- , GHC == 8.10.1+ , GHC == 8.8.4+ , GHC == 8.10.4+ , GHC == 9.0.1 synopsis: Monads for free description: Free monads are useful for many tree-like structures and domain specific languages.@@ -90,7 +91,7 @@ th-abstraction >= 0.4.2.0 && < 0.5, transformers >= 0.3 && < 0.6, transformers-base >= 0.4.5.2 && < 0.5,- template-haskell >= 2.7.0.0 && < 2.18+ template-haskell >= 2.7.0.0 && < 2.19 -- GHC-7.8 bundles transformers-0.3, -- mtl-2.2.* requires transformers >=0.4@@ -160,3 +161,5 @@ -- these flags may abort compilation with GHC-8.10 -- https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3295 ghc-options: -Winferred-safe-imports -Wmissing-safe-haskell-mode++ x-docspec-extra-packages: tagged
src/Control/Comonad/Cofree/Class.hs view
@@ -26,7 +26,7 @@ import Control.Comonad.Trans.Store import Control.Comonad.Trans.Traced import Control.Comonad.Trans.Identity-import Data.List.NonEmpty+import Data.List.NonEmpty (NonEmpty(..)) import Data.Tree #if __GLASGOW_HASKELL__ < 710 import Data.Monoid
src/Control/Monad/Free.hs view
@@ -71,6 +71,14 @@ import GHC.Generics #endif +-- $setup+-- >>> import Control.Applicative (Const (..))+-- >>> import Data.Functor.Identity (Identity (..))+-- >>> import Data.Monoid (First (..))+-- >>> import Data.Tagged (Tagged (..))+-- >>> let preview l x = getFirst (getConst (l (Const . First . Just) x))+-- >>> let review l x = runIdentity (unTagged (l (Tagged (Identity x))))+ -- | The 'Free' 'Monad' for a 'Functor' @f@. -- -- /Formally/
src/Control/Monad/Free/Ap.hs view
@@ -77,6 +77,14 @@ import GHC.Generics #endif +-- $setup+-- >>> import Control.Applicative (Const (..))+-- >>> import Data.Functor.Identity (Identity (..))+-- >>> import Data.Monoid (First (..))+-- >>> import Data.Tagged (Tagged (..))+-- >>> let preview l x = getFirst (getConst (l (Const . First . Just) x))+-- >>> let review l x = runIdentity (unTagged (l (Tagged (Identity x))))+ -- | A free monad given an applicative data Free f a = Pure a | Free (f (Free f a)) #if __GLASGOW_HASKELL__ >= 707
src/Control/Monad/Trans/Free/Church.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE RankNTypes #-}