[英]Trying to print out a list of random IPs but keep encountering errors in Haskell
I am not very experienced in Haskell so I am not too sure what's going on.我对 Haskell 不是很有经验,所以我不太确定发生了什么。 I want to generate a list of random IP addresses and print them out but I keep encountering the errors below:
我想生成一个随机 IP 地址列表并将它们打印出来,但我一直遇到以下错误:
My code:我的代码:
import System.Random (randomRIO)
import Data.List
import Control.Monad.Cont
main :: IO ()
main = do
let maxtests = 5
let mylist = createList maxtests []
forM_ mylist $ \ip -> do
print ip
createList :: Int -> [[Char]] -> [[Char]]
createList 0 mylist = return mylist
createList n mylist = do
myarr <- randomIp 4
let myip = (show (myarr !! 0)) ++ "." ++ (show (myarr !! 1)) ++ "." ++ (show (myarr !! 2)) ++ "." ++ (show (myarr !! 3))
let mylist2 = mylist ++ [myip]
let mylist3 = createList (n-1) mylist2
return mylist3
randomIp :: Int -> IO([Int])
randomIp 0 = return []
randomIp n = do
r <- randomRIO (0,255)
rs <- randomIp (n-1)
return (r:rs)
Error messages when I compile:我编译时的错误消息:
test2.hs:13:23: error:
* Couldn't match type `[Char]' with `Char'
Expected type: [[Char]]
Actual type: [[[Char]]]
* In the expression: return mylist
In an equation for `createList':
createList 0 mylist = return mylist
|
13 | createList 0 mylist = return mylist
| ^^^^^^^^^^^^^
test2.hs:15:14: error:
* Couldn't match type `IO' with `[]'
Expected type: [[Int]]
Actual type: IO [Int]
* In a stmt of a 'do' block: myarr <- randomIp 4
In the expression:
do myarr <- randomIp 4
let myip
= (show (myarr !! 0))
++
"."
++
(show (myarr !! 1))
++ "." ++ (show (myarr !! 2)) ++ "." ++ (show (myarr !! 3))
let mylist2 = mylist ++ ...
let mylist3 = createList (n - 1) mylist2
....
In an equation for `createList':
createList n mylist
= do myarr <- randomIp 4
let myip = ...
let mylist2 = ...
....
|
15 | myarr <- randomIp 4
| ^^^^^^^^^^
test2.hs:19:5: error:
* Couldn't match type `[Char]' with `Char'
Expected type: [[Char]]
Actual type: [[[Char]]]
* In a stmt of a 'do' block: return mylist3
In the expression:
do myarr <- randomIp 4
let myip
= (show (myarr !! 0))
++
"."
++
(show (myarr !! 1))
++ "." ++ (show (myarr !! 2)) ++ "." ++ (show (myarr !! 3))
let mylist2 = mylist ++ ...
let mylist3 = createList (n - 1) mylist2
....
In an equation for `createList':
createList n mylist
= do myarr <- randomIp 4
let myip = ...
let mylist2 = ...
....
|
19 | return mylist3
| ^^^^^^^^^^^^^^
Would appreciate any pointers on what I'm doing wrong.将不胜感激任何关于我做错了什么的指示。
Your problems all stem from not handling IO correctly.您的问题都源于未正确处理 IO 。
First problem: createList
calls randomIP
, and randomIP
's result is in IO.第一个问题:
createList
调用randomIP
, randomIP
的结果在 IO 中。 Thus, createList
must have its result in IO too.因此,
createList
的结果也必须在 IO 中。 So change createList:: Int -> [[Char]] -> [[Char]]
to createList:: Int -> [[Char]] -> IO [[Char]]
.所以将
createList:: Int -> [[Char]] -> [[Char]]
更改为createList:: Int -> [[Char]] -> IO [[Char]]
。
Second problem: Since createList
's result is in IO, the recursive call to itself must unwrap the IO.第二个问题:由于
createList
的结果在 IO 中,因此对自身的递归调用必须解开 IO。 So change let mylist3 = createList (n-1) mylist2
to mylist3 <- createList (n-1) mylist2
.所以将
let mylist3 = createList (n-1) mylist2
为mylist3 <- createList (n-1) mylist2
。
Third problem: Since createList
's result is in IO, main
's call to it must unwrap the IO.第三个问题:由于
createList
的结果在 IO 中,所以main
对其的调用必须解开 IO。 So change let mylist = createList maxtests []
to mylist <- createList maxtests []
.所以将
let mylist = createList maxtests []
更改为mylist <- createList maxtests []
。
With all of those changes, it compiles.通过所有这些更改,它可以编译。
Bonus material below here:奖金材料如下:
Also, note that you've unnecessarily reimplemented a few functions that are already built in to Haskell: replicateM
, intercalate
, and map
.另外,请注意,您不必要地重新实现了 Haskell 中已内置的一些函数:
replicateM
、 intercalate
和map
。
To make use of intercalate
and map
, change let myip = (show (myarr.. 0)) ++ "." ++ (show (myarr !! 1)) ++ "." ++ (show (myarr !! 2)) ++ "." ++ (show (myarr !! 3))
要使用
intercalate
和map
,请更改let myip = (show (myarr.. 0)) ++ "." ++ (show (myarr !! 1)) ++ "." ++ (show (myarr !! 2)) ++ "." ++ (show (myarr !! 3))
let myip = (show (myarr.. 0)) ++ "." ++ (show (myarr !! 1)) ++ "." ++ (show (myarr !! 2)) ++ "." ++ (show (myarr !! 3))
let myip = (show (myarr.. 0)) ++ "." ++ (show (myarr !! 1)) ++ "." ++ (show (myarr !! 2)) ++ "." ++ (show (myarr !! 3))
to let myip = intercalate "." (map show myarr)
let myip = (show (myarr.. 0)) ++ "." ++ (show (myarr !! 1)) ++ "." ++ (show (myarr !! 2)) ++ "." ++ (show (myarr !! 3))
let myip = intercalate "." (map show myarr)
let myip = intercalate "." (map show myarr)
. let myip = intercalate "." (map show myarr)
。
Making use of replicateM
requires much larger changes, so I'll just show you the result:使用
replicateM
需要更大的更改,所以我将向您展示结果:
import System.Random (randomRIO)
import Data.List
import Control.Monad.Cont
main :: IO ()
main = do
let maxtests = 5
mylist <- createList maxtests
forM_ mylist $ \ip -> do
print ip
createList :: Int -> IO [[Char]]
createList n = replicateM n $ do
myarr <- randomIp 4
let myip = intercalate "." (map show myarr)
return myip
randomIp :: Int -> IO [Int]
randomIp n = replicateM n $ do
r <- randomRIO (0,255)
return r
You can even continue the refactoring further if you want, to something like this:如果您愿意,您甚至可以继续进一步重构,如下所示:
import System.Random (randomRIO)
import Control.Monad
import Data.Foldable
import Data.List
main :: IO ()
main = do
let maxtests = 5
mylist <- createList maxtests
for_ mylist print
createList :: Int -> IO [[Char]]
createList n = replicateM n $ intercalate "." . map show <$> randomIp 4
randomIp :: Int -> IO [Int]
randomIp n = replicateM n $ randomRIO (0,255)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.