简体   繁体   中英

Implementing instance of Read typeclass in haskell

I've been playing around with inductive types (defined natural numbers and arithmetic operations on them) a little bit, and I can't get Haskell read function to work.

Here's my code:

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

I want this expression to be valid: naturalNumber = read someStringWithInteger :: Natural , so I can't just derive Read typeclass.

I've tried using readsPrec and readPrec , but I only get mismatched type errors.

How do I implement an instance of Read typeclass?

Your function has the wrong type. Your readsPrec has type String -> Natural , whereas you should have used Int -> String -> [(Natural, String)] . But we can adjust that:

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

This uses Integer 's readsPrec function. Since you want to read Integer s it's just fitting to use it for convenience.

For symmetry reasons, I suggest you to implement showsPrec instead of show in your Show instance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM