Haskell无法从“:”cons运算符获取正确的类型

Haskell无法从“:”cons运算符获取正确的类型,haskell,Haskell,我遇到了一个错误,我试图在深度优先搜索算法中使用map来测试路径,以将目标单元包含在一个无方向且无循环的迷宫中。我遇到的麻烦是map的递归调用 这是我的密码: type Maze = [[Cell]] data Cell = Cell { top, left, right, bottom :: Bool } type Pos = (Int, Int) type Path = [Pos] findPath :: Maze -> Path findPath [] = [] findPa

我遇到了一个错误,我试图在深度优先搜索算法中使用map来测试路径,以将目标单元包含在一个无方向且无循环的迷宫中。我遇到的麻烦是map的递归调用

这是我的密码:

type Maze = [[Cell]]

data Cell = Cell { top, left, right, bottom :: Bool }

type Pos = (Int, Int)

type Path = [Pos]

findPath :: Maze -> Path
findPath [] = []
findPath  maze = dfs maze [] (-1,-1) (1,1) 

dfs :: Maze ->Path -> Pos -> Pos -> Path
dfs maze trail prev curr  
    | (curr == goal) = reverse $ goal : trail -- ?
    | (null adj)     = []
    | otherwise      = dfs maze (curr : trail) curr `map` (adj c (fst curr) (snd curr) prev)
    where   c = maze!!(fst curr- 1)!!(snd curr - 1)
            goal = (length maze, length (maze!!0))



adj:: Cell -> Int -> Int -> Pos ->Path
adj c x y prev =     if (top c && prev /= (x-1, y)) then [(x-1, y)] else [] ++  
                     if (left c && prev /= (x, y-1)) then [(x, y-1)] else [] ++  
                     if (right c && prev /= (x, y+1)) then [(x, y+1)] else [] ++  
                     if (bottom c && prev /= (x+1, y)) then [(x+1, y)] else []
我对dfs迷宫curr:trail curr'map'adj c fst curr snd curr prev的期望是,我将函数f::Pos->trail应用于[Pos]中的每个元素,但curr:trail给出的是[Path]而不是路径

错误堆栈给我的信息如下:

stack: WARNING! Expecting stack options comment at line 1, column 1
stack: WARNING! Missing or unusable stack options specification
stack: WARNING! Using runghc without any additional stack options

SolveMaze.hs:77:24: error:
    * Couldn't match type `[Pos]' with `(Int, Int)'
      Expected type: Path
        Actual type: [Path]
    * In the expression:
        dfs maze (curr : trail) curr
          `map` (adj c (fst curr) (snd curr) prev)
      In an equation for `dfs':
          dfs maze trail prev curr
            | (curr == goal) = reverse $ goal : trail
            | (null adj) = []
            | otherwise
            = dfs maze (curr : trail) curr
                `map` (adj c (fst curr) (snd curr) prev)
            where
                c = maze !! (fst curr - 1) !! (snd curr - 1)
                goal = (length maze, length (maze !! 0))
   |
77 |     | otherwise      = dfs maze (curr : trail) curr `map` (adj c (fst curr)
 (snd curr) prev)
   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^

如果这真的是哈斯凯尔巫师们的基本问题,我很抱歉,但我已经盯着这个太久了,我无法接受,需要寻求帮助。谢谢。

让我们放大两行。首先是dfs的类型:

dfs :: Maze ->Path -> Pos -> Pos -> Path
因此,当完全应用dfs时,会返回一条路径,非常好

我们还有dfs的定义,它必须返回路径,即:

dfs maze (curr : trail) curr `map` (adj c (fst curr) (snd curr) prev)
或者通过一些简化来明确发生了什么:

map (dfs and some args) (some list)
因此dfs必须返回一个路径,类型是这样说的,但定义将其显示为返回一个路径列表

您似乎想要的是尝试下降到一个相邻的位置,执行深度优先搜索,然后下降到下一个可能的路径,利用沿途的惰性评估-太棒了

让我们将dfs更改为返回路径列表[Path]——如果找到死胡同,将是解决方案或非解决方案的列表[]。更改反向。。。到[反向…]。并映射到concatMap

问一个函数是否为空是没有意义的,我认为你需要修改adj的应用程序,比如null adj c fst curr

Find path现在必须从dfs返回的解决方案列表中选择一个,第一个就足够了。您可以使用listToMaybe获得可能的路径结果

如果你愿意的话,你还可以清理很多其他的东西

[]表示失败的路径,而不是可能的路径。如果第一次深度优先搜索失败,则返回的解决方案将为[]。 使用!!假设输入不是锯齿状的。可以使用数组。 adj的详细定义,可以使用防护。
请不要发布文本图像,而是发布文本。@ThomasM.DuBuisson我现在已经编辑并修复了此错误是因为dfs迷宫curr:trail curr`map`adj c fst curr snd curr prev是一个路径列表。要看到这一点,请记住dfs迷宫curr:trail curr::Pos->Path和map::a->b->[a]->[b],在本例中,我们有b~路径,因此我们以[Path]结束。如何解决这一问题取决于您想要实现的目标,可能是头部,可能是使用listToMaybethus,在没有路径时返回可能路径而不是错误。另外,null adj上面的一行也不会编译,因为adj是一个函数。@M.Aroosi好的,我明白你的意思了,我必须阅读一些文章,了解如何在我的问题背景下准确地解决这个问题。你的帖子帮了我很大的忙,我对它写得多么好印象深刻,但我现在进入了一个序幕负索引错误令人沮丧,因为没有引用行号,并且消除Pos类型中出现负值的可能性仍然会导致错误
import Data.Maybe (listToMaybe)

type Maze = [[Cell]]    
data Cell = Cell { top, left, right, bottom :: Bool }    
type Pos = (Int, Int)    
type Path = [Pos]

findPath :: Maze -> Maybe Path
findPath [] = Just []
findPath  maze = listToMaybe $ dfs maze [] (-1,-1) (1,1)

dfs :: Maze ->Path -> Pos -> Pos -> [Path]
dfs maze trail prev curr
    | (curr == goal) = [reverse $ goal : trail] -- ?
    | (null adjVal)  = []
    | otherwise      = dfs maze (curr : trail) curr `concatMap` adjVal
    where   c = maze!!(fst curr- 1)!!(snd curr - 1)
            goal = (length maze, length (maze!!0))
            adjVal = adj c (fst curr) (snd curr) prev

adj:: Cell -> Int -> Int -> Pos ->Path
adj c x y prev =     if (top c && prev /= (x-1, y)) then [(x-1, y)] else [] ++
                     if (left c && prev /= (x, y-1)) then [(x, y-1)] else [] ++
                     if (right c && prev /= (x, y+1)) then [(x, y+1)] else [] ++
                     if (bottom c && prev /= (x+1, y)) then [(x+1, y)] else []