如何在if语句的列表中存储值

时间:2014-11-09 01:38:54

标签: haskell

嗨,我有这些功能:

i_am_at::String->String
i_am_at place =
  place

at::String-> (String, String)
at place =
  case place of
    "bedroom" -> ("fly", "light switch")
    "den" -> ("flyswatter", "light switch")

main::IO()
main = do
  putStrLn "Enter place"
  p <- getLine :: IO String
  i_am_at p

我想写一个函数&#34; take&#34;需要参数&#34; item&#34;并调用i_am_at函数,该函数返回一个字符串&#34; place&#34;,然后调用&#34; at&#34;使用i_am_at函数返回的字符串函数,然后在place为卧室时检查该项是否为灯开关,然后将其存储到数组中并返回它。但是,如果物品飞了,那么就不要存放它。类似地,如果place是den并且该项目来自两者,则将其存储到该数组中。我正在做这样的事情:

take::String->String[],IO() 
take item =
  plc = i_am_at
    | plc == "bedroom" && item == "light switch" && item not present in list y already (I don't know how to write this condition)
      y = item
    | plc == "bedroom" && item == "fly" && item not present in list y already (I don't know how to write this condition)
      = putStrLn "You cannot take that"
    | plc == "den" && item == "flyswatter" && item not present in list y already (I don't know how to write this condition)
      y = item
    | plc == "den" && item == "light switch" && item not present in list y already (I don't know how to write this condition)
      y = item
    | if item present in list y already
      = putStrLn "You already have it"
    | Otherwise = putStrLn "Item is not here"
    return y

有人可以帮我解决这个问题。 y是此函数中的列表,但我不知道如何在其中存储值。我也不知道我们怎么能有一个返回类型的返回类型并将其打印出来。我也不知道陈述plc=i_am_at是否正确。如何使这项工作?

1 个答案:

答案 0 :(得分:2)

在像Haskell这样的纯函数式语言中,您可以使用以下方法模拟可变状态:

  1. 定义一个数据结构,其中包含可能发生变化的所有内容(让我们称之为World
  2. 编写所有状态修改函数以获得签名World -> World(或者,如果需要执行IO,则可能World -> IO World。该函数从现有函数创建新的世界值。
  3. 链接所有函数调用,以便将来自一个调用的输出世界作为输入传递给下一个函数。
  4. 示例:假设您的世界只包含一个项目列表(字符串):

    type World = [String]
    

    要删除项目,您可以编写如下函数:

    removeItem :: String -> World -> IO World
    removeItem item world = do
      if elem item world
        then do putStrLn "Item removed."
                return $ delete item world
        else do putStrLn "No such item - " ++ item
                return world
    

    然后你可以删除两个项目:

    removeTwoItems a b world = do
      world1 <- removeItem a world
      world2 <- removeItem b world
      return world2
    

    有一些先进的机制(比如State monad)可以帮助你处理这些模式,但这基本上就是这样。

    一个更完整的示例,展示了如何将此模式集成到应用程序中:

    look :: World -> IO World
    look w = do
      putStrLn $ "You see these items here: " ++ show w
      return w
    
    loop w = do
      words <- fmap words getLine
      case words of
        ("quit":_) -> return ()
        ("look":_) -> do w' <- look; loop w'
        ("remove":item:_) -> do w' <- removeItem item w; loop w'
        _ -> do putStrLn "huh?"; loop w
    
    main = do
      let world0 = ["chair", "bucket"] -- the initial world
      loop world0