IOモナドの
https://wiki.haskell.org/99_questions/21_to_28 の "Problem 23" を参考に
以下のようなコードを作成しました。
("abcdefgh" の中からランダムに 3 文字表示するプログラム)
[コード1]
これは想定通り動作しました。
この関数を少し変えて、`>>=` を使用するように変更しました。
[コード2]
この場合も問題ありません。
さらに、上記の
[コード3]
すると、以下のようにエラーとなります。
メッセージから考えて
問題なく動作しました。
[コード4]
説明が長くなってしまい恐縮ですが、`[コード3]` と
>>=
について質問させてくださいhttps://wiki.haskell.org/99_questions/21_to_28 の "Problem 23" を参考に
以下のようなコードを作成しました。
("abcdefgh" の中からランダムに 3 文字表示するプログラム)
[コード1]
import System.Random rnd_select :: [a] -> Int -> IO [a] rnd_select xs n = do let l = length xs - 1 ys <- sequence . replicate n $ (randomRIO (0, l) :: IO Int) return $ map (xs !!) ys
これは想定通り動作しました。
ghci> rnd_select "abcdefgh" 3 >>= putStrLn efc it :: ()
この関数を少し変えて、`>>=` を使用するように変更しました。
[コード2]
rnd_select xs n = f >>= return . map (xs !!) where l = length xs - 1 f = sequence . replicate n $ (randomRIO (0, l) :: IO Int)
この場合も問題ありません。
さらに、上記の
f
の部分を (where 句ではなく) 直接書いて以下のように変更しました。[コード3]
rnd_select xs n = sequence . replicate n $ (randomRIO (0, l) :: IO Int) >>= return . map (xs !!) where l = length xs - 1
すると、以下のようにエラーとなります。
ghci> :l d [1 of 2] Compiling Main ( d.hs, interpreted ) d.hs:5:86: error: [GHC-83865] • Couldn't match type '[Int]' with 'Int' Expected: Int -> a Actual: [Int] -> [a] • In the second argument of '(.)', namely 'map (xs !!)' In the second argument of '(>>=)', namely 'return . map (xs !!)' In the second argument of '($)', namely '(randomRIO (0, l) :: IO Int) >>= return . map (xs !!)' | 5 | rnd_select xs n = sequence . replicate n $ (randomRIO (0, l) :: IO Int) >>= return . map (xs !!) | ^^^^^^^^^^^ Failed, no modules loaded.
メッセージから考えて
[Int]
ではなく Int
が要求されているようだったので、以下のように変更したところ問題なく動作しました。
[コード4]
rnd_select xs n = sequence . replicate n $ (randomRIO (0, l) :: IO Int) >>= return . (xs !!) where l = length xs - 1
説明が長くなってしまい恐縮ですが、`[コード3]` と
[コード4]
のような違いが出る理由が理解できませんでした。