通过 SomeNat 上的模式匹配产生的类型变量的范围是什么?
What is the scope of a type variable brought into existence by pattern matching on SomeNat?
我无法理解此代码的原因:
-- someNatVal test case
--
-- David Banas <capn.freako@gmail.com>
-- August 5, 2018
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
import GHC.TypeLits
import Data.Proxy
tellNat :: forall n. KnownNat n => Integer
tellNat = natVal (Proxy :: Proxy n)
foo :: Integer -> Integer
foo n =
let SomeNat (_ :: Proxy m) =
fromMaybe (error "Negative Nat!") (someNatVal n)
in tellNat @m
main :: IO ()
main = print $ foo 1 == 1
产生此编译错误:
[1 of 1] Compiling Main ( someNatValTest.hs,
someNatValTest.o )
someNatValTest.hs:22:16: error: Not in scope: type variable ‘m’
根据@Carl,此代码:
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
import GHC.TypeLits
import Data.Maybe
import Data.Proxy
tellNat :: forall n. KnownNat n => Integer
tellNat = natVal (Proxy :: Proxy n)
foo :: Integer -> Integer
foo n =
case n' of
SomeNat (_ :: Proxy m) ->
tellNat @m
where n' = fromMaybe (error "Negative Nat!") (someNatVal n)
main :: IO ()
main = print $ foo 1 == 1
作品:
dca9047d694f:tmp a594349$ stack runghc someNatValTest.hs
True
有趣 - 如果您尝试类似的操作,GHC 通常会告诉您它的大脑爆炸了。我想在你的情况下,SomeNat
只是一个存在的,而不是真正的 GADT,因此你不会收到有趣的错误消息。
无论如何,如果要访问隐藏在数据类型中的类型,则需要将构造函数与 case
表达式而不是 let
匹配。
我无法理解此代码的原因:
-- someNatVal test case
--
-- David Banas <capn.freako@gmail.com>
-- August 5, 2018
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
import GHC.TypeLits
import Data.Proxy
tellNat :: forall n. KnownNat n => Integer
tellNat = natVal (Proxy :: Proxy n)
foo :: Integer -> Integer
foo n =
let SomeNat (_ :: Proxy m) =
fromMaybe (error "Negative Nat!") (someNatVal n)
in tellNat @m
main :: IO ()
main = print $ foo 1 == 1
产生此编译错误:
[1 of 1] Compiling Main ( someNatValTest.hs, someNatValTest.o )
someNatValTest.hs:22:16: error: Not in scope: type variable ‘m’
根据@Carl,此代码:
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
import GHC.TypeLits
import Data.Maybe
import Data.Proxy
tellNat :: forall n. KnownNat n => Integer
tellNat = natVal (Proxy :: Proxy n)
foo :: Integer -> Integer
foo n =
case n' of
SomeNat (_ :: Proxy m) ->
tellNat @m
where n' = fromMaybe (error "Negative Nat!") (someNatVal n)
main :: IO ()
main = print $ foo 1 == 1
作品:
dca9047d694f:tmp a594349$ stack runghc someNatValTest.hs
True
有趣 - 如果您尝试类似的操作,GHC 通常会告诉您它的大脑爆炸了。我想在你的情况下,SomeNat
只是一个存在的,而不是真正的 GADT,因此你不会收到有趣的错误消息。
无论如何,如果要访问隐藏在数据类型中的类型,则需要将构造函数与 case
表达式而不是 let
匹配。