现在我稍微改进了代码,删掉了一些东西,等等。
这是源代码:
import Prelude
{-- DEFINE THE TYPES --}
data Tile = Tile -- the tiles of the map
{char :: Char
,isBlocking :: Bool
,position :: (Int,Int)}
type Dungeon = [Tile] -- the dungeon
{-- THE MAIN FUNCTION --}
main :: IO ()
main = do
let theDungeon :: Dungeon
theDungeon = mkDungeon 0 0 []
writeFile "./test.log" $ show theDungeon
{-- DEFINE THE SIZE OF THE MAP --}
screenX = 80
screenY = 24
mapX = screenX
mapY = screenY - 4
{-- THE FUNCTIONS FOR THE DUNGEON --}
mkDungeon :: Int -> Int -> Dungeon -> Dungeon -- function for generating the dungeon
mkDungeon x y dungeon =
if x > mapX -- looks if the line isn't too long
then mkDungeon 0 (y + 1) dungeon -- it's too long, so make the next line
else if y == 0 -- if it at the top
then mkDungeon (x + 1) y $ dungeon ++ [Tile '#' True (x, y)}
else if y > 0 && y < mapY -- looks if the line is in the middle
then if x == 0 || x == mapX -- is it at the right or at the left
then mkDungeon (x + 1) y $ dungeon ++ [Tile '#' True (x, y)]
else mkDungeon (x + 1) y $ dungeon ++ Tile '.' False (x, y)]
else if y == mapX -- looks if it is at the bottom
then do mkDungeon (x + 1) y $ dungeon ++ [Tile '#' True (x, y)]
else return $ dungeon :: Dungeon
所以现在,当我尝试编译它时,我变成了这个错误:
main.hs:42:26:
Couldn't match type ‘[Tile]’ with ‘Tile’
Expected type: Dungeon
Actual type: [Dungeon]
In the expression: return $ dungeon :: Dungeon
In the expression:
...
据我了解,它试图返回一个列表的列表,但它不会导致:
mkDungeon :: Int -> Int -> Dungeon -> Dungeon
但如果我写
else return $ dungeon
相反,我收到此错误:
main.hs:42:26:
Couldn't match type ‘[Tile]’ with ‘Tile’
Expected type: Dungeon
Actual type: [Dungeon]
In the expression: return $ dungeon
...
当我在没有
$
的情况下编写它时,我明白了:main.hs:42:26:
Couldn't match type ‘[Tile]’ with ‘Tile’
Expected type: Tile
Actual type: Dungeon
In the expression: return dungeon
...
那么我怎样才能将它作为地牢类型返回呢?
最佳答案
main = do
let theDungeon :: Dungeon
theDungeon <- mkDungeon 0 0 []
writeFile "./test.log" $ show theDungeon
如果我们从中删除语法糖,我们会得到:
main =
let
theDungeon :: Dungeon
in
mkDungeon 0 0 [] >>= \theDungeon ->
writeFile "./test.log" $ show theDungeon
错误消息提示的是
let
block 包含 theDungeon
的类型签名,但没有实际定义。下一个问题是 mkDungeon 0 0 []
产生一个 Dungeon
类型的值,这不是一个单子(monad),所以你不能使用 >>=
(以及扩展名 <-
)。要正确定义
theDungeon
,您需要使用 =
而不是 <-
( <-
用于从 monads 中“提取”值,并且使用 >>=
对其进行脱糖, =
用于 let
(和全局)绑定(bind)') let
block 。所以:main = do
let theDungeon :: Dungeon
theDungeon = mkDungeon 0 0 []
writeFile "./test.log" $ show theDungeon
或者你可以跳过类型签名,只写
let theDungeon = mkDungeon 0 0 []
。
关于haskell - 当我尝试返回列表时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37927780/