I was following the example set out in the question Can I have an unknown KnownNat?
I wanted to make a small change to the code.
The original code was
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
import GHC.TypeLits
import Data.Proxy
data Bar (n :: Nat) = Bar String deriving Show
bar :: (KnownNat n) => Bar n -> (String, Integer)
bar b@(Bar s) = (s, natVal b)
main :: IO ()
main = do
i <- readLn
let Just someNat = someNatVal i
case someNat of
SomeNat (_ :: Proxy n) -> do
let a :: Bar n
a = Bar "as"
print $ bar a
which works as expected. I wanted to make a change in which I modify the type level n
.
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
import GHC.TypeLits
import Data.Proxy
data Bar (n :: Nat) = Bar String deriving Show
bar :: (KnownNat n) => Bar n -> (String, Integer)
bar b@(Bar s) = (s, natVal b)
main :: IO ()
main = do
i <- readLn
let Just someNat = someNatVal i
case someNat of
SomeNat (_ :: Proxy n) -> do
let a :: Bar (n + 5)
a = Bar "as"
print $ bar a
The error message I get is
Could not deduce (KnownNat (n + 5)) arising from a use of ‘bar’
from the context (KnownNat n)
bound by a pattern with constructor
SomeNat :: forall (n :: Nat). KnownNat n => Proxy n -> SomeNat,
in a case alternative
at Blag.hs:19:9-30
In the second argument of ‘($)’, namely ‘bar a’
In a stmt of a 'do' block: print $ bar a
In the expression:
do { let a :: Bar (n + 5)
a = Bar "as";
print $ bar a }
Failed, modules loaded: none.
Why can't the compiler deduce KnownNat (n + 5)
from KnownNat n
?