如何在Haskell中的另一个函数内调用多个函数?

时间:2014-11-10 16:03:18

标签: haskell

我在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函数,以返回该位置的描述。我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

在这种情况下,你的世界由两个状态项组成:

  • 你在哪里,
  • 你有什么物品

因此type World = [String]无法正常工作。你需要这样的东西:

type World = (String, [String])  -- (where, items)
-- or:
data World = World { where_ :: String, items_ :: [String] }

现在必须重新设计removeItemdescribe之类的功能。

例如,假设我们有type World = (String,[String])。那么describe会像:

describe :: World -> IO ()
describe (place,_) =
  case place of
    "usa" -> ...
    "uk" -> ...
    ...other cases...

答案 1 :(得分:0)

如果您想在两个函数(maintest)之间保持状态,可以使用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

但是,这完全是错误的方向。这不是哈斯克尔惯用的做事方式。实际上,您正在用函数式语言复制命令式代码。

尝试以不需要可变变量的方式重构代码,构建状态机可以是一个好的开始。