即使我添加了边界Typeable来满足cast函数的要求,为什么以下代码也无法编译?
import Data.Data\n\na :: Maybe Int\na = cast f\n where\n f :: Typeable a => a\n f = undefined\nRun Code Online (Sandbox Code Playgroud)\napp/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 | ^^^^\nRun Code Online (Sandbox Code Playgroud)\nMaybe Int应该实现类型类,因为以下代码可以编译。
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 | ^^^^\nRun Code Online (Sandbox Code Playgroud)\n(我不是问如何转换一个值,例如从Int到String。我只是对这个奇怪的错误感到好奇。)
GHC:9.2.2
\nf问题是您从未在强制转换之前指定应具有的类型。你同样可以这样做
a :: Maybe Int\na = cast (f :: Int)\n where f :: Typeable a => a\n f = undefined\nRun Code Online (Sandbox Code Playgroud)\n(这会产生Just \xe2\x8a\xa5)或
a :: Maybe Int\na = cast (f :: [String])\n where f :: Typeable a => a\n f = undefined\nRun Code Online (Sandbox Code Playgroud)\n(这会产生Nothing)。
某些约束会导致编译器默认未指定的类型,例如Num上下文默认为Integer. 但Typeable没有默认任何内容,因此编译器会犹豫。