以下代碼因此錯誤而失敗。
main.hs:30:13: error:
? Couldn't match type: [[Octopus]]
with: IO a0
Expected: IO a0 -> IO a0
Actual: [[Octopus]] -> [[Octopus]]
? In the first argument of ‘iterate’, namely ‘loopStage’
In the first argument of ‘(!!)’, namely
‘iterate loopStage octopusMatrix’
In a stmt of a 'do' block: iterate loopStage octopusMatrix !! 100
|
30 | iterate loopStage octopusMatrix !! 100
|
module Main where
data Octopus = Octopus {
level :: Int,
hasFlashed :: Int
} deriving (Show)
incrementOctopusEnergyLevelByOne :: Octopus -> Octopus
incrementOctopusEnergyLevelByOne (Octopus level hasFlashed) =
Octopus (level 1) hasFlashed
incrementOctopusListEnergyLevelByOne :: [Octopus] -> [Octopus]
incrementOctopusListEnergyLevelByOne = map incrementOctopusEnergyLevelByOne
increaseAllEnergyLevel :: [[Octopus]] -> [[Octopus]]
increaseAllEnergyLevel = map incrementOctopusListEnergyLevelByOne
loopStage :: [[Octopus]] -> [[Octopus]]
loopStage octopus_matrix = do
increaseAllEnergyLevel octopus_matrix
main = do
contents <- readFile "input.txt"
let fileLines = lines contents
let matrix = parseListOfStringsToMatrixOfIntegers fileLines
let octopusMatrix = convertMatrixToOctopusMatrix matrix
iterate loopStage octopusMatrix !! 100
print octopusMatrix
parseStringToListOfIntegers :: String -> [Int]
parseStringToListOfIntegers string = map (read . (:"")) string :: [Int]
parseListOfStringsToMatrixOfIntegers :: [String] -> [[Int]]
parseListOfStringsToMatrixOfIntegers = map parseStringToListOfIntegers
convertIntToOctopus :: Int -> Octopus
convertIntToOctopus value = Octopus value 0
convertListOfIntsToListOctopus :: [Int] -> [Octopus]
convertListOfIntsToListOctopus = map convertIntToOctopus
convertMatrixToOctopusMatrix :: [[Int]] -> [[Octopus]]
convertMatrixToOctopusMatrix = map convertListOfIntsToListOctopus
我的問題是,為什么 loopStage 函式需要一個 IO 值?它清楚地標記為[[Octopus]]。
我嘗試洗掉迭代,這使錯誤訊息更加明確。
main.hs:30:5: error:
? Couldn't match type ‘[]’ with ‘IO’
Expected: IO [Octopus]
Actual: [[Octopus]]
進一步除錯后,似乎錯誤出在函式的回傳型別上,它回傳的是 [[Octopus]] 矩陣的非 IO 版本?這是我第一次寫 Haskell。我嘗試將所有回傳值包裝在 IO 中,但找不到解決方案
uj5u.com熱心網友回復:
我的問題是,為什么
loopStage函式需要一個IO值?它清楚地標記為[[Octopus]]。
事實上,該loopStage功能并不期望IO。問題在別處。
讓我們關注這些行。
contents <- readFile "input.txt"
-- ...
iterate loopStage octopusMatrix !! 100
在這個do塊中,readFile回傳一個值 inside IO。因此,Haskell 推斷iterate loopStage octopusMatrix !! 100必須有型別IO something。
現在,讓我們看一下iterate多型型別:
iterate :: (a -> a) -> a -> [a]
結果型別為
iterate loopStage octopusMatrix !! 100
那么必須是a(的元素型別[a],由`iterate回傳)。因此,我們必須有
iterate loopStage octopusMatrix !! 100 :: a
loopStage :: (a -> a)
octopusMatrix :: a
a = IO something
因此,我們期望
loopStage :: IO something -> IO something
它處理的實際型別loopStage:
loopStage :: [[Octopus]] -> [[Octopus]]
請注意,GHC 錯誤訊息正是這樣說的:
Expected: IO a0 -> IO a0
Actual: [[Octopus]] -> [[Octopus]]
這意味著“您正在嘗試將loopStage具有型別的函式 ( ) 傳遞[[Octopus]] -> [[Octopus]]給函式 ( iterate),而函式 ( ) 需要一種形式的型別IO a0 -> IO a0”。
如何解決這個問題?必須避免嘗試“運行”結果,iterate就好像它是一個 IO 操作一樣:
let newOctopusMatrix = iterate loopStage octopusMatrix !! 100
print newOctopusMatrix
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/536675.html
標籤:哈斯克尔
下一篇:了解“newtype”關鍵字
