Convert Nat from invoking type family to Integer

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)

      

doesn't work 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 this?

+3


source to share


1 answer


There are two problems with the code. First, (sing :: Sing n)

it has no n

scope. To bring it into scope, you need to explicitly forall

.

Second, if you want SingI

, you need to say it. The GHC does not know and never checks what N t

is SingI

for everyone t

, what is actually wrong, by the way: it N Bool

has a form Nat

, but not SingI (N Bool)

.

Hence the solution:



foo :: forall t. SingI (N t) => t -> Integer
foo _ = fromSing (sing :: Sing (N t))

      

Or with the type of applications:

foo :: forall t. SingI (N t) => t -> Integer
foo _ = fromSing (sing @_ @(N t))

      

+3


source







All Articles