正如我在评论中所述,在内存中分配的运行时对象在Haskell程序中没有类型标记。因此,没有像Java中那样的通用instanceof
操作。
考虑以下内容也很重要。在Haskell中,对于初步近似(即忽略一些初学者不应该过早处理的奇特东西),所有运行时函数调用都是单态。也就是说,编译器直接或间接地知道可执行程序中每个函数调用的单态(非泛型)类型。即使你的V
类型的show
函数有一个泛型类型:
-- Specialized to `V a`
show :: V a -> String -- generic; has variable `a`
...你不能真正写在运行时调用该函数没有程序的情况,直接或间接地告诉编译器到底是什么类型的a
会在每一个电话中。因此,例如:
-- Here you tell it directly that `a := Int`
example1 = show (V (1 :: Int))
-- Here you're not saying which type `a` is, but this just "puts off"
-- the decision—for `example2` to be called, *something* in the call
-- graph will have to pick a monomorphic type for `a`.
example2 :: a -> String
example2 x = show (V x) ++ example1
由此看来,希望你可以发现你要问什么问题:
instance Show (V a) where
show (V a) = if a instanceof Show
then show a
else "Some Error."
基本上,因为对于a
参数类型将在编译知道任何实际调用show
函数的时间,都没有必要在运行时测试这种类型 - 您可以在编译时测试它!一旦你掌握这个,你就导致了威尔休厄尔的建议:
-- No call to `show (V x)` will compile unless `x` is of a `Show` type.
instance Show a => Show (V a) where ...
编辑:更具建设性的答案也许可能是这样的:你V
类型必须是多个个案标签联合。这确实需要使用GADTs
扩展:
{-# LANGUAGE GADTs #-}
-- This definition requires `GADTs`. It has two constructors:
data V a where
-- The `Showable` constructor can only be used with `Show` types.
Showable :: Show a => a -> V a
-- The `Unshowable` constructor can be used with any type.
Unshowable :: a -> V a
instance Show (V a) where
show (Showable a) = show a
show (Unshowable a) = "Some Error."
但是,这不是一个类型是否为Show
实例,你的代码是负责了解在编译时在Showable
构造函数是要使用的运行时检查。
Haskell是一种完全删除类型的语言;在运行时,内存分配的结构不包含可用于恢复其类型或这些类型实现的类的标签。因此,没有Java或类似语言提供的'instanceof'运算符。 (有些更高级的技术可以在某些情况下用于类似的运行时类型反射,但如果您是初学者,您应该首先坚持基本知识!) –
此行为无法实现,因为哲学上_every类型是在每个班级。当然,如果编译器无法为某种类型的'Show'实例查找'show',则会出现错误;但这被理解为在概念上“你忘了写必要的实例”,而不是“你试图展示一个不可显示的类型”。类型类是开放的,任何人都可以稍后为某些库类定义实例。当编译库时,编译器不可能证明这不会发生! – leftaroundabout
也就是说:行为可以用[重叠实例]来模拟(https://downloads.haskell.org/~ghc/7.8.1/docs/html/users_guide/type-class-extensions.html#instance-overlap) ,这被认为有点丑陋(甚至不安全)。也许更好地匹配这个想法是[封闭类型家族](http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/axioms-extended.pdf),虽然他们不很容易让你实现这个show实例。 – leftaroundabout