如何在Haskell中编写自定义的show函数

yeh*_*ehe 4 enums haskell

我正在定义Octave类型:

data Octave = 1 | 2 | 3
  deriving (Show, Read, Ord, Enum)
Run Code Online (Sandbox Code Playgroud)

由于'1'对数据构造函数标识符无效,我必须这样做:

data Octave = O1 | O2 | O3
  deriving (Show, Eq, Read, Ord, Enum)
Run Code Online (Sandbox Code Playgroud)

现在,如果我show Octave O1显示"O1",这不是我想要的.我希望结果为"1".我知道我们可以像这样定制我们的Show行为:

instance Show Blabla where                                                                                       
  show (Blabla ints chars list num) =                                                                            
    "integers = " ++ show ints ++ "\n"
Run Code Online (Sandbox Code Playgroud)

但问题是我使用的是枚举类型,这意味着除了标识符名称'O1'之外它没有值.我怎样才能在Haskell中访问它?

另一个问题:我怎么读回来?

read "O1" :: Octave 工作,但我想 read "1" :: Octave

instance Read Octave where
  read "1" = O1
  read "2" = O2
  read "3" = O3
Run Code Online (Sandbox Code Playgroud)

这不起作用:" read不是(可见的)类方法Read".

sha*_*ang 6

利用Octave的Enum实例并使用ShowRead实例,Int我们可以实现这样的显示和读取:

data Octave = O1 | O2 | O3 deriving (Eq, Ord, Enum)

instance Show Octave where
    show o = show (fromEnum o + 1)

instance Read Octave where
    readsPrec prec = map (\(n,s) -> (toEnum (n - 1), s)) . readsPrec prec
Run Code Online (Sandbox Code Playgroud)

fromEnum,toEnum在八度和整数之间进行转换,以便O1< - > 0O2< - > 1,因此我们必须在读取和写入时调整一个.


aug*_*tss 5

这是一种不同的方法:

data Octave_ = O1 | O2 | O3 deriving (Show, Eq, Read, Ord, Enum)
newtype Octave = O { unO :: Octave_ }  deriving (Eq, Ord, Enum)

instance Show Octave where
    show = tail . show . unO
Run Code Online (Sandbox Code Playgroud)

根据你正在做的事情,这可能是好事还是坏事.