我在Haskell中有这些功能:
type World = [String]
look :: World -> IO World
look w = do
putStrLn $ "You are here " ++ show w
return w
test w = do
words <- fmap words getLine
case words of
("quit":_) -> return ()
("look":_) -> do w' <- area w'; describe w'
("remove":item:_) -> do w' <- removeItem item w; loop w'
_ -> do putStrLn "Wrong input"; test w
area::String->String
area place =
return place
describe:: String ->String
describe place =
case place of
"usa" -> putStrLn "It is usa"
"uk" -> putStrLn "It is uk"
"aur" -> putStrLn "It is aus"
main = do
let world0 = ["ht", "alt"]
let place = ["usa"]
area place
print place
test world0
在第
行("look":_) -> do w' <- area w'; describe w'
我想打电话给&#34;区域&#34;返回在main中输入的位置的函数和describe
函数,以返回该位置的描述。我怎么能这样做?
答案 0 :(得分:2)
在这种情况下,你的世界由两个状态项组成:
因此type World = [String]
无法正常工作。你需要这样的东西:
type World = (String, [String]) -- (where, items)
-- or:
data World = World { where_ :: String, items_ :: [String] }
现在必须重新设计removeItem
,describe
之类的功能。
例如,假设我们有type World = (String,[String])
。那么describe
会像:
describe :: World -> IO ()
describe (place,_) =
case place of
"usa" -> ...
"uk" -> ...
...other cases...
答案 1 :(得分:0)
如果您想在两个函数(main
和test
)之间保持状态,可以使用IORef
进行此操作。
test w ref = do
-- when you need to read it:
place <- readIORef ref
i_am_at = writeIORef
main = do
let world0 = ["ht", "alt"]
let place = ["usa"]
ref <- newIORef place -- creates the ref with initial value
i_am_at ref place -- needs reference
print place
test world0 ref
但是,这完全是错误的方向。这不是哈斯克尔惯用的做事方式。实际上,您正在用函数式语言复制命令式代码。
尝试以不需要可变变量的方式重构代码,构建状态机可以是一个好的开始。