1+ {-# LANGUAGE MultiParamTypeClasses #-}
2+ {-# LANGUAGE AllowAmbiguousTypes #-}
3+ {-# LANGUAGE GHC2021#-}
4+
15{-|
26Module : Data.Default.Singletons
37Description : Provides singleton-based default values and optional types.
@@ -150,42 +154,69 @@ import Data.Singletons
150154import Data.String
151155import Prelude.Singletons ()
152156
157+ import qualified Data.Text as T
158+
153159{- |
154160`Opt`ional type with
155161either a `Def`ault promoted value @def@,
156162or `Some` specific `Demote`d value.
157163-}
158- data Opt (def :: k ) where
159- Def :: forall {k } def . SingDef def => Opt (def :: k )
160- Some :: forall {k } def . Demote k -> Opt (def :: k )
164+ data Opt (def :: k ) a where
165+ Def :: forall {k } def a . SingDef def a => Opt (def :: k ) a
166+ Some :: forall {k } def a . a -> Opt (def :: k ) a
161167
162168{- | Constraint required to `demote` @@def@. -}
163- type SingDef (def :: k ) = (SingI def , SingKind k )
169+ class SingKind k => SingDef (def :: k ) a where
170+ demoteDef :: a
171+
172+ instance {-# OVERLAPPABLE #-} (SingKind k , a ~ Demote k , SingI def )
173+ => SingDef (def :: k ) a where
174+ demoteDef = demote @ def
175+
176+ instance (KnownNat def , Num a )
177+ => SingDef (def :: Nat ) a where
178+ demoteDef = fromIntegral $ demote @ def
179+
180+ instance (SingI def , Num a )
181+ => SingDef (def :: Z ) a where
182+ demoteDef = fromIntegral $ demote @ def
183+
184+ instance (SingI def , Fractional a )
185+ => SingDef (def :: Q ) a where
186+ demoteDef = fromRational $ demote @ def
187+
188+ instance {-# OVERLAPPING #-} KnownSymbol def
189+ => SingDef (def :: Symbol ) T. Text where
190+ demoteDef = demote @ def
191+
192+ instance (IsString a , KnownSymbol def ) => SingDef (def :: Symbol ) a where
193+ demoteDef = fromString $ symbolVal (Proxy @ def )
194+
164195
165- instance Semigroup (Opt (def :: k )) where
196+ instance Semigroup (Opt (def :: k ) a ) where
166197 Def <> opt = opt
167198 Some x <> _ = Some x
168199
169- instance SingDef def => Monoid (Opt def ) where
200+ instance SingDef def a => Monoid (Opt def a ) where
170201 mempty = Def
171202
172- deriving instance (SingDef def , Show ( Demote k ) )
173- => Show (Opt (def :: k ))
203+ deriving instance (SingDef def a , Show a )
204+ => Show (Opt (def :: k ) a )
174205
175- deriving instance (SingDef def , Read ( Demote k ) )
176- => Read (Opt (def :: k ))
206+ deriving instance (SingDef def a , Read a )
207+ => Read (Opt (def :: k ) a )
177208
178- deriving instance (SingDef def , Eq ( Demote k ) )
179- => Eq (Opt (def :: k ))
209+ deriving instance (SingDef def a , Eq a )
210+ => Eq (Opt (def :: k ) a )
180211
181- deriving instance (SingDef def , Ord ( Demote k ) )
182- => Ord (Opt (def :: k ))
212+ deriving instance (SingDef def a , Ord a )
213+ => Ord (Opt (def :: k ) a )
183214
184- instance SingDef def
185- => Default (Opt (def :: k )) where def = Def
215+ instance SingDef def a
216+ => Default (Opt (def :: k ) a ) where def = Def
186217
187- instance Num ( Demote k )
188- => Num (Opt (def :: k )) where
218+ instance Num a
219+ => Num (Opt (def :: k ) a ) where
189220 x + y = Some $ definite x + definite y
190221 x * y = Some $ definite x * definite y
191222 abs x = Some $ abs (definite x)
@@ -194,19 +225,19 @@ instance Num (Demote k)
194225 negate x = Some $ negate (definite x)
195226 x - y = Some $ definite x - definite y
196227
197- instance Fractional ( Demote k )
198- => Fractional (Opt (def :: k )) where
228+ instance Fractional a
229+ => Fractional (Opt (def :: k ) a ) where
199230 recip x = Some $ recip (definite x)
200231 x / y = Some $ definite x / definite y
201232 fromRational x = Some $ fromRational x
202233
203- instance IsString ( Demote k )
204- => IsString (Opt (def :: k )) where
234+ instance IsString a
235+ => IsString (Opt (def :: k ) a ) where
205236 fromString x = Some $ fromString x
206237
207- instance IsList ( Demote k )
208- => IsList (Opt (def :: k )) where
209- type Item (Opt (def :: k )) = Item ( Demote k )
238+ instance IsList a
239+ => IsList (Opt (def :: k ) a ) where
240+ type Item (Opt (def :: k ) a ) = Item a
210241 fromList xs = Some $ fromList xs
211242 fromListN n xs = Some $ fromListN n xs
212243 toList x = toList $ definite x
@@ -222,19 +253,19 @@ and `Just` maps to `Some`.
222253"bar"
223254-}
224255optionally
225- :: forall {k } def . SingDef def
226- => Maybe ( Demote k )
227- -> Opt (def :: k )
256+ :: forall {k } def a . SingDef def a
257+ => Maybe a
258+ -> Opt (def :: k ) a
228259optionally = maybe Def Some
229260
230261{- |
231262Deconstructs an `Opt` to a `Demote`d value.
232263`Def` maps to `demote` @@def@,
233264and `Some` maps to its argument.
234265-}
235- definite :: forall {k } def . Opt (def :: k ) -> Demote k
266+ definite :: forall {k } def a . Opt (def :: k ) a -> a
236267definite = \ case
237- Def -> demote @ def
268+ Def -> demoteDef @ k @ def
238269 Some a -> a
239270
240271{- |
@@ -244,8 +275,8 @@ and `Some` maps to `pure`,
244275inverting `optionally`.
245276-}
246277perhaps
247- :: forall {k } def m . Alternative m
248- => Opt (def :: k ) -> m ( Demote k )
278+ :: forall {k } def a m . Alternative m
279+ => Opt (def :: k ) a -> m a
249280perhaps = \ case
250281 Def -> empty
251282 Some a -> pure a
0 commit comments