我正在Haskell中编写一个带有IO操作的小程序 这是
module StackQuestion where
import Data.Map (Map, insert, fromList)
type Name = String
type Value = String
readValue :: Name -> IO String
readValue name = do putStrLn name
value <- getLine
return value
addPair :: Name -> Value -> Map Name Value -> Map Name Value
addPair = insert
names = map show [1..5]
values = map (\char -> [char]) ['a'..'d']
initialMap = fromList (zip names values)
正如你所看到的,我有一些带有值的初始映射,以及为映射添加一对的函数,这些函数读取一个值。
如何从String
获取明确的readValue
值并将其传递给其他函数?
或者我应该将type Value = String
更改为type Value = IO String
并使用地图Map String (IO String)
?
如果我有Map String (IO String)
我如何处理这张地图,我怎样才能获得依赖于IO
内容中的数据的任何值(可能是一些函数func :: (a->b) -> IO a -> b
)
例如,有没有办法将IO String
与 clear String
进行比较?
如果我有函数func
我会写
map :: Map String (IO String)
...
func (==) (map ! "key")
使用IO
值的策略是什么?
答案 0 :(得分:7)
如何从
String
获取明确的readValue
值并将其传递给其他函数?
你不能;你必须在readValue
monad中操纵IO
的结果。
{- read value for name and store both in map -}
readAndStore :: Name -> Map Name Value -> IO (Map Name Value)
readAndStore name m = do value <- readValue name
return $ insert name value m
return
函数获取insert
的结果,并将其整齐地放回IO
monad中。此代码举例说明了使用IO
中的普通函数操作值的一般模式。
或者我应该将
type Value = String
更改为type Value = IO String
没有;考虑一下这意味着什么。 IO String
表示带有IO
类型结果的可能副作用(String
)的计算。您将名称映射到计算。 (这是可能的,但这不是你的意思。)
我上面显示的示例使用IO (Map Name Value)
代替;即,IO
monad中的计算结果为Map
。