Skip to content

Commit e94607b

Browse files
committed
Opt for Num and Fractional types
1 parent 1fc8d58 commit e94607b

File tree

4 files changed

+67
-33
lines changed

4 files changed

+67
-33
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ cabal.project.local
2121
cabal.project.local~
2222
.HTF/
2323
.ghc.environment.*
24+
Makefile

package.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ dependencies:
1616
- data-default-class >= 0.1.2.0 && < 1
1717
- singletons >= 3.0.2 && < 3.1
1818
- singletons-base >= 3.1.1 && < 3.5
19+
- text >= 2 && < 2.2
1920
ghc-options:
2021
- -Wall
2122
- -Wcompat

singletons-default.cabal

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 2.2
22

3-
-- This file has been generated from package.yaml by hpack version 0.36.0.
3+
-- This file has been generated from package.yaml by hpack version 0.38.1.
44
--
55
-- see: https://github.com/sol/hpack
66

@@ -40,4 +40,5 @@ library
4040
, data-default-class >=0.1.2.0 && <1
4141
, singletons >=3.0.2 && <3.1
4242
, singletons-base >=3.1.1 && <3.5
43+
, text >=2 && <2.2
4344
default-language: Haskell2010

src/Data/Default/Singletons.hs

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
{-# LANGUAGE MultiParamTypeClasses #-}
2+
{-# LANGUAGE AllowAmbiguousTypes #-}
3+
{-# LANGUAGE GHC2021#-}
4+
15
{-|
26
Module : Data.Default.Singletons
37
Description : Provides singleton-based default values and optional types.
@@ -150,42 +154,69 @@ import Data.Singletons
150154
import Data.String
151155
import Prelude.Singletons ()
152156

157+
import qualified Data.Text as T
158+
153159
{- |
154160
`Opt`ional type with
155161
either a `Def`ault promoted value @def@,
156162
or `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
-}
224255
optionally
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
228259
optionally = maybe Def Some
229260

230261
{- |
231262
Deconstructs an `Opt` to a `Demote`d value.
232263
`Def` maps to `demote` @@def@,
233264
and `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
236267
definite = \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`,
244275
inverting `optionally`.
245276
-}
246277
perhaps
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
249280
perhaps = \case
250281
Def -> empty
251282
Some a -> pure a

0 commit comments

Comments
 (0)