I'm a newbie when it comes to the singleton
library, and may have bitten off more than I can chew here.
I've managed to use fromSing
successfully to convert a "singleton type" to a "value-level term" (is my terminology correct?) However, I'm unable to understand how to use toSing
and conceptually how it would convert a value at run-time to a type?
Here's what the docs for toSing
say, which I don't really understand...
-- Convert an unrefined type to an existentially-quantified singleton type.
toSing :: Demote k -> SomeSing k
Here's what SomeSing
says:
-- An existentially-quantified singleton. This type is useful
-- when you want a singleton type, but there is no way of knowing,
-- at compile-time, what the type index will be. To make use of this
-- type, you will generally have to use a pattern-match:
foo :: Bool -> ...
foo b = case toSing b of
SomeSing sb -> {- fancy dependently-typed code with sb -}
Does this mean that conceptually, fromSing
is basically doing the following:
data RuntimeValue = Value1 | Value2
someFunction :: RuntimeValue -> UnifiedType a
case runtimeValue of
Value1 -> someAction (Proxy :: Proxy 'Value1)
Value2 -> someAction (Proxy :: Proxy 'Value2)
And that is the best that one can expect from Haskell, as of today? i.e. we need to pattern-match on the runtime value, run functions that can be of different types, but ultimately they should unify to a single type?