簡體   English   中英

讀取IO字符串並在Haskell中返回自定義數據類型列表

[英]Read IO String and return custom data type list in Haskell

我是Haskell的初學者,並且在IO操作方面遇到困難。 我應該從用戶那里獲取IO String,直到用戶發送“。”為止。 (點)字符。 我將使用這些輸入來通過解析字符串來轉換自定義數據類型,命名卡。 然后將卡添加到列表中。 當用戶鍵入“。”時,我將發送整個卡列表。 Haskell代碼如下:

readCards :: IO [Card]
readCards = return (returnCardList [])
    where 
        returnCardList :: [Card] -> [Card]
        returnCardList acc =  do line <- getLine
                                 if line == "."
                                 then acc
                                 else returnCardList ((convertCard (line !! 0) (line !! 1)):acc)

convertCard是一個需要兩個char並返回Card的函數。 也是acc代表尾部遞歸函數的累加器(不必使用尾部遞歸來實現,我只是選擇了它)。

例如returnCardList 'h' 'q'給出Card {suit=Hearts, rank=Queen}

但是上面的代碼分區給出了一個錯誤:

 Couldn't match type `IO' with `[]'
 Expected type: [String]
 Actual type: IO String

但是下面的代碼(帶有虛擬卡列表)可以正常運行:

readCards :: IO [Card]
readCards = return [Card {suit=Clubs, rank=King}, Card {suit=Clubs, rank=Ace}, Card {suit=Clubs, rank=Jack}]

我讀了很多東西,但無法解決。 我真的很想知道我想念什么。

這段代碼

readCards :: IO [Card]
readCards = return (returnCardList [])

指出readCards是實際上不做IO的IO計算。 實際上, return something表示未執行任何IO,並且something[Card]類型的純值。

這不是您想要的。 你需要類似的東西

readCards :: IO [Card]
readCards = returnCardList []

因此,IO必須由returnCardList完成,該類型現在必須具有

returnCardList :: [Card] -> IO [Card]
                         -- ^^ we do perform IO here!

您自己的實現應該可以正常工作

    returnCardList acc = do 
       line <- getLine
       if line == "."
       then return acc
         -- ^^^^^^ turn the plain value into an IO computation
       else returnCardList ((convertCard (line !! 0) (line !! 1)):acc)

可以這樣重寫:

    returnCardList acc = do 
       line <- getLine
       case line of
          "." -> return acc
          (c1:c2:_) -> returnCardList (convertCard c1 c2 : acc)
          _ -> ... -- you should handle here the other cases (length < 2)

請注意,您也可以不使用acc參數:

    returnCardList = do 
       line <- getLine
       case line of
          "." -> return []
          (c1:c2:_) -> (convertCard c1 c2 :) <$> returnCardList
          _ -> ... -- you should handle here the other cases (length < 2)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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