packages feed

data-extend-generic (empty) → 0.1.0.0

raw patch · 6 files changed

+226/−0 lines, 6 filesdep +basedep +data-extend-genericdep +hspecsetup-changed

Dependencies added: base, data-extend-generic, hspec

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Author name here (c) 2015++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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ data-extend-generic.cabal view
@@ -0,0 +1,35 @@+name:                data-extend-generic+version:             0.1.0.0+synopsis:            Extend Haskell data or newtype like in OOP languages+description:         This package allows you to extend Haskell data or newtype like in OOP languages.+homepage:            http://github.com/githubuser/data-extend-generic#readme+license:             BSD3+license-file:        LICENSE+author:              Yu Li+maintainer:          ylilarry@gmail.com+copyright:           2010 Yu Li+category:            Data+build-type:          Simple+-- extra-source-files:+cabal-version:       >=1.10++library+  hs-source-dirs:      src+  exposed-modules:     Data.Extend+                     , Data.Extend.Internal+  build-depends:       base >= 4.7 && < 5+  default-language:    Haskell2010++test-suite data-extend-generic-test+  type:                exitcode-stdio-1.0+  hs-source-dirs:      test+  main-is:             Spec.hs+  build-depends:       base+                     , data-extend-generic+                     , hspec+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N+  default-language:    Haskell2010++source-repository head+  type:     git+  location: https://github.com/githubuser/data-extend-generic
+ src/Data/Extend.hs view
@@ -0,0 +1,44 @@+{-# LANGUAGE Safe #-}+----------------------------------------------------------------------------------+-- |+-- Module      : Data.Extend+-- Copyright   : (c) Yu Li, 2015+-- License     : BSD+-- Maintainer  : ylilarry@gmail.com+-- Stability   : experimental+-- Portability : GHC extensions+--+-- This package allows you to extend a Haskell data like how you do in OOP.+--+-- Here is an example use for testing:+--+-- >+-- > data Test = Test | TestA {+-- >       f1 :: Int,+-- >       f2 :: Maybe Int,+-- >       f3 :: Maybe Int+-- >    } deriving (Show, Generic, Eq)+-- >+-- > test1A = TestA 1 (Just 1) (Just 3)+-- > test2A = TestA 0 Nothing (Just 2)+-- >+-- > main :: IO ()+-- > main = hspec $+-- >    describe "Data.Extend" $ do+-- >       specify "Int" $+-- >          (2 `extend` 1) `shouldBe` (2 :: Int)+-- >       specify "String" $+-- >          ("b" `extend` "a") `shouldBe` "b"+-- >       specify "data 0" $+-- >          (Test `extend` Test) `shouldBe` Test+-- >       specify "data 1" $+-- >          (test2A `extend` test1A) `shouldBe` TestA 0 (Just 1) (Just 2)+-- >+--+----------------------------------------------------------------------------------++module Data.Extend (+      Extend(..)+   ) where++import Data.Extend.Internal
+ src/Data/Extend/Internal.hs view
@@ -0,0 +1,65 @@+{-# LANGUAGE Safe #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}++module Data.Extend.Internal where++import Control.Applicative+import GHC.Generics+++class GExtend a where+   gExtend :: a p -> a p -> a p+++instance (GExtend (K1 i (m a)), Alternative m, GExtend b) => GExtend (K1 i (m a) :*: b) where+   gExtend (K1 a1 :*: b1) (K1 a2 :*: b2) = K1 (a1 <|> a2) :*: gExtend b1 b2++instance GExtend U1 where+   gExtend _ _ = U1++instance (Extend a) => GExtend (K1 i a) where+   gExtend (K1 a) (K1 b) = K1 $ extend a b++instance (GExtend a, GExtend b) => GExtend (a :*: b) where+   gExtend (a1 :*: b1) (a2 :*: b2) = gExtend a1 a2 :*: gExtend b1 b2++instance (GExtend a, GExtend b) => GExtend (a :+: b) where+   gExtend (L1 a) (L1 b) = L1 $ gExtend a b+   gExtend (R1 a) (R1 b) = R1 $ gExtend a b+   gExtend a _ = a++instance (GExtend a) => GExtend (M1 i c a) where+   gExtend (M1 a) (M1 b) = M1 $ gExtend a b+++class Extend a where+   -- | By default+   --+   -- prop>  a `extend` b = a+   --+   -- prop> Nothing `extend` Just a = Just a+   --+   -- To use the "Extend" class, simply make your data derive Generic.+   --+   -- If "a" is a user defined data type, then all "Nothing" fields of "a" are replaced by corresponding fields in "b",+   --+   -- ie, all "Just" fields in "a" will override corresponding fields in "b".+   extend :: a -> a -> a+   default extend :: (Generic a, GExtend (Rep a)) => a -> a -> a+   extend a b = to $ gExtend (from a) (from b)+++instance (Extend a) => Extend (Maybe a) where+   -- | Nothing `extend` Just b = Just b+   -- (Just a) `extend` (Just b) = Just a+   extend (Just a) _ = Just a+   extend Nothing  b = b++instance {-# OVERLAPPABLE #-} Extend a where+   -- | By default a `extend` b is a+   extend a _ = a+
+ test/Spec.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE DeriveGeneric #-}++import Test.Hspec+import Data.Extend+import GHC.Generics+++data Test = Test | TestA {+      f1 :: Int,+      f2 :: Maybe Int,+      f3 :: Maybe Int+   } | TestB {+      g1 :: Int,+      g2 :: Maybe Int,+      g3 :: Maybe Int+   } deriving (Show, Generic, Eq)++test1A = TestA 1 (Just 1) Nothing+test2A = TestA 0 Nothing (Just 2)++test1B = TestB 1 (Just 1) Nothing+test2B = TestB 0 Nothing (Just 2)++++instance Extend Test++main :: IO ()+main = hspec $+   describe "Data.Extend" $ do+      specify "Int" $+         (2 `extend` 1) `shouldBe` (2 :: Int)+      specify "String" $+         ("b" `extend` "a") `shouldBe` "b"+      specify "data 0" $+         (Test `extend` Test) `shouldBe` Test+      specify "data 1" $+         (test2A `extend` test1A) `shouldBe` TestA 0 (Just 1) (Just 2)+      specify "data 2" $+         (test2B `extend` test1B) `shouldBe` TestB 0 (Just 1) (Just 2)+      specify "data 3" $+         (test2B `extend` test1A) `shouldBe` test2B+      specify "data 4" $+         (test1A `extend` test2B) `shouldBe` test1A+      specify "data 5" $+         (test2A `extend` test1B) `shouldBe` test2A+      specify "data 6" $+         (test1B `extend` test2A) `shouldBe` test1B++