trek (empty) → 0.0.1.0
raw patch · 7 files changed
+255/−0 lines, 7 filesdep +basedep +logictdep +mtlsetup-changed
Dependencies added: base, logict, mtl, trek
Files
- ChangeLog.md +3/−0
- LICENSE +30/−0
- README.md +21/−0
- Setup.hs +2/−0
- src/Trek.hs +143/−0
- test/Spec.hs +2/−0
- trek.cabal +54/−0
+ ChangeLog.md view
@@ -0,0 +1,3 @@+# Changelog for opticus-prime++## Unreleased changes
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Author name here (c) 2020++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 Author name here 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.
+ README.md view
@@ -0,0 +1,21 @@+# Trek++Provides a generic monadic interface for diving through and updating arbitrary structures.++It takes inspiration from:++* [jq](https://stedolan.github.io/jq/manual/)+* [meander](https://github.com/noprompt/meander)+* [XQuery](https://en.wikipedia.org/wiki/XQuery)++## Elevator Pitch++Trek allows you to dive down into nested structures while keeping handles on relevant bits as you go.++You can then transform the structure, collect results, etc.++Trek implicitly handles the idea of missing or multiple values for you, meaning you can write your collections or transformations declaratively.++## `trek-lens`++There's an extension to trek: `trek-lens` which I highly recommend using. It provides the `focusing` combinator which gives Trek a LOT more power. Trek is meant to be used alongside optics.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Trek.hs view
@@ -0,0 +1,143 @@+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE DerivingVia #-}+module Trek+ (++ -- * Types+ TrekT(..)+ , Trek++ -- * Combinators+ , select+ , selectEach+ , iter+ , collect+ , mount+ , mountEach+ , with+ , withEach++ -- * Running Trek+ , evalTrek+ , evalTrekT+ , execTrek+ , execTrekT+ , runTrek+ , runTrekT++ -- * Re-Exports+ , get+ , gets+ , put+ , modify+ , ask+ , asks+ ) where++import Control.Applicative+import Control.Monad.Fail+import Control.Monad.Identity+import Control.Monad.Logic+import Control.Monad.Reader+import Control.Monad.State+import Data.Foldable+import Data.Functor.Identity+import Data.Monoid++-- | Pure Trek Monad+type Trek s a = TrekT s Identity a++-- | The Trek Monad Transformer.+-- Implements both MonadReader and MonadState.+newtype TrekT s m a = TrekT (LogicT (StateT s m) a)+ deriving newtype (Functor, Applicative, Monad, MonadState s, Alternative, MonadFail)+ deriving (Semigroup, Monoid) via Ap (LogicT (StateT s m)) a++instance MonadTrans (TrekT s) where+ lift m = TrekT (lift . lift $ m)++instance (Monad m) => MonadReader s (TrekT s m) where+ ask = get+ local f m = do+ s <- get+ modify f+ a <- m+ put s+ pure a+++-- | Get a value from your state+select :: Monad m => (s -> a) -> TrekT s m a+select getter = gets getter++-- | Iterate over several values from your state. An alias for @'select' >=> 'iter'@+selectEach :: (Monad m, Foldable f) => (s -> f a) -> TrekT s m a+selectEach getter = select getter >>= iter++-- | Iterate over each of the provided values one at a time.+iter :: Foldable f => f a -> TrekT s m a+iter = asum . fmap pure . toList++-- | Run a full 'TrekT' block collecting all results into a list+collect :: Monad m => TrekT s m a -> TrekT s m [a]+collect trek = do+ s <- get+ lift . fmap fst $ runTrekT trek s++-- | Run a 'TrekT' block over a portion of state. All state changes from the block are+-- discarded.+mount :: Monad m => (t -> s) -> TrekT s m a -> TrekT t m a+mount f trek = do+ s <- select f+ with s trek++-- | Like 'mount' but focuses each of a list of values one at a time.+-- All state changes from the block are discarded.+mountEach :: (Monad m, Foldable f) => (t -> f s) -> TrekT s m a -> TrekT t m a+mountEach f trek = do+ s <- selectEach f+ with s trek++-- | Run a 'TrekT' block over a piece of state.+-- All state changes from the block are discarded.+with :: Monad m => s -> TrekT s m a -> TrekT t m a+with s = mount (const s)++-- | Like 'with' but focuses each of a list of values one at a time.+-- All state changes from the block are discarded.+withEach :: (Monad m, Foldable f) => f s -> TrekT s m a -> TrekT t m a+withEach xs trek =+ iter xs >>= flip with trek++-- | Evaluate the results of a 'Trek'.+evalTrek :: Trek s a -> s -> [a]+evalTrek t s = runIdentity $ evalTrekT t s++-- | Evaluate the results of a 'TrekT'.+evalTrekT :: Monad m => TrekT s m a -> s -> m [a]+evalTrekT t s = fst <$> runTrekT t s++-- | Return the altered state after running a 'Trek'.+execTrek :: Trek s a -> s -> s+execTrek t s = runIdentity $ execTrekT t s++-- | Return the altered state after running a 'TrekT'.+execTrekT :: Monad m => TrekT s m a -> s -> m s+execTrekT t s = snd <$> runTrekT t s++-- | Run a 'Trek'+runTrek :: Trek s a -> s -> ([a], s)+runTrek t s = runIdentity $ runTrekT t s++-- | Run a 'TrekT'+runTrekT :: Monad m => TrekT s m a -> s -> m ([a], s)+runTrekT (TrekT m) s = flip runStateT s $ observeAllT m
+ test/Spec.hs view
@@ -0,0 +1,2 @@+main :: IO ()+main = putStrLn "Test suite not yet implemented"
+ trek.cabal view
@@ -0,0 +1,54 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.33.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: 6c8c0450d245d5ee31c6c3de323a2d8755a133416129451b6f29266dded9f7d9++name: trek+version: 0.0.1.0+description: Please see the README on GitHub at <https://github.com/githubuser/trek#readme>+homepage: https://github.com/githubuser/trek#readme+bug-reports: https://github.com/githubuser/trek/issues+author: Author name here+maintainer: example@example.com+copyright: 2020 Author name here+license: BSD3+license-file: LICENSE+build-type: Simple+extra-source-files:+ README.md+ ChangeLog.md++source-repository head+ type: git+ location: https://github.com/githubuser/trek++library+ exposed-modules:+ Trek+ other-modules:+ Paths_trek+ hs-source-dirs:+ src+ build-depends:+ base >=4.7 && <5+ , logict+ , mtl+ default-language: Haskell2010++test-suite trek-test+ type: exitcode-stdio-1.0+ main-is: Spec.hs+ other-modules:+ Paths_trek+ hs-source-dirs:+ test+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ build-depends:+ base >=4.7 && <5+ , logict+ , mtl+ , trek+ default-language: Haskell2010