Skip to the content.

Convert a type level natural number to a value level integer and vise versa

As we saw in the last post, GHC supports type level natural numbers. How can we treat it in value level?

To bring a type level natural number to a value level, we use Data.Proxy.Proxy. Then use GHC.TypeLits.natVal to convert it to Integer. For example, natVal (Proxy :: Proxy 10) returns 10.

Let’s take an example of the type-safe list in the last post and add length function that returns a length of a list.

length :: forall len a. KnownNat len => List len a -> Integer
length _ = natVal (Proxy :: Proxy len)

Note that it doesn’t use an actual list value. It just uses its type.

On the other hand, we can use GHC.TypeLits.someNatVal to convert Integer to a type level number. At this time, I’m going to add isLength function for a type-safe list. Of course, you can implement it using length, but I’m not going to do that.

isLength :: forall len a. KnownNat len => Integer -> List len a -> Bool
isLength n _ | Just (SomeNat p)  List l a -> List (l + 1) a

deriving instance Show a => Show (List len a)

length :: forall len a. KnownNat len => List len a -> Integer
length _ = natVal (Proxy :: Proxy len)

isLength :: forall len a. KnownNat len => Integer -> List len a -> Bool
isLength n _ | Just (SomeNat p)