concise (empty) → 0.1.0.0
raw patch · 6 files changed
+247/−0 lines, 6 filesdep +QuickCheckdep +basedep +bytestringsetup-changed
Dependencies added: QuickCheck, base, bytestring, concise, lens, quickcheck-instances, tasty, tasty-quickcheck, text
Files
- LICENSE +26/−0
- README.rst +7/−0
- Setup.hs +2/−0
- concise.cabal +52/−0
- src/Control/Lens/Cons/Extras.hs +106/−0
- test/Prop.hs +54/−0
+ LICENSE view
@@ -0,0 +1,26 @@+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.rst view
@@ -0,0 +1,7 @@+Utilities for ``Control.Lens.Cons``+===================================++This library provides a few utility types and functions for working+with ``Control.Lens.Cons``. Rewrite rules are employed to make+common conversions perform as well as the "native" but non-generic+conversion (e.g. ``String`` to ``Text``, lazy to strict, etc).
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ concise.cabal view
@@ -0,0 +1,52 @@+name: concise+version: 0.1.0.0+synopsis: Utilities for Control.Lens.Cons+description:+ concise provides a handful of functions to extend what you can+ do with Control.Lens.Cons.++homepage: https://github.com/frasertweedal/hs-concise+bug-reports: https://github.com/frasertweedal/hs-concise/issues+license: BSD3+license-file: LICENSE+author: Fraser Tweedale+maintainer: frase@frase.id.au+copyright: Copyright (C) 2016 Fraser Tweedale+category: Data, Lenses+build-type: Simple+extra-source-files: README.rst+cabal-version: >=1.10++source-repository head+ type: git+ location: https://github.com/frasertweedale/hs-concise++library+ hs-source-dirs: src+ default-language: Haskell2010+ ghc-options: -O2 -Wall+ exposed-modules:+ Control.Lens.Cons.Extras+ build-depends:+ base >= 4 && < 5+ , lens+ , text+ , bytestring++test-suite tests+ default-language: Haskell2010+ type: exitcode-stdio-1.0+ ghc-options: -O2 -threaded+ hs-source-dirs: test+ main-is: Prop.hs+ build-depends:+ base >= 4 && < 5+ , bytestring+ , lens+ , text+ , concise++ , tasty+ , tasty-quickcheck+ , QuickCheck+ , quickcheck-instances
+ src/Control/Lens/Cons/Extras.hs view
@@ -0,0 +1,106 @@+-- This file is part of hs-concise+-- Copyright (C) 2016 Fraser Tweedale+--+-- 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.++{-# LANGUAGE NoImplicitPrelude #-}++module Control.Lens.Cons.Extras+ (+ recons+ , unfoldr+ ) where++import Data.Function (id)+import Data.Maybe (Maybe)+import Data.String (String)+import Data.Word (Word8)++import Control.Lens+import Control.Lens ((#))+import Control.Lens.Cons (Cons, cons, uncons)+import Control.Lens.Empty (AsEmpty(..))+import Control.Lens.Fold (foldrOf, unfolded)++import Control.Lens.Iso (lazy, strict)+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as L+import Data.ByteString.Lens (packedBytes, unpackedBytes)+import qualified Data.Text as T+import Data.Text.Lens (packed, unpacked)+import qualified Data.Text.Lazy as TL++-- | Convert one type with a 'Cons' instance into the other.+--+-- Rewrite rules are provided for efficient conversion between+-- 'String' and 'Text', @['Word8']@ and 'ByteString', and lazy and+-- strict 'Text' and 'ByteString'. Programs must be compiled+-- with @-O@ to use them.+--+-- Although the type does not prove it, if @(recons . recons)@+-- exists it should obey:+--+-- > recons . recons ≡ id+--+{-# NOINLINE [2] recons #-}+recons :: (Cons s1 s1 a a, Cons s2 s2 a a, AsEmpty s2) => Getter s1 s2+recons = to (unfoldr uncons)++-- | > unfoldr f = foldrOf (unfolded f) cons (_Empty # ())+--+unfoldr :: (Cons s2 s2 a a, AsEmpty s2) => (s1 -> Maybe (a, s1)) -> s1 -> s2+unfoldr f = foldrOf (unfolded f) cons (_Empty # ())++{-# RULES+"recons/id"+ recons = id+"recons/string-text"+ recons = packed :: Getter String T.Text+"recons/text-string"+ recons = unpacked :: Getter T.Text String+"recons/string-lazytext"+ recons = packed :: Getter String TL.Text+"recons/lazytext-string"+ recons = unpacked :: Getter TL.Text String+"recons/text-strict"+ recons = strict :: Getter TL.Text T.Text+"recons/text-lazy"+ recons = lazy :: Getter T.Text TL.Text+"recons/list-bs"+ recons = packedBytes :: Getter [Word8] B.ByteString+"recons/bs-list"+ recons = unpackedBytes :: Getter B.ByteString [Word8]+"recons/list-lazybs"+ recons = packedBytes :: Getter [Word8] L.ByteString+"recons/lazybs-list"+ recons = unpackedBytes :: Getter L.ByteString [Word8]+"recons/bs-strict"+ recons = strict :: Getter L.ByteString B.ByteString+"recons/bs-lazy"+ recons = lazy :: Getter B.ByteString L.ByteString+ #-}
+ test/Prop.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}++{-# OPTIONS_GHC -ddump-rule-rewrites #-}++import Data.Word (Word8)++import Control.Lens (AsEmpty(..), Cons(..), prism, view)+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as L+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL++import Test.QuickCheck+import Test.QuickCheck.Instances ()+import Test.Tasty+import Test.Tasty.QuickCheck++import Control.Lens.Cons.Extras++main :: IO ()+main = defaultMain $ testGroup "Properties"+ [ testProperty "[a] -> [a]" (\s -> view recons (s :: String) == s)+ , testProperty "T -> T" (\s -> view recons (s :: T.Text) == s)+ , testProperty "TL -> TL" (\s -> view recons (s :: TL.Text) == s)+ , testProperty "B -> B" (\s -> view recons (s :: B.ByteString) == s)+ , testProperty "L -> L" (\s -> view recons (s :: L.ByteString) == s)+ , testProperty "Str -> T -> Str" (\s -> view recons (view recons (s :: String) :: T.Text) == s)+ , testProperty "Str -> TL -> Str" (\s -> view recons (view recons (s :: String) :: TL.Text) == s)+ , testProperty "T -> TL -> T" (\s -> view recons (view recons (s :: T.Text) :: TL.Text) == s)+ , testProperty "[W8] -> B -> [W8]" (\s -> view recons (view recons (s :: [Word8]) :: B.ByteString) == s)+ , testProperty "[W8] -> L -> [W8]" (\s -> view recons (view recons (s :: [Word8]) :: L.ByteString) == s)+ , testProperty "B -> L -> B" (\s -> view recons (view recons (s :: B.ByteString) :: L.ByteString) == s)+ , testProperty "[a] -> List a -> [a]" (\s -> view recons (view recons (s :: [Int]) :: List Int) == s)+ ]++-- Let's implement a type *without* rewrite rules to ensure that the+-- default implementation is correct+--+data List a = Nil | Cons a (List a)+ deriving (Eq)++instance AsEmpty (List a) where+ _Empty = prism (const Nil) f+ where+ f Nil = Right ()+ f xs = Left xs++instance Cons (List a) (List b) a b where+ _Cons = prism (uncurry Cons) f+ where+ f Nil = Left Nil+ f (Cons x xs) = Right (x, xs)