haskell 自定义数据类型的读取类的实现

fafcakar  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(212)

我试图创建一个可以转换为字符串的数据类型(用于用户输入)。我想要一个函数,它可以是dataToText :: Colour -> String,也可以是textToData :: String -> Colour的反函数。我编写了下面的代码来实现这个功能:

data Colour = Red | Blue | Green deriving (Eq, Read)
instance Show Colour where
    show Red = "R"
    show Blue = "B"
    show Green = "G"

当我在GHCi中运行这个命令时,show Red返回"R",这正是我希望'dataToText'工作的方式。
我想,但我可能错了,通过派生Read类,read将通过反转我的show函数来工作。将我的代码加载到GHCi中不会给予错误,所以我猜必须创建一些read函数。我在网上看了很多关于read的信息,但是我不知道如何实现这个基本的读取功能,经常提到readPrecreadsPrec,但是我无法使用这些来创建一个成功的实现。有人能解释一下我上面的例子应该如何实现吗?我觉得我只是缺少了一个(但基本的)一块拼图,以了解阅读是如何工作的。

plicqrtu

plicqrtu1#

在派生示例时使用-ddump-derive

Prelude> data Colour = Red | Blue | Green deriving Read

==================== Derived instances ====================
Derived class instances:
  instance GHC.Read.Read Ghci3.Colour where
    GHC.Read.readPrec
      = GHC.Read.parens
          (GHC.Read.choose
             [("Red", GHC.Base.return Ghci3.Red),
              ("Blue", GHC.Base.return Ghci3.Blue),
              ("Green", GHC.Base.return Ghci3.Green)])
    GHC.Read.readList = GHC.Read.readListDefault
    GHC.Read.readListPrec = GHC.Read.readListPrecDefault

Derived type family instances:


==================== Filling in method body ====================
GHC.Read.Read [Ghci3.Colour]
  GHC.Read.readsPrec = GHC.Read.$dmreadsPrec @(Ghci3.Colour)

然后您可以轻松地替换字符串

instance Read Colour where
  readPrec :: ReadPrec Colour
  readPrec = parens $
    choose
      [ ("R", pure Red)
      , ("B", pure Blue)
      , ("G", pure Green)
      ]

相关问题