Reputation: 2956
import Data.Singletons
import Data.Singletons.TypeLits
type family N t :: Nat where
N Int = 42
N String = 9
foo :: (n ~ N t) => t -> Integer
foo _ = fromSing (sing :: Sing n)
fails with
• Could not deduce: DemoteRep * ~ Integer
from the context: n ~ N t
bound by the type signature for:
foo :: n ~ N t => t -> Integer
at mini.hs:16:1-32
• In the expression: fromSing (sing :: Sing n)
In an equation for ‘foo’: foo _ = fromSing (sing :: Sing n)
How can I fix it?
Upvotes: 3
Views: 403
Reputation: 30103
There are two issues with your code. First, (sing :: Sing n)
does not have n
in scope. You need explicit forall
to bring it to scope.
Second, if you want SingI
, you need to say so. GHC does not know and never checks that N t
is SingI
for all t
, which is not actually true, by the way: N Bool
has kind Nat
but there is no SingI (N Bool)
.
Hence, the solution:
foo :: forall t. SingI (N t) => t -> Integer
foo _ = fromSing (sing :: Sing (N t))
Or with type applications:
foo :: forall t. SingI (N t) => t -> Integer
foo _ = fromSing (sing @_ @(N t))
Upvotes: 3