[英]Trying to print out a list of random IPs but keep encountering errors in Haskell
我对 Haskell 不是很有经验,所以我不太确定发生了什么。 我想生成一个随机 IP 地址列表并将它们打印出来,但我一直遇到以下错误:
我的代码:
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)
我编译时的错误消息:
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
| ^^^^^^^^^^^^^^
将不胜感激任何关于我做错了什么的指示。
您的问题都源于未正确处理 IO 。
第一个问题: createList
调用randomIP
, randomIP
的结果在 IO 中。 因此, createList
的结果也必须在 IO 中。 所以将createList:: Int -> [[Char]] -> [[Char]]
更改为createList:: Int -> [[Char]] -> IO [[Char]]
。
第二个问题:由于createList
的结果在 IO 中,因此对自身的递归调用必须解开 IO。 所以将let mylist3 = createList (n-1) mylist2
为mylist3 <- createList (n-1) mylist2
。
第三个问题:由于createList
的结果在 IO 中,所以main
对其的调用必须解开 IO。 所以将let mylist = createList maxtests []
更改为mylist <- createList maxtests []
。
通过所有这些更改,它可以编译。
奖金材料如下:
另外,请注意,您不必要地重新实现了 Haskell 中已内置的一些函数: replicateM
、 intercalate
和map
。
要使用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))
let myip = intercalate "." (map show myarr)
let myip = intercalate "." (map show myarr)
。
使用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
如果您愿意,您甚至可以继续进一步重构,如下所示:
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.