【问题标题】:How to create instance of Read for a datatype in haskell如何在haskell中为数据类型创建读取实例
【发布时间】:2011-10-21 14:57:20
【问题描述】:

所以我有一个数据类型

data SomeType a =
    Type a |
    Mix (SomeType a) (SomeType a)

这是我的 SomeType 展示实例

instance (Show a) => Show (SomeType a) where
    show (Type a) = show a
    show (Mix a b) = "(" ++ show a ++ " " ++ show b ++ ")"

所以

Mix (Type 5) (Type 4)

会给我

(5 4)

现在我想拥有

read "(3 4)" :: SomeType Int 

生产

(3 4)

read "(a b)" :: SomeType Char

生产

(a b)

我不知道如何使用 Read 类。

【问题讨论】:

  • 顺便说一句,SomeType Char 的示例不是 show (Mix (Type 'a') (Type 'b')) 会生成的。
  • 您可以在类型声明后使用 deriving (Show, Read) 派生 - Show 和 Read 实例。虽然它们不会产生您的输出和输入,但它们是显示(有时是读取)值的标准方式,这就是为什么您应该使用它们而不是您自己的实例的原因。如果您想以不同的方式显示它们,请使用单独的函数并将其命名为render 左右。

标签: haskell typeclass


【解决方案1】:

这是一个基于documentation 的示例,它应该能够解析show 呈现的所有内容(假设该类型定义了兼容的Read 实例),即read . show 应该或多或少是身份:

instance (Read a) => Read (SomeType a) where
    readsPrec d r = readMix r ++ readType r
      where
        readMix = readParen True $ \r -> do
            (v1, r'') <- readsPrec d r
            (v2, r')  <- readsPrec d r''
            return (Mix v1 v2, r')

        readType r = do
            (v, r') <- readsPrec d r
            return (Type v, r')

因此,

> read "(3 4)" :: SomeType Int 
(3 4)
it :: SomeType Int

但请注意,对于 SomeType CharChar 的默认 Show 实例用单引号括住字符:

> read "('a' ('b' 'c'))" :: SomeType Char
('a' ('b' 'c'))
it :: SomeType Char

希望对你有帮助

【讨论】:

  • @Qin d 是封闭解析上下文的运算符优先级(我不小心增加了——我已经编辑过这个),r 是当前要解析的剩余字符串。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-05
  • 2017-04-03
  • 2015-02-03
  • 1970-01-01
  • 1970-01-01
  • 2013-03-29
  • 1970-01-01
相关资源
最近更新 更多