我无法理解为什么要使用此代码:
-- 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之1]编译Main(someNatValTest.hs, someNatValTest.o)
someNatValTest.hs:22:16:错误:不在范围内:输入变量“ 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
答案 0 :(得分:2)
有趣的是-如果您尝试类似的操作,GHC通常会告诉您其大脑爆炸了。我想在您的情况下,SomeNat
只是存在的,不是真正的GADT,因此您不会收到有趣的错误消息。
无论如何,如果要访问隐藏在数据类型内部的类型,则需要将构造函数与case
表达式而不是let
匹配。