| 1 | {-# LANGUAGE OverlappingInstances, UndecidableInstances, MultiParamTypeClasses, |
|---|
| 2 | FlexibleContexts #-} |
|---|
| 3 | {-# OPTIONS -Wall #-} |
|---|
| 4 | |
|---|
| 5 | ----------------------------------------------------------------------------- |
|---|
| 6 | -- | |
|---|
| 7 | -- Module : Happstack.Data.Default |
|---|
| 8 | -- Copyright : (c) 2009 Happstack.com; (c) 2007 HAppS LLC |
|---|
| 9 | -- License : BSD3 |
|---|
| 10 | -- |
|---|
| 11 | -- Maintainer : happs@googlegroups.com |
|---|
| 12 | -- Stability : experimental |
|---|
| 13 | -- Portability : Not portable |
|---|
| 14 | -- |
|---|
| 15 | -- Provides default values for Haskell datatypes. |
|---|
| 16 | -- |
|---|
| 17 | ----------------------------------------------------------------------------- |
|---|
| 18 | |
|---|
| 19 | module Default (Default(defaultValue)) where |
|---|
| 20 | |
|---|
| 21 | import qualified Data.ByteString.Char8 as BSC |
|---|
| 22 | import qualified Data.ByteString.Lazy.Char8 as BSLC |
|---|
| 23 | import qualified Data.Text as Text |
|---|
| 24 | import Data.Generics.SYB.WithClass.Basics |
|---|
| 25 | import Data.Generics.SYB.WithClass.Instances () |
|---|
| 26 | import Data.Int |
|---|
| 27 | import Data.Word |
|---|
| 28 | import qualified Data.Map as M |
|---|
| 29 | import qualified Data.Set as S |
|---|
| 30 | import Foreign.ForeignPtr |
|---|
| 31 | |
|---|
| 32 | -- | The 'Default' class provides a 'defaultValue' value, which |
|---|
| 33 | -- is the default value for that type. |
|---|
| 34 | -- |
|---|
| 35 | -- There is no instance for arbitrary types by default, but if you |
|---|
| 36 | -- declare an instance without providing the value then one will be |
|---|
| 37 | -- built using the first constructor. 'defaultValue' is used to provide |
|---|
| 38 | -- values for any arguments of the constructor. |
|---|
| 39 | -- |
|---|
| 40 | -- If you want an instance for all types then import |
|---|
| 41 | -- "Happstack.Data.Default.Generic". |
|---|
| 42 | class (Data DefaultD a) => Default a where |
|---|
| 43 | defaultValue :: a |
|---|
| 44 | defaultValue = defaultDefaultValue |
|---|
| 45 | |
|---|
| 46 | -- | This is the 'defaultValue' that is used in an instance if you don't |
|---|
| 47 | -- specify one. It may be a useful building block when writing your own |
|---|
| 48 | -- instances. |
|---|
| 49 | defaultDefaultValue :: (Data DefaultD a,Default a) => a |
|---|
| 50 | defaultDefaultValue = res |
|---|
| 51 | where res = case datarep $ dataTypeOf defaultProxy res of |
|---|
| 52 | AlgRep (c:_) -> |
|---|
| 53 | fromConstrB defaultProxy (defaultValueD dict) c |
|---|
| 54 | r -> |
|---|
| 55 | error ("defaultDefaultValue: Bad DataRep: " ++ show r) |
|---|
| 56 | |
|---|
| 57 | -- | When writing your own generic functions for 'Default' you may |
|---|
| 58 | -- need to access the class method through this datatype rather than |
|---|
| 59 | -- directly. |
|---|
| 60 | data DefaultD a = DefaultD { defaultValueD :: a } |
|---|
| 61 | |
|---|
| 62 | -- | When writing your own generic functions for 'Default' you may |
|---|
| 63 | -- need this, the proxy value. |
|---|
| 64 | defaultProxy :: Proxy DefaultD |
|---|
| 65 | defaultProxy = error "defaultProxy" |
|---|
| 66 | |
|---|
| 67 | instance Default t => Sat (DefaultD t) where |
|---|
| 68 | dict = DefaultD { defaultValueD = defaultValue } |
|---|
| 69 | |
|---|
| 70 | instance Default a => Default [a] where |
|---|
| 71 | defaultValue = [] |
|---|
| 72 | |
|---|
| 73 | instance Default Int where defaultValue = 0 |
|---|
| 74 | instance Default Int8 where defaultValue = 0 |
|---|
| 75 | instance Default Int16 where defaultValue = 0 |
|---|
| 76 | instance Default Int32 where defaultValue = 0 |
|---|
| 77 | instance Default Int64 where defaultValue = 0 |
|---|
| 78 | instance Default Word where defaultValue = 0 |
|---|
| 79 | instance Default Word8 where defaultValue = 0 |
|---|
| 80 | instance Default Word16 where defaultValue = 0 |
|---|
| 81 | instance Default Word32 where defaultValue = 0 |
|---|
| 82 | instance Default Word64 where defaultValue = 0 |
|---|
| 83 | instance Default Integer where defaultValue = 0 |
|---|
| 84 | instance Default Float where defaultValue = 0 |
|---|
| 85 | instance Default Double where defaultValue = 0 |
|---|
| 86 | |
|---|
| 87 | instance (Default a, Default b) => Default (Either a b) where |
|---|
| 88 | defaultValue = Left defaultValue |
|---|
| 89 | |
|---|
| 90 | instance Default () where |
|---|
| 91 | defaultValue = () |
|---|
| 92 | instance (Default a, Default b) => Default (a,b) where |
|---|
| 93 | defaultValue = (defaultValue, defaultValue) |
|---|
| 94 | instance (Default a, Default b, Default c) => Default (a,b,c) where |
|---|
| 95 | defaultValue = (defaultValue, defaultValue, defaultValue) |
|---|
| 96 | instance (Default a, Default b, Default c, Default d) => Default (a,b,c,d) where |
|---|
| 97 | defaultValue = (defaultValue, defaultValue, defaultValue, defaultValue) |
|---|
| 98 | |
|---|
| 99 | |
|---|
| 100 | instance Default Char where |
|---|
| 101 | defaultValue = 'A' |
|---|
| 102 | |
|---|
| 103 | instance Default a => Default (Maybe a) where |
|---|
| 104 | defaultValue = Nothing |
|---|
| 105 | |
|---|
| 106 | instance Default BSC.ByteString where |
|---|
| 107 | defaultValue = BSC.pack "" |
|---|
| 108 | |
|---|
| 109 | instance Default BSLC.ByteString where |
|---|
| 110 | defaultValue = BSLC.pack "" |
|---|
| 111 | |
|---|
| 112 | instance Default Text.Text where |
|---|
| 113 | defaultValue = Text.pack "" |
|---|
| 114 | |
|---|
| 115 | -- instance (Data DefaultD) T.Text |
|---|
| 116 | |
|---|
| 117 | -- We don't really want this instance, but we need it for the ByteString |
|---|
| 118 | -- instance |
|---|
| 119 | instance Default a => Default (ForeignPtr a) where |
|---|
| 120 | defaultValue = error "defaultValue: ForeignPtr" |
|---|
| 121 | |
|---|
| 122 | instance (Data DefaultD a, Data DefaultD b, Ord a) => Default (M.Map a b) |
|---|
| 123 | instance (Data DefaultD a, Ord a) => Default (S.Set a) |
|---|