为什么函数需要IO [data]而不是[[data]] Haskell

gcuhipw9  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(157)

下列程式码会因为这个错误而失败。
第一个
我的问题是,为什么loopStage函数需要一个IO值?它被明确地标记为Octopus
我尝试删除迭代,这使得错误消息更加明确。

main.hs:30:5: error:
    • Couldn't match type ‘[]’ with ‘IO’
      Expected: IO [Octopus]
        Actual: [[Octopus]]

经过进一步的调试,似乎错误出在函数的返回类型上,它返回的是一个非IO的Octopus matrix版本?这是我第一次写Haskell。我试着用IO Package 所有的返回值,但是没有找到解决办法

i5desfxk

i5desfxk1#

我的问题是,为什么loopStage函数需要一个IO值?它被清楚地标记为[[Octopus]]
实际上,loopStage函数不需要IO。问题出在别处。
让我们把注意力集中在这些线条上。

contents <- readFile "input.txt"
    -- ...        
    iterate loopStage octopusMatrix !! 100

在这个do区块中,readFile会传回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]]

这意味着“您正试图将类型为[[Octopus]] -> [[Octopus]]loopStage传递给函数(iterate),而该函数要求的类型为IO a0 -> IO a0“。
如何解决这个问题?必须避免试图“运行”iterate的结果,就好像它是一个IO操作:

let newOctopusMatrix = iterate loopStage octopusMatrix !! 100
print newOctopusMatrix

相关问题