从列表中获取一个字符串并将其保存到另一个列表中?

use*_*127 0 haskell

我正在尝试从字符串列表中获取一个随机项并将其保存到另一个字符串列表但我无法让我的代码工作.

    import System.Random
    import Control.Applicative ( (<$>) )

    food = ["meatballs and potoes","veggisoup","lasagna","pasta bolognese","steak and fries","salad","roasted chicken"]


    randomFood xs = do
              if (length xs - 1 ) > 0 then 
                 [list] <- (fmap (xs!!) $ randomRIO (0, length xs -1))
                 else
                 putStrLn (show([list])
Run Code Online (Sandbox Code Playgroud)

我在输入'< - '上得到解析错误,但我确定还有更多问题:/还有一个问题,列表可能连续两天包含相同的菜肴,这不是我想要的,我猜我可以删除重复项,但这也将删除列表中的项目数,我希望保持与列表中的数字相同.

任何人都知道我怎么能这样做?我一直在寻找一天,我找不到对我有用的东西,但那仅仅是因为我在错误的地方寻找.关于我如何能够做到这一点或在哪里可以找到信息的任何建议都将受到极大关注!

//问候

And*_*ewC 5

它不工作的原因是,你需要其他 do的以后if...then.(在then你需要表达之后,而不是pattern <- expression.)

randomFood :: String -> IO ()  -- type signature: take a String and do some IO.
randomFood xs = do
          if length xs > 1 then do
             [list] <- (fmap (xs!!) $ randomRIO (0, length xs -1))
             else
             putStrLn (show([list])
Run Code Online (Sandbox Code Playgroud)

但是仍然没有编译,因为你实际上没有对你的列表做任何事情.在每个do块的末尾,您需要一个表达式来返回.如果长度xs太短,我认为你仍打算打印一些东西,如果有多个可供选择,你可能打算打印所选的食物.

更好的是:

randomFood :: String -> IO () 
randomFood xs | length xs <= 1 = putStrLn $ show xs
randomFood xs | otherwise = do
             item <- (xs!!) <$> randomRIO (0, length xs -1)
             putStrLn $ show(item)
Run Code Online (Sandbox Code Playgroud)

| boolean test =对于基于输入的条件答案,此语法更好.

我改为[list],item因为你是随机选择一个项目,而不是项目列表.Haskell非常乐意让你放[list],因为任何有一个字符的字符串都匹配[list].例如,"h" = [list]如果list='h',因为"h"是简称['h'].任何更长的字符串都会给你Pattern match failure.特别是,你指定的所有食物都有不止一个字符,所以这个定义randomFood永远不会有效!item将匹配您的randomRIO表达式返回的任何内容,这样就可以了.

你导入<$>然后没有使用它,但它是一个不错的运算符,所以我已经替换fmap f iothingf <$> iothing.

我终于意识到我用短名单做错了; 如果我这样做,randomFood ["lump of cheese"]我会得到["lump of cheese"],这与randomFood ["lump of cheese"]我的不一致"lump of cheese".我认为我们应该将短列表与空列表分开,这使我们能够进行更多的模式匹配和更少的布尔值:

randomFood :: String -> IO () 
randomFood []        = putStrLn "--No food listed, sorry.--"
randomFood [oneitem] = putStrLn . show $ oneitem 
randomFood xs = do
         item <- (xs!!) <$> randomRIO (0, length xs -1)
         putStrLn . show $ item
Run Code Online (Sandbox Code Playgroud)

这给出了三种不同的定义,randomFood取决于输入的外观.

在这里,我也换成putStrLn (show (item))putStrLn . show $ item-组成的功能showputStrLn和应用($)即到item.