【问题标题】:How to call multiple functions inside another function in Haskell?如何在 Haskell 的另一个函数中调用多个函数?
【发布时间】:2014-11-10 16:03:17
【问题描述】:

我在 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'

我想调用“区域”函数来返回在 main 中输入的地点,并调用 describe 函数来返回该地点的描述。我该怎么做?

【问题讨论】:

  • 这是一个用 Haskell 编写的简单冒险游戏,可能有助于程序组织:link
  • 不应该areadescribe 分别具有String -&gt; IO StringString -&gt; IO () 类型吗?你在这些函数中使用了returnputStrLn,所以它们必须返回一个单子值

标签: haskell


【解决方案1】:

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

  • 您在哪里,以及
  • 你有什么东西

所以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...

【讨论】:

    【解决方案2】:

    如果您想保持两个函数(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
    

    但是,这完全是在错误的方向。这不是 Haskell 惯用的做事方式。本质上,您是在用函数式语言重现命令式代码。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-29
      • 1970-01-01
      • 2018-07-02
      • 2018-12-02
      • 1970-01-01
      • 2018-07-27
      • 1970-01-01
      • 2011-05-30
      相关资源
      最近更新 更多