Split effectful package (#27)

* Moved effectful library to a subdirectory

* Initial commit of the effectful-core library

* Removed tests/benchmarks/examples from effectful-core package

* Removed READMEs from packages

* Updated CI

* Refactored doctest script

This is a bit closer to the CI setup.

* Adjusted dependencies

* Updated README

* Updated the package descriptions

* Added examples to test suite
This commit is contained in:
Mann mit Hut 2021-07-25 15:18:35 +02:00 committed by GitHub
parent d4eb837a2d
commit f0bf1e49db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 258 additions and 69 deletions

View File

@ -1,6 +1,6 @@
# This GitHub workflow config has been generated by a script via
#
# haskell-ci 'github' '--config=cabal.haskell-ci' 'effectful.cabal'
# haskell-ci 'github' '--config=cabal.haskell-ci' 'cabal.project'
#
# To regenerate the script (for example after adjusting tested-with) run
#
@ -10,7 +10,7 @@
#
# version: 0.13.20210621
#
# REGENDATA ("0.13.20210621",["github","--config=cabal.haskell-ci","effectful.cabal"])
# REGENDATA ("0.13.20210621",["github","--config=cabal.haskell-ci","cabal.project"])
#
name: Haskell-CI
on:
@ -170,7 +170,8 @@ jobs:
- name: initial cabal.project for sdist
run: |
touch cabal.project
echo "packages: $GITHUB_WORKSPACE/source/." >> cabal.project
echo "packages: $GITHUB_WORKSPACE/source/effectful" >> cabal.project
echo "packages: $GITHUB_WORKSPACE/source/effectful-core" >> cabal.project
cat cabal.project
- name: sdist
run: |
@ -184,12 +185,17 @@ jobs:
run: |
PKGDIR_effectful="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/effectful-[0-9.]*')"
echo "PKGDIR_effectful=${PKGDIR_effectful}" >> "$GITHUB_ENV"
PKGDIR_effectful_core="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/effectful-core-[0-9.]*')"
echo "PKGDIR_effectful_core=${PKGDIR_effectful_core}" >> "$GITHUB_ENV"
rm -f cabal.project cabal.project.local
touch cabal.project
touch cabal.project.local
echo "packages: ${PKGDIR_effectful}" >> cabal.project
echo "packages: ${PKGDIR_effectful_core}" >> cabal.project
echo "package effectful" >> cabal.project
echo " ghc-options: -Werror=missing-methods" >> cabal.project
echo "package effectful-core" >> cabal.project
echo " ghc-options: -Werror=missing-methods" >> cabal.project
cat >> cabal.project <<EOF
package effectful
flags: +benchmark-foreign-libraries
@ -197,7 +203,7 @@ jobs:
if $HEADHACKAGE; then
echo "allow-newer: $($HCPKG list --simple-output | sed -E 's/([a-zA-Z-]+)-[0-9.]+/*:\1,/g')" >> cabal.project
fi
$HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: $_ installed\n" unless /^(effectful)$/; }' >> cabal.project.local
$HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: $_ installed\n" unless /^(effectful|effectful-core)$/; }' >> cabal.project.local
cat cabal.project
cat cabal.project.local
- name: dump install plan
@ -227,12 +233,14 @@ jobs:
run: |
if [ $((HCNUMVER < 90200)) -ne 0 ] ; then cd ${PKGDIR_effectful} || false ; fi
if [ $((HCNUMVER < 90200)) -ne 0 ] ; then doctest -XBangPatterns -XConstraintKinds -XDataKinds -XDeriveFunctor -XFlexibleContexts -XFlexibleInstances -XGADTs -XGeneralizedNewtypeDeriving -XLambdaCase -XMultiParamTypeClasses -XNoStarIsType -XRankNTypes -XRecordWildCards -XRoleAnnotations -XScopedTypeVariables -XStandaloneDeriving -XStrictData -XTupleSections -XTypeApplications -XTypeFamilies -XTypeOperators src ; fi
if [ $((HCNUMVER < 90200)) -ne 0 ] ; then cd ${PKGDIR_effectful} || false ; fi
if [ $((HCNUMVER < 90200)) -ne 0 ] ; then doctest -XBangPatterns -XConstraintKinds -XDataKinds -XDeriveFunctor -XFlexibleContexts -XFlexibleInstances -XGADTs -XGeneralizedNewtypeDeriving -XLambdaCase -XMultiParamTypeClasses -XNoStarIsType -XRankNTypes -XRecordWildCards -XRoleAnnotations -XScopedTypeVariables -XStandaloneDeriving -XStrictData -XTupleSections -XTypeApplications -XTypeFamilies -XTypeOperators utils ; fi
if [ $((HCNUMVER < 90200)) -ne 0 ] ; then cd ${PKGDIR_effectful_core} || false ; fi
if [ $((HCNUMVER < 90200)) -ne 0 ] ; then doctest -XBangPatterns -XConstraintKinds -XDataKinds -XDeriveFunctor -XFlexibleContexts -XFlexibleInstances -XGADTs -XGeneralizedNewtypeDeriving -XLambdaCase -XMultiParamTypeClasses -XNoStarIsType -XRankNTypes -XRecordWildCards -XRoleAnnotations -XScopedTypeVariables -XStandaloneDeriving -XStrictData -XTupleSections -XTypeApplications -XTypeFamilies -XTypeOperators src ; fi
- name: cabal check
run: |
cd ${PKGDIR_effectful} || false
${CABAL} -vnormal check
cd ${PKGDIR_effectful_core} || false
${CABAL} -vnormal check
- name: haddock
run: |
$CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all

View File

@ -100,11 +100,25 @@ to "boring" transformer stacks, most of which are a dozen of newtype'd `StateT`
or `ReaderT` transformers, each with a few associated operations (usually tied
to a type class), not to replace monad transformers altogether.
## Usage
The effect system and its effects are split among several libraries:
- The `effectful-core` library contains the main machinery of the effect system
itself and a few basic effects.
It aims for a small dependency footprint and provides the building blocks for
more advanced effects.
- _TBD_ `effectful-resource`, `effectful-process`, ...
- Finally, the `effectful` library which comes with 'batteries included'. It is
build on top of the other libraries and re-exports the functionality of those.
## Example
A `Filesystem` effect with two handlers, one that runs in `IO` and another that
uses an in-memory virtual file system can be found
[here](https://github.com/arybczak/effectful/blob/master/examples/FileSystem.hs).
[here](https://github.com/arybczak/effectful/blob/master/effectful/examples/FileSystem.hs).
## Resources

3
cabal.project Normal file
View File

@ -0,0 +1,3 @@
packages:
effectful/effectful.cabal
effectful-core/effectful-core.cabal

View File

@ -7,25 +7,35 @@
# - Compile doctest with the same GHC version the project currently uses.
#
doctest src \
-XBangPatterns \
-XConstraintKinds \
-XDataKinds \
-XDeriveFunctor \
-XFlexibleContexts \
-XFlexibleInstances \
-XGADTs \
-XGeneralizedNewtypeDeriving \
-XLambdaCase \
-XMultiParamTypeClasses \
-XNoStarIsType \
-XRankNTypes \
-XRecordWildCards \
-XRoleAnnotations \
-XScopedTypeVariables \
-XStandaloneDeriving \
-XStrictData \
-XTupleSections \
-XTypeApplications \
-XTypeFamilies \
-XTypeOperators
set -eu
run_doctest() {
pushd "${1}"
doctest \
"${2}" \
-XBangPatterns \
-XConstraintKinds \
-XDataKinds \
-XDeriveFunctor \
-XFlexibleContexts \
-XFlexibleInstances \
-XGADTs \
-XGeneralizedNewtypeDeriving \
-XLambdaCase \
-XMultiParamTypeClasses \
-XNoStarIsType \
-XRankNTypes \
-XRecordWildCards \
-XRoleAnnotations \
-XScopedTypeVariables \
-XStandaloneDeriving \
-XStrictData \
-XTupleSections \
-XTypeApplications \
-XTypeFamilies \
-XTypeOperators
popd
}
run_doctest effectful src
run_doctest effectful-core src

View File

@ -0,0 +1,2 @@
# effectful-core-0.0.0.0 (2021-06-13)
* Initial alpha release.

30
effectful-core/LICENSE Normal file
View File

@ -0,0 +1,30 @@
Copyright (c) 2021, Andrzej Rybczak
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Andrzej Rybczak nor the names of other
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,100 @@
cabal-version: 2.4
build-type: Simple
name: effectful-core
version: 0.0.0.0
license: BSD-3-Clause
license-file: LICENSE
category: Control
maintainer: andrzej@rybczak.net
author: Andrzej Rybczak
synopsis: An easy to use, performant extensible effects library.
description: An easy to use, performant extensible effects library with seamless
integration with the existing Haskell ecosystem.
.
This library provides the core of the effect system and is quiet
minimal. If you look for something more sophisticated have a look
at the @<https://hackage.haskell.org/package/effectful effectful>@
package.
extra-source-files: CHANGELOG.md
tested-with: GHC ==8.8.4 || ==8.10.4 || ==9.0.1 || ==9.2.0.20210422
bug-reports: https://github.com/arybczak/effectful/issues
source-repository head
type: git
location: https://github.com/arybczak/effectful.git
common language
ghc-options: -Wall -Wcompat
default-language: Haskell2010
default-extensions: BangPatterns
ConstraintKinds
DataKinds
DeriveFunctor
FlexibleContexts
FlexibleInstances
GADTs
GeneralizedNewtypeDeriving
LambdaCase
MultiParamTypeClasses
NoStarIsType
RankNTypes
RecordWildCards
RoleAnnotations
ScopedTypeVariables
StandaloneDeriving
StrictData
TupleSections
TypeApplications
TypeFamilies
TypeOperators
library effectful-internal-utils
import: language
build-depends: base
hs-source-dirs: utils
c-sources: utils/utils.c
exposed-modules: Effectful.Internal.Utils
library
import: language
ghc-options: -O2
build-depends: base >= 4.13 && <5
, containers
, effectful-internal-utils
, exceptions
, monad-control
, primitive
, transformers-base
, unliftio-core
hs-source-dirs: src
exposed-modules: Effectful.Error
Effectful.Error.Dynamic
Effectful.Fail
Effectful.Handler
Effectful.Internal.Effect
Effectful.Internal.Env
Effectful.Internal.Monad
Effectful.Internal.Unlift
Effectful.Monad
Effectful.Reader
Effectful.Reader.Dynamic
Effectful.State.Dynamic
Effectful.State.Local
Effectful.State.Shared
Effectful.Writer.Dynamic
Effectful.Writer.Local
Effectful.Writer.Shared
reexported-modules: Effectful.Internal.Utils

View File

@ -267,4 +267,3 @@ localLiftUnliftIO (LocalEnv les) strategy k = case strategy of
-- $setup
-- >>> import Control.Concurrent
-- >>> import Effectful

2
effectful/CHANGELOG.md Normal file
View File

@ -0,0 +1,2 @@
# effectful-0.0.0.0 (2021-06-13)
* Initial alpha release.

30
effectful/LICENSE Normal file
View File

@ -0,0 +1,30 @@
Copyright (c) 2021, Andrzej Rybczak
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Andrzej Rybczak nor the names of other
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -11,9 +11,13 @@ synopsis: An easy to use, performant extensible effects library.
description: An easy to use, performant extensible effects library with seamless
integration with the existing Haskell ecosystem.
.
This is the "batteries included" variant; See the
@<https://hackage.haskell.org/package/effectful-core effectful-core>@
package for the effect system itself as well as the various other
@effectful-*@ packages if you need a smaller dependency footprint.
extra-source-files: CHANGELOG.md
README.md
tested-with: GHC ==8.8.4 || ==8.10.4 || ==9.0.1 || ==9.2.0.20210422
@ -53,16 +57,6 @@ common language
TypeFamilies
TypeOperators
library effectful-internal-utils
import: language
build-depends: base
hs-source-dirs: utils
c-sources: utils/utils.c
exposed-modules: Effectful.Internal.Utils
library
import: language
@ -70,40 +64,34 @@ library
build-depends: base >= 4.13 && <5
, async
, containers
, effectful-internal-utils
, exceptions
, monad-control
, primitive
, effectful-core
, resourcet
, transformers-base
, unliftio-core
, unliftio
hs-source-dirs: src
exposed-modules: Effectful
Effectful.Async
Effectful.Error
Effectful.Error.Dynamic
Effectful.Fail
Effectful.Handler
Effectful.Internal.Effect
Effectful.Internal.Env
Effectful.Internal.Monad
Effectful.Internal.Unlift
Effectful.Monad
Effectful.Reader
Effectful.Reader.Dynamic
Effectful.Resource
Effectful.State.Dynamic
Effectful.State.Local
Effectful.State.Shared
Effectful.Writer.Dynamic
Effectful.Writer.Local
Effectful.Writer.Shared
reexported-modules: Effectful.Internal.Utils
reexported-modules: Effectful.Error
, Effectful.Error.Dynamic
, Effectful.Fail
, Effectful.Handler
, Effectful.Internal.Effect
, Effectful.Internal.Env
, Effectful.Internal.Monad
, Effectful.Internal.Unlift
, Effectful.Internal.Utils
, Effectful.Monad
, Effectful.Reader
, Effectful.Reader.Dynamic
, Effectful.State.Dynamic
, Effectful.State.Local
, Effectful.State.Shared
, Effectful.Writer.Dynamic
, Effectful.Writer.Local
, Effectful.Writer.Shared
test-suite test
import: language
@ -119,7 +107,7 @@ test-suite test
, tasty-hunit
, unliftio
hs-source-dirs: tests
hs-source-dirs: tests examples
type: exitcode-stdio-1.0
main-is: Main.hs
@ -129,6 +117,9 @@ test-suite test
ErrorTests
StateTests
Utils
-- These are examples; We do not actually run them but list
-- them here in order to check if they compile.
FileSystem
benchmark bench
import: language

View File

@ -44,7 +44,7 @@ runFileSystemIO
:: (IOE :> es, Error FsError :> es)
=> Eff (FileSystem : es) a
-> Eff es a
runFileSystemIO = interpret $ \case
runFileSystemIO = interpret $ \_ -> \case
ReadFile path -> adapt $ IO.readFile path
WriteFile path contents -> adapt $ IO.writeFile path contents
where
@ -55,7 +55,7 @@ runFileSystemPure
=> M.Map FilePath String
-> Eff (FileSystem : es) a
-> Eff es a
runFileSystemPure fs0 = reinterpret (evalState fs0) $ \case
runFileSystemPure fs0 = reinterpret (evalState fs0) $ \_ -> \case
ReadFile path -> gets (M.lookup path) >>= \case
Just contents -> pure contents
Nothing -> throwError . FsError $ "File not found: " ++ show path