gpt4 book ai didi

haskell - 为 Typeable 编写实例声明而不进行派生

转载 作者:行者123 更新时间:2023-12-04 03:11:49 26 4
gpt4 key购买 nike

如何为 Typeable 编写实际的实例声明?例如,假设我想为 Char 编写一个实例,其中每个字符都有不同的类型,例如

instance Typeable Char where
typeOf 'a' = C
typeOf 'b' = C -> D
typeOf 'c' = D -> E
typeOf = String

显然这不会这样写,因为 typeOf 的输出是一个 TypeRep,但我不知道如何实际构造一个 TypeRep。

这甚至可能吗?似乎所有关于 Typeable 的讨论都假设您将使用 DeriveDataTypeable。

最佳答案

好吧,这样做有一些问题。

  • 它坏了。 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)

    现在作为一个为什么这很糟糕的例子,考虑一下
    what :: Char -> C
    what c = if isJust weird then fromJust weird else error "Sanity!"
    where weird = fromDynamic . toDyn $ Foo c

    现在
    > what 'a'
    C
    > what 'b'
    *** Exception: Sanity!

    取决于 Foo 的表示方式这可以做各种有趣的事情,比如 seg 错误、胡说八道的答案,或者让猴子从你的耳朵里飞出来。

    Robert Harper举了一个更戏剧化的例子
    {-# 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 ())

    这使
    <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)

    关于haskell - 为 Typeable 编写实例声明而不进行派生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20896098/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com