在 haskell 中实现 Read 类型类的实例

Implementing instance of Read typeclass in haskell

我一直在研究归纳类型(定义的自然数和对它们的算术运算),但我无法让 Haskell 读取函数工作。

这是我的代码:

data Natural = Zero | Succ Natural
    deriving (Eq, Ord)

instance Enum Natural where
    pred Zero = undefined
    pred (Succ x) = x

    succ x = Succ x

    toEnum 0 = Zero
    toEnum x = Succ (toEnum (x - 1))

    fromEnum Zero = 0
    fromEnum (Succ x) = fromEnum x + 1

instance Num Natural where
    (+) x Zero = x
    (+) x (Succ y) = Succ (x + y)

    (-) Zero (Succ x) = undefined
    (-) x Zero = x
    (-) (Succ x) (Succ y) = x - y

    (*) x Zero = Zero
    (*) x (Succ y) = x * y + x

    abs x = x

    signum Zero = Zero
    signum (Succ x) = Succ Zero

    fromInteger 0 = Zero
    fromInteger x = Succ (fromInteger (x - 1))

instance Show Natural where
    show x = show $ fromEnum x

-- Not working!

instance Read Natural where
    readsPrec x = fromInteger $ (read x) :: Integer

我希望这个表达式有效: naturalNumber = read someStringWithInteger :: Natural,所以我不能只派生 Read 类型类。

我试过使用 readsPrecreadPrec,但我只遇到类型不匹配的错误。

如何实现 Read 类型类的实例?

您的函数类型错误。您的 readsPrec 的类型为 String -> Natural,而您应该使用 Int -> String -> [(Natural, String)]。但我们可以调整:

readsPrec p s = [(fromInteger i, s') | (i, s') <- readsPrec p s]

这使用了 IntegerreadsPrec 函数。既然你想阅读Integers,为了方便起见,正好适合。

出于对称原因,我建议您在 Show 实例中实施 showsPrec 而不是 show