在 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 类型类。
我试过使用 readsPrec
和 readPrec
,但我只遇到类型不匹配的错误。
如何实现 Read 类型类的实例?
您的函数类型错误。您的 readsPrec
的类型为 String -> Natural
,而您应该使用 Int -> String -> [(Natural, String)]
。但我们可以调整:
readsPrec p s = [(fromInteger i, s') | (i, s') <- readsPrec p s]
这使用了 Integer
的 readsPrec
函数。既然你想阅读Integer
s,为了方便起见,正好适合。
出于对称原因,我建议您在 Show
实例中实施 showsPrec
而不是 show
。
我一直在研究归纳类型(定义的自然数和对它们的算术运算),但我无法让 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 类型类。
我试过使用 readsPrec
和 readPrec
,但我只遇到类型不匹配的错误。
如何实现 Read 类型类的实例?
您的函数类型错误。您的 readsPrec
的类型为 String -> Natural
,而您应该使用 Int -> String -> [(Natural, String)]
。但我们可以调整:
readsPrec p s = [(fromInteger i, s') | (i, s') <- readsPrec p s]
这使用了 Integer
的 readsPrec
函数。既然你想阅读Integer
s,为了方便起见,正好适合。
出于对称原因,我建议您在 Show
实例中实施 showsPrec
而不是 show
。