为什么即使我指定 is 作为类型限制,GHC 也会抱怨缺少 `Typeable` 实例?

tok*_*a-n 1 haskell

即使我添加了边界Typeable来满足cast函数的要求,为什么以下代码也无法编译?

\n
import           Data.Data\n\na :: Maybe Int\na = cast f\n  where\n    f :: Typeable a => a\n    f = undefined\n
Run Code Online (Sandbox Code Playgroud)\n
app/Main.hs:6:5: error:\n    \xe2\x80\xa2 No instance for (Typeable a0) arising from a use of \xe2\x80\x98cast\xe2\x80\x99\n    \xe2\x80\xa2 In the expression: cast f\n      In an equation for \xe2\x80\x98a\xe2\x80\x99:\n          a = cast f\n            where\n                f :: Typeable a => a\n                f = undefined\n  |\n6 | a = cast f\n  |     ^^^^\n
Run Code Online (Sandbox Code Playgroud)\n

Maybe Int应该实现类型类,因为以下代码可以编译。

\n
app/Main.hs:6:5: error:\n    \xe2\x80\xa2 No instance for (Typeable a0) arising from a use of \xe2\x80\x98cast\xe2\x80\x99\n    \xe2\x80\xa2 In the expression: cast f\n      In an equation for \xe2\x80\x98a\xe2\x80\x99:\n          a = cast f\n            where\n                f :: Typeable a => a\n                f = undefined\n  |\n6 | a = cast f\n  |     ^^^^\n
Run Code Online (Sandbox Code Playgroud)\n

(我不是问如何转换一个值,例如从IntString。我只是对这个奇怪的错误感到好奇。)

\n

GHC:9.2.2

\n

lef*_*out 6

f问题是您从未在强制转换之前指定应具有的类型。你同样可以这样做

\n
a :: Maybe Int\na = cast (f :: Int)\n where f :: Typeable a => a\n       f = undefined\n
Run Code Online (Sandbox Code Playgroud)\n

(这会产生Just \xe2\x8a\xa5)或

\n
a :: Maybe Int\na = cast (f :: [String])\n where f :: Typeable a => a\n       f = undefined\n
Run Code Online (Sandbox Code Playgroud)\n

(这会产生Nothing)。

\n

某些约束会导致编译器默认未指定的类型,例如Num上下文默认为Integer. 但Typeable没有默认任何内容,因此编译器会犹豫。

\n