试图打印出随机IP列表,但在Haskell中不断遇到错误

试图打印出随机IP列表,但在Haskell中不断遇到错误,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

我在哈斯凯尔不是很有经验,所以我不太确定到底发生了什么。我想生成一个随机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
   |     ^^^^^^^^^^^^^^
导入系统随机(randomRIO)
导入数据。列表
进口管制
main::IO()
main=do
设maxtests=5
让mylist=createList maxtests[]
表单uuMyList$\ip->do
打印ip
createList::Int->[[Char]]->[[Char]]
createList 0 mylist=返回mylist
createList n mylist=do
myarr IO([Int])
randomIp 0=返回[]
随机数n=do

r您的问题都源于未正确处理IO

第一个问题:
createList
调用
randomIP
,而
randomIP
的结果是在IO中。因此,
createList
的结果也必须在IO中。因此,将
createList::Int->[[Char]]->[[Char]]]
更改为
createList::Int->[[Char]]->IO[[Char]]]

第二个问题:由于
createList
的结果在IO中,因此对自身的递归调用必须打开IO。因此,将mylist3=createList(n-1)mylist2更改为mylist3 IO[[Char]] createList n=replicItem n$do myarr IO[Int] randomIp n=复制项n$do 里欧[Int] randomIp n=replicateM n$randomRIO(0255)
我相信你的意思是
mylist@Vlam-Yep,现已修复。@Vlam另外,我还编辑了一些额外的技巧,其中一些你可能会觉得有用。代码现在看起来非常简单和干净。谢谢!!
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)