haskell - 当我尝试返回列表时出错

标签 haskell compiler-errors roguelike

现在我稍微改进了代码,删掉了一些东西,等等。
这是源代码:

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/

相关文章:

haskell - 在haskell中处理事件流

java - 在“问题”选项卡 Eclipse 中保存错误

compiler-errors - 在Ubuntu中为CoolC编译器安装VirtualBox时出错

c++ - 如何使用 ncurses 库让 Player 与 Monster 交互?

java - 使用 Java 在带有面板的网格中显示 ASCII 的最佳方法是什么?

java - 如何用java中的OOP设计一个RPG类系统?

haskell - 如何确定 Haskell 中类型的大小?

haskell - 如何在 Haskell 的多播连接中指定源地址?

haskell - 如何横向和向下 build 一棵树?

laravel - [Vue警告] : Error compiling template: invalid expression: Unexpected token >