正如我在評論中所述,在內存中分配的運行時對象在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