それが機能しなかった理由は、あなたの後に別の ものが必要だったからです。(後は、ではなく式が必要です。)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])
しかし、実際にはリストに対して何もしないため、それでもコンパイルされません。すべてのブロックの終わりに、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)
この| boolean test =
構文は、入力に基づく条件付き回答に適しています。
アイテムのリストではなく、ランダムに1つのアイテムを選択しているため、に変更[list]
しました。Haskellは、1文字の文字列が一致するため、item
を入れてくれてとてもうれしいです。たとえば、「h」は。の略であるため、。それより長い文字列はあなたに与えます。特に、指定したすべての食品には複数の文字が含まれているため、この定義では機能しません。あなたの表現によって返されるものと一致するので、それは問題ありません。[list]
[list]
"h" = [list]
list='h'
['h']
Pattern match failure
randomFood
item
randomRIO
インポート<$>
して使用しませんでしたが、優れた演算子なので、に置き換えfmap f iothing
ましたf <$> 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
randomFood
これにより、入力がどのように見えるかに応じて3つの異なる定義が与えられます。
putStrLn (show (item))
ここでは、 -に置き換えました。putStrLn . show $ item
関数show
を作成し、それputStrLn
をに適用します($
)item
。