thy*_*222 10 haskell types instance
如何为Typeable编写实际的实例声明?例如,假设我想为Char编写一个实例,其中每个角色都有不同的类型,例如
instance Typeable Char where
typeOf 'a' = C
typeOf 'b' = C -> D
typeOf 'c' = D -> E
typeOf = String
Run Code Online (Sandbox Code Playgroud)
显然这不会像这样写,因为typeOf的输出是TypeRep,但我无法弄清楚如何实际构造TypeRep.
这甚至可能吗?似乎所有关于Typeable的内容都假定您将使用DeriveDataTypeable.
Dan*_*zer 17
这样做有一些问题.
它坏了.typeOf
不应该在它的论点中严格,所以typeOf (undefined :: Char)
应该工作.
这是不安全的.实际上,如果您手动创建一个实例,Typeable
则无法在Safe Haskell下编译.
记住这一点!
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Typeable
data C = C deriving (Typeable)
data D = D deriving (Typeable)
data E = E deriving (Typeable)
newtype Foo = Foo Char
instance Typeable Foo where
typeOf (Foo 'a') = typeOf (undefined :: C)
typeOf (Foo 'b') = typeOf (undefined :: C -> D)
typeOf (Foo 'c') = typeOf (undefined :: D -> E)
typeOf _ = typeOf (undefined :: String)
Run Code Online (Sandbox Code Playgroud)
现在作为为什么这是可怕的一个例子,考虑一下
what :: Char -> C
what c = if isJust weird then fromJust weird else error "Sanity!"
where weird = fromDynamic . toDyn $ Foo c
Run Code Online (Sandbox Code Playgroud)
现在
> what 'a'
C
> what 'b'
*** Exception: Sanity!
Run Code Online (Sandbox Code Playgroud)
取决于Foo
这可以做各种有趣的事情的表示,如段错,吐出无意义的答案,或让猴子飞出你的耳朵.
罗伯特哈珀给出了一个更具戏剧性的例子
{-# LANGUAGE DeriveDataTypeable #-}
import Control.Exception
import Data.Typeable
newtype Foo = Foo (() -> IO ())
{- set Foo’s TypeRep to be the same as ErrorCall’s -}
instance Typeable Foo where
typeOf _ = typeOf (undefined :: ErrorCall)
instance Show Foo where show _ = ""
instance Exception Foo
main = Control.Exception.catch (error "kaboom") (\ (Foo f) -> f ())
Run Code Online (Sandbox Code Playgroud)
这使
<interactive>: internal error: stg_ap_v_ret
(GHC version 7.6.3 for x86_64_unknown_linux)
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
C-c C-c
Process haskell aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
768 次 |
最近记录: |