Squ*_*dly 5 string io parsing haskell
我正在使用控制台从中读取值readLn.
我想写一个函数:
requestValue :: String -> IO a
requestValue s = do
putStrLn $ "Please enter a new value for " ++ s
readLn
Run Code Online (Sandbox Code Playgroud)
然后,我可以这样做,例如,
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'}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是String的读取实例似乎要求字符串在引号中."Fred"当我真的只想输入时,我不想进入控制台更改名称Fred.
是否有一种简单的方法可以保持requestValue多态性?
由于您想read为用户名添加自己的自定义行为,因此方法是实际为读数名称编写一个新实例。为此,我们可以为名称创建一个新类型:
import Control.Arrow (first)
newtype Name = Name { unName :: String }
deriving (Eq, Ord, Show)
Run Code Online (Sandbox Code Playgroud)
read并为其编写自定义:
instance Read Name where
readsPrec n = map (first Name) . readsPrec n . quote
where quote s = '"' : s ++ ['"']
Run Code Online (Sandbox Code Playgroud)
这与字符串的读取实例相同,但我们在读入字符串后首先引用该字符串。
现在您可以修改您的Person类型来Name代替String:
data Person = Person { age :: Int
, name :: Name } deriving Show
Run Code Online (Sandbox Code Playgroud)
我们正在做生意:
*Main> changeName (Person 31 (Name "dons"))
Please enter a new value for name
Don
Person {age = 31, name = Name {unName = "Don"}}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
149 次 |
| 最近记录: |