Поскольку вы хотите добавить свое собственное пользовательское поведение read
для имен пользователей, способ сделать это - написать новый экземпляр для чтения имен.Чтобы сделать это , мы можем создать новый тип для имен:
import Control.Arrow (first)
newtype Name = Name { unName :: String }
deriving (Eq, Ord, Show)
и написать для него пользовательский read
:
instance Read Name where
readsPrec n = map (first Name) . readsPrec n . quote
where quote s = '"' : s ++ ['"']
это то же самоев качестве экземпляра для чтения строк, но сначала мы цитируем строку, после чтения ее.
Теперь вы можете изменить тип Person
, чтобы использовать Name
вместо String
:
data Person = Person { age :: Int
, name :: Name } deriving Show
и мы находимся в бизнесе:
*Main> changeName (Person 31 (Name "dons"))
Please enter a new value for name
Don
Person {age = 31, name = Name {unName = "Don"}}