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] のような違いが出る理由が理解できませんでした。