| Safe Haskell | Safe-Inferred |
|---|---|
| Language | Haskell2010 |
SomeDictOf
Contents
Synopsis
- type SomeDict = SomeDictOf Proxy
- data SomeDictOf (f :: k -> Type) (c :: k -> Constraint) where
- SomeDictOf :: c a => f a -> SomeDictOf f c
- someDict :: forall a c. c a => SomeDict c
- fromDict :: forall a c. Dict (c a) -> SomeDict c
- withSomeDictOf :: SomeDictOf f c -> (forall a. c a => f a -> r) -> r
- mapSomeDictOf :: (forall a. c a => f a -> g a) -> SomeDictOf f c -> SomeDictOf g c
- forgetContents :: forall f c. Functor f => SomeDictOf f c -> f (SomeDictOf Proxy c)
- module Data.Functor.Identity
- module Data.Proxy
- module Data.Constraint
Documentation
type SomeDict = SomeDictOf Proxy Source #
In the case where you only need evidence that the dictionary exists,
then you can use this type. By carrying a Proxy instead of a real
value, we can summon these up whenever we have an instance of the type in
question.
This is useful when you have a type class that specifies some *static*
behavior that is useful, or a type class that can provide means of
creatingretrievingworking with data. Consider the PersistEntity class
from the persistent database library. An instance of that class can be used
to get the EntityDef that describes how the type interacts with the
database, or you can even selectList and grab all entities out of the
database.
someEntity :: SomeDict PersistEntity
someEntity = someDict @User
With this value, we can now extract the EntityDef:
someEntityDef :: EntityDef
someEntityDef =
case someEntity of
SomeDictOf (Proxy :: Proxy a) ->
entityDef (Proxy :: Proxy a)
We can also load all the rows out of the database.
verifyRowsCanLoad :: SqlPersistT IO ()
verifyRowsCanLoad =
case someEntity of
SomeDictOf (Proxy :: Proxy a) -> do
rows <- selectList [] [] :: SqlPersistT IO [Entity a]
mapM_ (print . entityKey) rows
Since: 0.1.0.0
data SomeDictOf (f :: k -> Type) (c :: k -> Constraint) where Source #
A datatype that carries evidence of type class membership for some type, along with a datatype indexed by that type. This is confusing, so let's look at some examples.
The alias uses SomeDict clazzProxy for the datatype index. This means
that the wrapper is a , and you know that the type
Proxy :: Proxy aa has an instance of clazz a. The SomeDictOf type does not actually
*carry* any values of this type.
That is not to say that we *necessarily* won't have a value - consider
, which actually does hold a value. We can use this
to make an existential SomeDictOf IdentityShow wrapper.
showSomeDict ::SomeDictOfIdentityShowshowSomeDict =SomeDictOf(Identity3 ::IdentityInt)
We can happily have a [, or a SomeDictOf Identity Show]Map String
(, or similar.SomeDictOf Identity 'Show)
Constructing them is easy enough. Consuming them can be a bit trickier. Let's
look at a .SomeDict Monoid
monoid ::SomeDictOfProxyMonoidmonoid =SomeDictOf(Proxy::ProxyText)
All we know about this is that it's carrying a datatype with a Monoid
instance. We'll case-match on the value, and then in the case branch, we'll
have evidence that (whatever the underlying type is) that it has a Monoid
instance.
We'll repackage the value, but instead of using Proxy, we'll stuff mempty
into Identity.
useMonoid ::SomeDictOfProxyMonoid->SomeDictOfIdentityMonoiduseMonoid someDictOfProxy = case someDictOfProxy of SomeDictOf (Proxy :: Proxy a) -> SomeDictOf (Identity (mempty :: a))
Since: 0.1.0.0
Constructors
| SomeDictOf :: c a => f a -> SomeDictOf f c |
someDict :: forall a c. c a => SomeDict c Source #
Construct a SomeDict with the type in question. Use with
TypeApplications.
Example:
showDict :: SomeDict Show showDict = someDict @Int entityDict :: SomeDict PersistEntity entityDict = someDict @User
Since: 0.1.0.0
fromDict :: forall a c. Dict (c a) -> SomeDict c Source #
Construct a SomeDict based on a Dict from the Data.Constraint module.
Since: 0.1.0.0
withSomeDictOf :: SomeDictOf f c -> (forall a. c a => f a -> r) -> r Source #
Unpack a SomeDictOf and attain access to the evidence that the
underlying type satisfies the instance in question.
Since: 0.1.0.0
mapSomeDictOf :: (forall a. c a => f a -> g a) -> SomeDictOf f c -> SomeDictOf g c Source #
Transform the type index used in the SomeDictOf. The provided function is
unable to inspect the type, but you will have the class operations available
to it.
Example:
provideMempty ;: SomeDictOf Proxy Monoid -> SomeDictOf Identity Monoid provideMempty = mapSomeDictOf (\proxy -> Identity mempty)
Since: 0.1.0.0
forgetContents :: forall f c. Functor f => SomeDictOf f c -> f (SomeDictOf Proxy c) Source #
Not really sure what this might be useful for.
Examples:
shows :: SomeDictOf [] Show
shows = SomeDictOf [True, False, True]
forgotten :: [SomeDictOf Proxy Show]
forgotten = forgetContents show
main = do
forM forgotten $ \(SomeDictOf Proxy) -> do
print 10
The above program should output 10 three times.
Since: 0.1.0.0
Re-exports
module Data.Functor.Identity
module Data.Proxy
module Data.Constraint