I am new to Haskell and I want to be able to a newtype so I can tell what is what, but I also have to read it from a string. I have
newtype SpecialId Int
deriving (Eq, Ord, Show)
I want to be able to read "5" :: SpecialId if I derive Read in the newtype it doesn't work it only works on read "SpecialId 5" :: SpecialId. I have tried
instance Read SpecialId where
readsPrec _ s = read s
But this gives me
SpecialId *** Exception: Prelude.read: no parse
This is possible since GHC 8.2 using -XDerivingStrategies:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DerivingStrategies #-}
newtype SpecialId = SpecialId Int
deriving stock (Eq, Ord, Show)
deriving newtype Read
In ghci:
ghci> read "5" :: SpecialId
SpecialId 5
You don't need a language extension if you're willing to forward to the Int instance manually:
instance Read SpecialId where
readsPrec n s = [ (SpecialId x, y) | (x, y) <- readsPrec n s ]
Despite appearances this is not a recursive use of readsPrec: We call the Int version of readsPrec to get a list of (Int, String) pairs, then we use a list comprehension to wrap every Int in a SpecialId.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With