strict-base (empty) → 0.4.0.0
raw patch · 11 files changed
+518/−0 lines, 11 filesdep +basedep +semigroupssetup-changed
Dependencies added: base, semigroups
Files
- LICENSE +26/−0
- Setup.hs +2/−0
- src/Data/Strict.hs +29/−0
- src/Data/Strict/Class.hs +28/−0
- src/Data/Strict/Either.hs +85/−0
- src/Data/Strict/List.hs +47/−0
- src/Data/Strict/List/NonEmpty.hs +50/−0
- src/Data/Strict/Maybe.hs +113/−0
- src/Data/Strict/Trustworthy.hs +6/−0
- src/Data/Strict/Tuple.hs +95/−0
- strict-base.cabal +37/−0
+ LICENSE view
@@ -0,0 +1,26 @@+Copyright (c) Daniel Mendler 2017, Roman Leshchinskiy 2006-2007++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++1. Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.+2. 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.+3. Neither the name of the author nor the names of his contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE 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 AUTHORS 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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Data/Strict.hs view
@@ -0,0 +1,29 @@+-----------------------------------------------------------------------------+-- |+-- Module : Data.Strict+-- Copyright : (c) 2017 Daniel Mendler, 2006-2007 Roman Leshchinskiy+-- License : BSD-style (see the file LICENSE)+--+-- Maintainer : Daniel Mendler <mail@daniel-mendler.de>+-- Stability : experimental+-- Portability : portable+--+-- Strict versions of some standard Haskell types.+--+-----------------------------------------------------------------------------++module Data.Strict (+ module Data.Strict.Class+ , module Data.Strict.Tuple+ , module Data.Strict.Maybe+ , module Data.Strict.Either+ , module Data.Strict.List+ , module Data.Strict.List.NonEmpty+) where++import Data.Strict.Class+import Data.Strict.Tuple+import Data.Strict.Maybe+import Data.Strict.Either+import Data.Strict.List+import Data.Strict.List.NonEmpty
+ src/Data/Strict/Class.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FunctionalDependencies #-}++-----------------------------------------------------------------------------+-- |+-- Module : Data.Strict.Class+-- Copyright : (c) 2017 Daniel Mendler+-- License : BSD-style (see the file LICENSE)+--+-- Maintainer : Daniel Mendler <mail@daniel-mendler.de>+-- Stability : experimental+-- Portability : portable+--+-- IsStrict isomorphism for conversion.+--+-----------------------------------------------------------------------------++module Data.Strict.Class (+ IsStrict(..),+ liftStrict+) where++class IsStrict l s | l -> s, s -> l where+ fromStrict :: s -> l+ toStrict :: l -> s++liftStrict :: IsStrict l s => (l -> l) -> (s -> s)+liftStrict f = toStrict . f . fromStrict
+ src/Data/Strict/Either.hs view
@@ -0,0 +1,85 @@+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-----------------------------------------------------------------------------+-- |+-- Module : Data.Strict.Either+-- Copyright : (c) 2017 Daniel Mendler, 2006-2007 Roman Leshchinskiy+-- License : BSD-style (see the file LICENSE)+--+-- Maintainer : Daniel Mendler <mail@daniel-mendler.de>+-- Stability : experimental+-- Portability : portable+--+-- Strict @Either@.+--+-- Same as the standard Haskell @Either@, but @Left _|_ = Right _|_ = _|_@+--+-----------------------------------------------------------------------------++module Data.Strict.Either (+ Either(..)+ , either+ , isLeft, isRight+ , lefts, rights+ , partitionEithers+) where++import qualified Data.Either as L+import Prelude hiding (Either(..), either)+import Data.Bifunctor (Bifunctor(..))+import GHC.Generics (Generic, Generic1)+import Data.Data (Data, Typeable)+import Data.Strict.Class++-- | The strict choice type.+data Either a b = Left !a | Right !b+ deriving (Eq, Ord, Read, Show, Functor, Traversable, Foldable, Generic, Generic1, Data, Typeable)++instance IsStrict (L.Either a b) (Either a b) where+ toStrict (L.Left x) = Left x+ toStrict (L.Right y) = Right y+ fromStrict (Left x) = L.Left x+ fromStrict (Right y) = L.Right y++instance Bifunctor Either where+ bimap f _ (Left a) = Left (f a)+ bimap _ g (Right a) = Right (g a)+ first f = either (Left . f) Right+ second g = either Left (Right . g)++-- | Case analysis: if the value is @'Left' a@, apply the first function to @a@;+-- if it is @'Right' b@, apply the second function to @b@.+either :: (a -> c) -> (b -> c) -> Either a b -> c+either f _ (Left x) = f x+either _ g (Right y) = g y++-- | Yields 'True' iff the argument is of the form @Left _@.+--+isLeft :: Either a b -> Bool+isLeft (Left _) = True+isLeft _ = False++-- | Yields 'True' iff the argument is of the form @Right _@.+--+isRight :: Either a b -> Bool+isRight (Right _) = True+isRight _ = False++-- | Analogous to 'L.lefts' in "Data.Either".+lefts :: [Either a b] -> [a]+lefts x = [a | Left a <- x]++-- | Analogous to 'L.rights' in "Data.Either".+rights :: [Either a b] -> [b]+rights x = [a | Right a <- x]++-- | Analogous to 'L.partitionEithers' in "Data.Either".+partitionEithers :: [Either a b] -> ([a],[b])+partitionEithers = foldr (either left right) ([], [])+ where left a ~(l, r) = (a:l, r)+ right a ~(l, r) = (l, a:r)
+ src/Data/Strict/List.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-----------------------------------------------------------------------------+-- |+-- Module : Data.Strict.List+-- Copyright : (c) 2017 Daniel Mendler+-- License : BSD-style (see the file LICENSE)+--+-- Maintainer : Daniel Mendler <mail@daniel-mendler.de>+-- Stability : experimental+-- Portability : portable+--+-- Strict @List@.+--+-- Same as the standard Haskell List, but strict.+--+-----------------------------------------------------------------------------++module Data.Strict.List (+ List(..)+) where++import GHC.Generics (Generic, Generic1)+import Data.Data (Data, Typeable)+import Data.Strict.Trustworthy+import Data.Strict.Class++infixr 5 :!++-- | The strict list type.+data List a = Nil | !a :! !(List a)+ deriving (Eq, Ord, Show, Read, Functor, Foldable, Traversable, Generic, Generic1, Data, Typeable)++instance IsStrict [a] (List a) where+ toStrict = foldr (:!) Nil+ fromStrict = foldr (:) []++instance IsList (List a) where+ type Item (List a) = a+ fromList = toStrict+ toList = fromStrict
+ src/Data/Strict/List/NonEmpty.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-----------------------------------------------------------------------------+-- |+-- Module : Data.Strict.List.NonEmpty+-- Copyright : (c) 2017 Daniel Mendler+-- License : BSD-style (see the file LICENSE)+--+-- Maintainer : Daniel Mendler <mail@daniel-mendler.de>+-- Stability : experimental+-- Portability : portable+--+-- Strict @NonEmpty@.+--+-- Same as the standard Haskell NonEmpty, but strict.+--+-----------------------------------------------------------------------------++module Data.Strict.List.NonEmpty (+ NonEmpty(..)+) where++import qualified Data.List.NonEmpty as L+import Data.Strict.List+import GHC.Generics (Generic, Generic1)+import Data.Data (Data, Typeable)+import Data.Strict.Trustworthy+import Data.Strict.Class++infixr 5 :|++-- | The strict list type.+data NonEmpty a = !a :| !(List a)+ deriving (Eq, Ord, Show, Read, Functor, Foldable, Traversable, Generic, Generic1, Data, Typeable)++instance IsStrict (L.NonEmpty a) (NonEmpty a) where+ toStrict (a L.:| as) = a :| toStrict as+ fromStrict (a :| as) = a L.:| fromStrict as++instance IsList (NonEmpty a) where+ type Item (NonEmpty a) = a+ fromList (a : as) = a :| fromList as+ fromList [] = error "NonEmpty.fromList: empty list"+ toList ~(a :| as) = a : toList as
+ src/Data/Strict/Maybe.hs view
@@ -0,0 +1,113 @@+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-----------------------------------------------------------------------------+-- |+-- Module : Data.Strict.Maybe+-- Copyright : (c) 2017 Daniel Mendler, 2006-2007 Roman Leshchinskiy+-- License : BSD-style (see the file LICENSE)+--+-- Maintainer : Daniel Mendler <mail@daniel-mendler.de>+-- Stability : experimental+-- Portability : portable+--+-- Strict @Maybe@.+--+-- Same as the standard Haskell @Maybe@, but @Just _|_ = _|_@+--+-- Note that strict @Maybe@ is not a monad since+-- @ return _|_ >>= f = _|_ @+-- which is not necessarily the same as @f _|_@.+--+-----------------------------------------------------------------------------++module Data.Strict.Maybe (+ Maybe(..)+ , isJust+ , isNothing+ , fromMaybe+ , maybe+ , listToMaybe+ , maybeToList+ , mapMaybe+ , catMaybes+) where++import qualified Data.Maybe as L+import Prelude hiding (Maybe(..), maybe)+import Data.Semigroup (Semigroup(..))+import GHC.Generics (Generic, Generic1)+import Data.Data (Data, Typeable)+import Data.Strict.Class++-- | The type of strict optional values.+data Maybe a = Nothing | Just !a+ deriving (Eq, Ord, Show, Read, Functor, Foldable, Traversable, Generic, Generic1, Data, Typeable)++instance IsStrict (L.Maybe a) (Maybe a) where+ toStrict L.Nothing = Nothing+ toStrict (L.Just x) = Just x+ fromStrict Nothing = L.Nothing+ fromStrict (Just x) = L.Just x++instance Semigroup a => Semigroup (Maybe a) where+ Nothing <> m = m+ m <> Nothing = m+ Just x1 <> Just x2 = Just (x1 <> x2)++instance Monoid a => Monoid (Maybe a) where+ mempty = Nothing+ Nothing `mappend` m = m+ m `mappend` Nothing = m+ Just x1 `mappend` Just x2 = Just (x1 `mappend` x2)++-- | Yields 'True' iff the argument is of the form @Just _@.+isJust :: Maybe a -> Bool+isJust Nothing = False+isJust _ = True++-- | Yields 'True' iff the argument is 'Nothing'.+isNothing :: Maybe a -> Bool+isNothing Nothing = True+isNothing _ = False++-- | Given a default value and a 'Maybe', yield the default value if the+-- 'Maybe' argument is 'Nothing' and extract the value out of the 'Just'+-- otherwise.+fromMaybe :: a -> Maybe a -> a+fromMaybe x Nothing = x+fromMaybe _ (Just y) = y++-- | Given a default value, a function and a 'Maybe' value, yields the default+-- value if the 'Maybe' value is 'Nothing' and applies the function to the+-- value stored in the 'Just' otherwise.+maybe :: b -> (a -> b) -> Maybe a -> b+maybe x _ Nothing = x+maybe _ f (Just y) = f y++-- | Analogous to 'L.listToMaybe' in "Data.Maybe".+listToMaybe :: [a] -> Maybe a+listToMaybe [] = Nothing+listToMaybe (a:_) = Just a++-- | Analogous to 'L.maybeToList' in "Data.Maybe".+maybeToList :: Maybe a -> [a]+maybeToList Nothing = []+maybeToList (Just x) = [x]++-- | Analogous to 'L.catMaybes' in "Data.Maybe".+catMaybes :: [Maybe a] -> [a]+catMaybes ls = [x | Just x <- ls]++-- | Analogous to 'L.mapMaybe' in "Data.Maybe".+mapMaybe :: (a -> Maybe b) -> [a] -> [b]+mapMaybe _ [] = []+mapMaybe f (x:xs) =+ case f x of+ Nothing -> rs+ Just r -> r:rs+ where rs = mapMaybe f xs
+ src/Data/Strict/Trustworthy.hs view
@@ -0,0 +1,6 @@+{-# LANGUAGE Trustworthy #-}+module Data.Strict.Trustworthy (+ IsList(..)+) where++import GHC.Exts (IsList(..))
+ src/Data/Strict/Tuple.hs view
@@ -0,0 +1,95 @@+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-----------------------------------------------------------------------------+-- |+-- Module : Data.Strict.Tuple+-- Copyright : (c) 2017 Daniel Mendler, 2006-2007 Roman Leshchinskiy+-- License : BSD-style (see the file LICENSE)+--+-- Maintainer : Daniel Mendler <mail@daniel-mendler.de>+-- Stability : experimental+-- Portability : portable+--+-- Strict pairs.+--+-- Same as regular Haskell pairs, but @(x :!: _|_) = (_|_ :!: y) = _|_@+--+-----------------------------------------------------------------------------++module Data.Strict.Tuple (+ Pair(..)+ , (:!:)+ , fst+ , snd+ , curry+ , uncurry+ , swap+ , zip+ , unzip+) where++import Prelude hiding (fst, snd, curry, uncurry, zip, unzip)+import Data.Semigroup(Semigroup(..))+import Data.Bifunctor (Bifunctor(..))+import Data.Ix (Ix)+import GHC.Generics (Generic, Generic1)+import Data.Data (Data, Typeable)+import Data.Strict.Class++infixl 2 :!:++-- | The type of strict pairs.+data Pair a b = !a :!: !b+ deriving (Eq, Ord, Show, Read, Bounded, Ix, Functor, Foldable, Traversable, Generic, Generic1, Data, Typeable)++-- This gives a nicer syntax for the type but only works in GHC for now.+type (:!:) = Pair++instance IsStrict (a, b) (Pair a b) where+ toStrict (a, b) = a :!: b+ fromStrict (a :!: b) = (a, b)++instance (Semigroup a, Semigroup b) => Semigroup (Pair a b) where+ (x1 :!: y1) <> (x2 :!: y2) = (x1 <> x2) :!: (y1 <> y2)++instance (Monoid a, Monoid b) => Monoid (Pair a b) where+ mempty = mempty :!: mempty+ (x1 :!: y1) `mappend` (x2 :!: y2) = (x1 `mappend` x2) :!: (y1 `mappend` y2)+instance Bifunctor Pair where+ bimap f g (a :!: b) = f a :!: g b+ first f (a :!: b) = f a :!: b+ second g (a :!: b) = a :!: g b++-- | Extract the first component of a strict pair.+fst :: Pair a b -> a+fst (x :!: _) = x++-- | Extract the second component of a strict pair.+snd :: Pair a b -> b+snd (_ :!: y) = y++-- | Curry a function on strict pairs.+curry :: (Pair a b -> c) -> a -> b -> c+curry f x y = f (x :!: y)++-- | Convert a curried function to a function on strict pairs.+uncurry :: (a -> b -> c) -> Pair a b -> c+uncurry f (x :!: y) = f x y++-- | Analagous to 'L.swap' from "Data.Tuple"+swap :: Pair a b -> Pair b a+swap (a :!: b) = b :!: a++-- | Zip for strict pairs (defined with zipWith).+zip :: [a] -> [b] -> [Pair a b]+zip = zipWith (:!:)++-- | Unzip for stict pairs into a (lazy) pair of lists.+unzip :: [Pair a b] -> ([a], [b])+unzip x = (map fst x, map snd x)
+ strict-base.cabal view
@@ -0,0 +1,37 @@+Name: strict-base+Version: 0.4.0.0+Synopsis: Strict versions of base data types.+Category: Data, System+Description: This package provides strict versions of some standard Haskell data+ types (Pairs, Maybe, Either, List and NonEmpty).+License: BSD3+License-File: LICENSE+Author: Daniel Mendler <mail@daniel-mendler.de>, Roman Leshchinskiy <rl@cse.unsw.edu.au>+Maintainer: Daniel Mendler <mail@daniel-mendler.de>+Copyright: (c) 2017 Daniel Mendler, 2006-2007 Roman Leshchinskiy+Homepage: https://github.com/minad/strict-base+Cabal-Version: >= 1.10+Build-type: Simple++source-repository head+ type: git+ location: https://github.com/minad/strict-base++library+ ghc-options: -Wall+ default-language: Haskell2010+ hs-source-dirs: src+ build-depends: base < 5+ if impl(ghc < 8.0)+ build-depends:+ semigroups >= 0.9 && < 1+ exposed-modules:+ Data.Strict.Tuple+ Data.Strict.Maybe+ Data.Strict.Either+ Data.Strict.Class+ Data.Strict.List+ Data.Strict.List.NonEmpty+ Data.Strict+ other-modules:+ Data.Strict.Trustworthy