gpt4 book ai didi

string - 如何在非双引号的字符串上使用 read ?

转载 作者:行者123 更新时间:2023-12-02 10:32:15 26 4
gpt4 key购买 nike

我正在使用 readLn 从控制台读取值。

我想写一个函数:

requestValue :: String -> IO a  
requestValue s = do
putStrLn $ "Please enter a new value for " ++ s
readLn

然后我就可以做,例如,

changeAge :: Person -> IO Person
changeAge p = do
age' <- requestValue "age"
return $ p { age = age'}

changeName :: Person -> IO Person
changeName p = do
name' <- requestValue "name"
return $ p { name = name'}

我遇到的问题是 String 的读取实例似乎要求字符串用引号引起来。当我真的只想输入 Fred 时,我不想在控制台中输入 "Fred" 来更改名称。

是否有一种简单的方法可以保持 requestValue 多态性?

最佳答案

由于您想为用户名添加自己的自定义读取行为,因此方法是实际为读数名称编写一个新实例。为此,我们可以为名称创建一个新类型:

import Control.Arrow (first)

newtype Name = Name { unName :: String }
deriving (Eq, Ord, Show)

并为其编写自定义读取:

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"}}

关于string - 如何在非双引号的字符串上使用 read ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6004554/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com