[英]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.