簡體   English   中英

嘗試打印出隨機 IP 列表,但在 Haskell 中不斷遇到錯誤

[英]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調用randomIPrandomIP的結果在 IO 中。 因此, createList的結果也必須在 IO 中。 所以將createList:: Int -> [[Char]] -> [[Char]]更改為createList:: Int -> [[Char]] -> IO [[Char]]

第二個問題:由於createList的結果在 IO 中,因此對自身的遞歸調用必須解開 IO。 所以將let mylist3 = createList (n-1) mylist2mylist3 <- createList (n-1) mylist2

第三個問題:由於createList的結果在 IO 中,所以main對其的調用必須解開 IO。 所以將let mylist = createList maxtests []更改為mylist <- createList maxtests []

通過所有這些更改,它可以編譯。


獎金材料如下:

另外,請注意,您不必要地重新實現了 Haskell 中已內置的一些函數: replicateMintercalatemap

要使用intercalatemap ,請更改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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM