packages feed

NonEmptyList (empty) → 0.0.1

raw patch · 4 files changed

+281/−0 lines, 4 filesdep +QuickCheckdep +basesetup-changed

Dependencies added: QuickCheck, base

Files

+ Data/List/NonEmpty.hs view
@@ -0,0 +1,226 @@+-- | A type-safe list that has at least one element.+module Data.List.NonEmpty(+                           NonEmpty,+                           -- * Accessors+                           neHead,+                           neTail,+                           -- * Constructors+                           nonEmpty,+                           (|:),+                           toNonEmpty,+                           unsafeToNonEmpty,+                           (.:),+                           (.++),+                           -- * List functions+                           reverse,+                           scanl,+                           scanl1,+                           scanr,+                           scanr1,+                           iterate,+                           repeat,+                           cycle,+                           inits,+                           tails,+                           sort,+                           insert,+                           zip,+                           unzip,                           +                           -- * Tests+                           prop_neHead,+                           prop_neTail,+                           prop_nonEmpty,+                           prop_nonEmptyAlias,+                           prop_toNonEmpty,+                           prop_unsafeNonEmpty,+                           prop_cons,+                           prop_append,+                           prop_reverse+                         ) where++import Control.Applicative+import Control.Monad+import Control.Arrow+import Data.Foldable+import Data.Maybe+import Data.Traversable+import qualified Data.List as L+import Prelude hiding (foldr, reverse, scanl, scanl1, scanr, scanr1, iterate, repeat, cycle, zip, unzip)+import Test.QuickCheck hiding (NonEmpty)++-- | An list with at least one element.+data NonEmpty a = NonEmpty {+  neHead :: a, -- ^ The head of the non-empty list.+  neTail :: [a] -- ^ The tail of the non-empty list.+} deriving (Eq, Ord)++instance Functor NonEmpty where+  fmap f (NonEmpty h t) = NonEmpty (f h) (fmap f t)++instance Applicative NonEmpty where+  pure = return+  (<*>) = ap++instance Monad NonEmpty where+  return = flip NonEmpty []+  NonEmpty h t >>= f = let NonEmpty a b = f h+                           k = t >>= toList . f+                       in NonEmpty a (b ++ k)++instance Foldable NonEmpty where+  foldr f x (NonEmpty h t) = foldr f x (h:t)+  foldl f x (NonEmpty h t) = foldl' f x (h:t)++instance Traversable NonEmpty where+  traverse f a = NonEmpty <$> head <*> tail <$> traverse f (toList a)++instance (Show a) => Show (NonEmpty a) where+  show (NonEmpty h t) = '|' : show (h:t) ++ "|"++-- | Constructs a non-empty list with the given head and tail.+nonEmpty :: a -- ^ The head.+            -> [a] -- ^ The tail.+            -> NonEmpty a+nonEmpty = NonEmpty++-- | Constructs a non-empty list with the given head and tail (an alias for @nonEmpty@).+(|:) :: a -- ^ The head.+        -> [a] -- ^ The tail.+        -> NonEmpty a+(|:) = nonEmpty++-- | Tries to convert a list to a @NonEmpty@ returning @Nothing@ if the given list is empty.+toNonEmpty :: [a] -- ^ The list to convert.+              -> Maybe (NonEmpty a)+toNonEmpty [] = Nothing+toNonEmpty (h:t) = Just (NonEmpty h t)++-- | /WARNING: Fails if given the empty list./+-- Tries to convert a list to a @NonEmpty@.+unsafeToNonEmpty :: [a] -- ^ The list to convert (must not be empty).+                    -> NonEmpty a+unsafeToNonEmpty = fromMaybe (error "unsafeToNonEmpty on empty list") . toNonEmpty++-- | Prepends a value to a non-empty list.+(.:) :: a -- ^ The value to prepend.+        -> NonEmpty a -- ^ The non-empty list to prepend to.+        -> NonEmpty a+a .: NonEmpty h t = NonEmpty a (h:t)++-- | Prepends a non-empty list to another non-empty list.+(.++) :: NonEmpty a -- ^ The non-empty list to prepend.+         -> NonEmpty a -- ^ The non-empty list to prepend to.+         -> NonEmpty a+NonEmpty a b .++ NonEmpty c d = NonEmpty a (b ++ c:d)++-- | Reverses the elements of the (finite) non-empty list.+reverse :: NonEmpty a+           -> NonEmpty a+reverse = list L.reverse++scanl :: (b -> a -> b)+         -> b+         -> NonEmpty a+         -> NonEmpty b+scanl = (list .) . L.scanl++scanl1 :: (a -> a -> a)+          -> NonEmpty a+          -> NonEmpty a+scanl1 = list . L.scanl1++scanr :: (a -> b -> b)+         -> b+         -> NonEmpty a+         -> NonEmpty b+scanr = (list .) . L.scanr++scanr1 :: (a -> a -> a)+          -> NonEmpty a+          -> NonEmpty a+scanr1 = list . L.scanr1++iterate :: (a -> a)+           -> a+           -> NonEmpty a+iterate = (unsafeToNonEmpty .) . L.iterate++repeat :: a+          -> NonEmpty a+repeat = unsafeToNonEmpty . L.repeat++cycle :: (Foldable f) =>+         f a+         -> NonEmpty a+cycle = list L.cycle++inits :: [a]+         -> NonEmpty [a]+inits = unsafeToNonEmpty . L.inits++tails :: [a]+         -> NonEmpty [a]+tails = unsafeToNonEmpty . L.tails++sort :: (Ord a) =>+        NonEmpty a+        -> NonEmpty a+sort = list L.sort++insert :: (Ord a) =>+          a ->+          NonEmpty a ->+          NonEmpty a+insert a = unsafeToNonEmpty . L.insert a . toList++zip :: NonEmpty a ->+       NonEmpty b ->+       NonEmpty (a, b)+zip a b = unsafeToNonEmpty (L.zip (toList a) (toList b))++unzip :: NonEmpty (a, b) ->+         (NonEmpty a, NonEmpty b)+unzip = (unsafeToNonEmpty *** unsafeToNonEmpty) . L.unzip . toList++-----------+-- TESTS --+-----------++instance (Arbitrary a) => Arbitrary (NonEmpty a) where+  arbitrary = nonEmpty <$> arbitrary <*> arbitrary+  shrink = (unsafeToNonEmpty <$>) . shrink . toList++prop_neHead :: String -> [String] -> Bool+prop_neHead h t = neHead (nonEmpty h t) == h++prop_neTail :: String -> [String] -> Bool+prop_neTail h t = neTail (nonEmpty h t) == t++prop_nonEmpty :: String -> [String] -> Bool+prop_nonEmpty h t = toList (nonEmpty h t) == h:t++prop_nonEmptyAlias :: String -> [String] -> Bool+prop_nonEmptyAlias h t = nonEmpty h t == h |: t++prop_toNonEmpty :: [String] -> Bool+prop_toNonEmpty x = toNonEmpty x == case x of [] -> Nothing+                                              (h:t) -> Just (nonEmpty h t)++prop_unsafeNonEmpty :: [String] -> Property+prop_unsafeNonEmpty x = not (null x) ==> prop_toNonEmpty x++prop_cons :: String -> NonEmpty String -> Bool+prop_cons a as = toList (a .: as) == a : toList as++prop_append :: NonEmpty String -> NonEmpty String -> Bool+prop_append a b = toList (a .++ b) == neHead a : neTail a ++ neHead b : neTail b++prop_reverse :: NonEmpty String -> Bool+prop_reverse x = (reverse . reverse) x == x++------------------+-- Not exported --+------------------++list :: (Foldable f) => ([a] -> [b]) -> f a -> NonEmpty b+list = (unsafeToNonEmpty .) . (. toList)
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright 2009 Tony Morris++All rights reserved.++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 REGENTS 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 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.
+ NonEmptyList.cabal view
@@ -0,0 +1,25 @@+Name:                NonEmptyList+Version:             0.0.1+License:             BSD3+License-File:        LICENSE+Synopsis:            A list with a length of at least one.+Description:         A list with a length of at least one and type-safe head/tail operations.+Homepage:            http://code.google.com/p/nonempty/+Category:            Data+Author:              Tony Morris, Oliver Taylor+Maintainer:          code@tmorris.net+Copyright:           2010 Tony Morris+build-type:          Simple+cabal-version:       >= 1.2++Flag small_base+  Description:     Choose the new, split-up base package.++Library+  if flag(small_base)+    Build-Depends: base < 5 && >= 3, QuickCheck >= 2+  else+    Build-Depends: base < 5 && >= 3, QuickCheck >= 2++  GHC-Options:    -Wall+  Exposed-Modules: Data.List.NonEmpty
+ Setup.lhs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain