nonempty-wrapper 0.1.0.0 → 0.1.1.0
raw patch · 7 files changed
+125/−15 lines, 7 filesdep +template-haskellPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: template-haskell
API changes (from Hackage documentation)
- Data.NonEmpty: ($sel:getNonEmpty:NonEmpty) :: NonEmpty a -> a
- Data.NonEmpty: type family NonEmptySingletonElement a :: Type;
+ Data.NonEmpty: getNonEmpty :: NonEmpty a -> a
+ Data.NonEmpty: type NonEmptySingletonElement a;
+ Data.NonEmpty.QQ: neString :: QuasiQuoter
+ Data.NonEmpty.QQ: trustedNonEmpty :: a -> NonEmpty a
+ Data.NonEmpty.TH: makeNonEmpty :: Q Exp -> Q Exp
+ Data.NonEmpty.TH: trustedNonEmpty :: a -> NonEmpty a
Files
- LICENSE +1/−1
- README.md +9/−0
- changelog.md +3/−0
- nonempty-wrapper.cabal +9/−3
- src/Data/NonEmpty.hs +11/−11
- src/Data/NonEmpty/QQ.hs +41/−0
- src/Data/NonEmpty/TH.hs +51/−0
LICENSE view
@@ -1,6 +1,6 @@ ISC License -Copyright (c) 2022 Gautier DI FOLCO+Copyright (c) 2022-2025 Gautier DI FOLCO Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above
+ README.md view
@@ -0,0 +1,9 @@+# nonempty-wrapper++Create NonEmpty version of any container.++## Example:++```+type NonEmptyText = NonEmpty Text+```
+ changelog.md view
@@ -0,0 +1,3 @@+# 0.1.1.0++* Add `Data.NonEmpty.QQ` and `Data.NonEmpty.TH`
nonempty-wrapper.cabal view
@@ -1,8 +1,11 @@ cabal-version: 3.0 name: nonempty-wrapper-version: 0.1.0.0+version: 0.1.1.0+extra-doc-files:+ README.md+ changelog.md author: Gautier DI FOLCO-maintainer: gautier.difolco@gmail.com+maintainer: foss@difolco.dev category: Data build-type: Simple license: ISC@@ -10,15 +13,18 @@ synopsis: Create NonEmpty version of any container description: Create NonEmpty version of any container. Homepage: http://github.com/blackheaven/nonempty-wrapper/nonempty-wrapper-tested-with: GHC==9.2.2, GHC==9.0.2, GHC==8.10.7+tested-with: GHC==9.12.1, GHC==9.10.2, GHC==9.8.4, GHC==9.6.7, GHC==9.4.8, GHC==9.2.8 library default-language: Haskell2010 build-depends: base == 4.*+ , template-haskell == 2.* hs-source-dirs: src exposed-modules: Data.NonEmpty+ Data.NonEmpty.QQ+ Data.NonEmpty.TH other-modules: Paths_nonempty_wrapper autogen-modules:
src/Data/NonEmpty.hs view
@@ -3,9 +3,9 @@ -- | -- Module : Data.NonEmpty -- Copyright : Gautier DI FOLCO--- License : BSD2+-- License : ISC ----- Maintainer : Gautier DI FOLCO <gautier.difolco@gmail.com>+-- Maintainer : Gautier DI FOLCO <foss@difolco.dev> -- Stability : Unstable -- Portability : GHC --@@ -39,8 +39,8 @@ ) where -import Data.Maybe(fromJust) import Data.Kind+import Data.Maybe (fromJust) import Data.Proxy -- | NonEmpty proofed value.@@ -50,20 +50,20 @@ } deriving stock (Eq, Ord, Show) -instance Semigroup a => Semigroup (NonEmpty a) where+instance (Semigroup a) => Semigroup (NonEmpty a) where NonEmpty x <> NonEmpty y = NonEmpty $ x <> y -- * Operations -- | Append empty container-(<|) :: Semigroup a => NonEmpty a -> a -> NonEmpty a+(<|) :: (Semigroup a) => NonEmpty a -> a -> NonEmpty a NonEmpty ne <| n = NonEmpty $ ne <> n {-# INLINE (<|) #-} infixr 6 <| -- | Prepend empty container-(|>) :: Semigroup a => a -> NonEmpty a -> NonEmpty a+(|>) :: (Semigroup a) => a -> NonEmpty a -> NonEmpty a n |> NonEmpty ne = NonEmpty $ n <> ne {-# INLINE (|>) #-} @@ -95,7 +95,7 @@ {-# INLINE overNonEmpty5 #-} -- | 'fmap' over a 'NonEmpty' container-fmapNonEmpty :: Functor f => (a -> b) -> NonEmpty (f a) -> NonEmpty (f b)+fmapNonEmpty :: (Functor f) => (a -> b) -> NonEmpty (f a) -> NonEmpty (f b) fmapNonEmpty f = overNonEmpty (fmap f) {-# INLINE fmapNonEmpty #-} @@ -115,7 +115,7 @@ nonEmptySingleton :: Proxy a -> NonEmptySingletonElement a -> a -- | Build a 'NonEmpty' value from a singleton value-singleton :: NonEmptySingleton a => Proxy a -> NonEmptySingletonElement a -> NonEmpty a+singleton :: (NonEmptySingleton a) => Proxy a -> NonEmptySingletonElement a -> NonEmpty a singleton p = trustedNonEmpty . nonEmptySingleton p {-# INLINE singleton #-} @@ -126,7 +126,7 @@ newtype MkNonEmptySingletonApplicative a = MkNonEmptySingletonApplicative a -instance Applicative f => NonEmptySingleton (f a) where+instance (Applicative f) => NonEmptySingleton (f a) where type NonEmptySingletonElement (f a) = a nonEmptySingleton _ = pure @@ -137,7 +137,7 @@ isNonEmpty :: a -> Bool -- | Attempt 'NonEmpty' proof-nonEmpty :: NonEmptyFromContainer a => a -> Maybe (NonEmpty a)+nonEmpty :: (NonEmptyFromContainer a) => a -> Maybe (NonEmpty a) nonEmpty x = if isNonEmpty x then Just $ trustedNonEmpty x@@ -150,5 +150,5 @@ newtype MkNonEmptyFromContainerFoldable a = MkNonEmptyFromContainerFoldable a -instance Foldable f => NonEmptyFromContainer (f a) where+instance (Foldable f) => NonEmptyFromContainer (f a) where isNonEmpty = not . null
+ src/Data/NonEmpty/QQ.hs view
@@ -0,0 +1,41 @@+-- |+-- Module : Data.NonEmpty.QQ+-- Copyright : Gautier DI FOLCO+-- License : ISC+--+-- Maintainer : Gautier DI FOLCO <foss@difolco.dev>+-- Stability : Unstable+-- Portability : GHC+--+-- Create NonEmpty values from quasi-quoting instead of unsafe functions.+--+-- Since @0.1.1.0@+module Data.NonEmpty.QQ+ ( neString,++ -- * Re-export+ trustedNonEmpty,+ )+where++import Data.NonEmpty+import Language.Haskell.TH+import Language.Haskell.TH.Quote++-- | Build a NonEmpty 'IsString' safely.+--+-- > [neString|something|]+--+-- Since @0.1.1.0@+neString :: QuasiQuoter+neString =+ QuasiQuoter+ { quoteExp =+ \input ->+ if null input+ then fail "Cannot build a non-enpty String from an empty input"+ else return $ AppE (VarE $ mkName "trustedNonEmpty") $ LitE $ StringL input,+ quotePat = const $ fail "neString is only supported on Expressions",+ quoteType = const $ fail "neString is only supported on Expressions",+ quoteDec = const $ fail "neString is only supported on Expressions"+ }
+ src/Data/NonEmpty/TH.hs view
@@ -0,0 +1,51 @@+{-# LANGUAGE CPP #-}+-- |+-- Module : Data.NonEmpty.TH+-- Copyright : Gautier DI FOLCO+-- License : ISC+--+-- Maintainer : Gautier DI FOLCO <foss@difolco.dev>+-- Stability : Unstable+-- Portability : GHC+--+-- Create NonEmpty values from TemplateHaskell instead of unsafe functions.+--+-- Since @0.1.1.0@+module Data.NonEmpty.TH+ ( makeNonEmpty,++ -- * Re-export+ trustedNonEmpty,+ )+where++import Control.Monad (when)+import Data.NonEmpty+import Language.Haskell.TH++-- | Build a NonEmpty safely.+--+-- Since @0.1.1.0@+--+-- > $(makeNonEmpty [|"Hello"|])+-- > $(makeNonEmpty [|[1, 2]|])+makeNonEmpty :: Q Exp -> Q Exp+makeNonEmpty eExp = do+ e <- eExp+ let ensureNonEmpty =+ \case+ LitE (StringL s) ->+ when (null s) $+ fail "Cannot build a non-enpty value from an empty string"+ ListE es ->+ when (null es) $+ fail "Cannot build a non-enpty value from an empty list"+ SigE e' _ -> ensureNonEmpty e'+#if MIN_VERSION_base(4,19,0)+ TypedBracketE e' -> ensureNonEmpty e'+ TypedSpliceE e' -> ensureNonEmpty e'+#endif+ e' -> fail $ "Unsupported expression type: " <> show e'++ ensureNonEmpty e+ return $ AppE (VarE $ mkName "trustedNonEmpty") e