我正在开发一个项目,我通过一个幻像类型跟踪我使用的db-schema - 它有一个KnownSymbol
- 这是模式名称。
就在前几天,我遇到了以下问题 - 我不明白:
为什么无法定义withoutProxy
或重新定义它?为什么GHC认为test
属于*
而非Symbol
(Proxy :: Proxy test)
,虽然类型签名另有说明,但ScopedTypeVariables
已启用。
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE KindSignatures #-}
module T where
import GHC.TypeLits
import Data.Proxy
newtype Phantom (x :: Symbol) y = Phantom y
withProxy :: (KnownSymbol test) => Proxy test -> Phantom test ()
withProxy _ = Phantom ()
withoutProxy :: (KnownSymbol test) => Phantom test ()
withoutProxy = withProxy (Proxy :: Proxy test)
我得到的错误最令人困惑
> ghci test.hs
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling T ( test.hs, interpreted )
test.hs:14:27: error:
• Couldn't match type ‘*’ with ‘Symbol’
Expected type: Proxy test
Actual type: Proxy test
Use -fprint-explicit-kinds to see the kind arguments
• In the first argument of ‘withProxy’, namely
‘(Proxy :: Proxy test)’
In the expression: withProxy (Proxy :: Proxy test)
In an equation for ‘withoutProxy’:
withoutProxy = withProxy (Proxy :: Proxy test)
Failed, modules loaded: none.
然后启用-fprint-explicit-kinds
Prelude> :set -fprint-explicit-kinds
Prelude> :r
[1 of 1] Compiling T ( test.hs, interpreted )
test.hs:15:27: error:
• Couldn't match type ‘*’ with ‘Symbol’
Expected type: Proxy Symbol test
Actual type: Proxy * test
• In the first argument of ‘withProxy’, namely
‘(Proxy :: Proxy test)’
In the expression: withProxy (Proxy :: Proxy test)
In an equation for ‘withoutProxy’:
withoutProxy = withProxy (Proxy :: Proxy test)
Failed, modules loaded: none.
答案 0 :(得分:5)
简短回答:添加forall
withoutProxy :: forall test. (KnownSymbol test) => Phantom test ()
withoutProxy = withProxy (Proxy :: Proxy test)
第二行没有test
,与上面的那个不同。
或者,根本不要添加类型注释:
withoutProxy :: (KnownSymbol test) => Phantom test ()
withoutProxy = withProxy Proxy
或者您可以添加{-# LANGUAGE PolyKinds #-}
,然后事情也会统一,因为Proxy :: Proxy test
将是forall k (test :: k). Proxy k test
,其中k
是一种。