在递归中应用Haskell映射函数

时间:2019-09-29 00:08:39

标签: dictionary haskell recursion backtracking

最近我一直在做一些Haskell。我需要生成所有可能的字符串,也就是给定[String],我应该输出[[String]]

solveGame :: [String] -> [[String]]
solveGame ts = recGame [] ts
  where recGame xs [] = [xs]
        recGame xs (t:ts) = map (recGame (xs ++ ) ts) [[x] | x <- (gen t)]

其中,gen输出所有可能重复出现的字符串数,因此, gen :: String -> [String]。因此,基本上,问题是置换gen生成的所有可能的字符串。我试图运行我的版本,但输出错误。这样行可以吗?

solveGame的输入将为星的矩阵n * n (例如["**", "**"]),并且输出应为所有可能的矩阵的列表,并用1和0填充(此列表将包含16个矩阵,例如["10", "01"]

我遇到的错误:

Takuzu.hs:15:16: error:
    • Couldn't match expected type ‘[[String]]’
                  with actual type ‘[String] -> [a1]’
    • Probable cause: ‘recGame’ is applied to too few arguments
      In the expression: recGame [] ts
      In an equation for ‘solveGame’:
          solveGame ts
            = recGame [] ts
            where
                recGame xs [] = [xs]
                recGame xs (t : ts)
                  = map (recGame (xs ++) ts) [[...] | x <- (gen t)]
   |
15 | solveGame ts = recGame [] ts
   |                ^^^^^^^^^^^^^

Takuzu.hs:15:24: error:
    • Couldn't match expected type ‘[a1] -> [a1]’
                  with actual type ‘[a0]’
    • In the first argument of ‘recGame’, namely ‘[]’
      In the expression: recGame [] ts
      In an equation for ‘solveGame’:
          solveGame ts
            = recGame [] ts
            where
                recGame xs [] = [xs]
                recGame xs (t : ts)
                  = map (recGame (xs ++) ts) [[...] | x <- (gen t)]
   |
15 | solveGame ts = recGame [] ts
   |                        ^^

Takuzu.hs:16:9: error:
    • Couldn't match type ‘[a]’ with ‘[a] -> [a]’
      Expected type: ([a] -> [a]) -> [String] -> [String] -> [a]
        Actual type: [a] -> [String] -> [[a]]
    • In an equation for ‘solveGame’:
          solveGame ts
            = recGame [] ts
            where
                recGame xs [] = [xs]
                recGame xs (t : ts)
                  = map (recGame (xs ++) ts) [[...] | x <- (gen t)]
    • Relevant bindings include
        recGame :: ([a] -> [a]) -> [String] -> [String] -> [a]
          (bound at Takuzu.hs:16:9)
   |
16 |   where recGame xs [] = [xs]
   |         ^^^^^^^^^^^^^^^^^^^^...
Failed, no modules loaded.

1 个答案:

答案 0 :(得分:2)

看着错误消息,看起来GHC正在为recGame推断错误的类型。 (我怎么知道的?这是因为每次错误消息中提到recGame时,都有很多[a] -> [a]的东西,看起来并不正确。)因此,作为第一步,让我们添加类型签名:

solveGame :: [String] -> [[String]]
solveGame ts = recGame [] ts
  where 
    recGame :: [String] -> [String] -> [[String]]
    recGame xs [] = [xs]
    recGame xs (t:ts) = map (recGame (xs ++ ) ts) [[x] | x <- (gen t)]

执行此操作后,我们会得到一些更有用的错误消息:

so.hs:10:30: error:
    • Couldn't match expected type ‘[String] -> [String]’
                  with actual type ‘[[String]]’
    • Possible cause: ‘recGame’ is applied to too many arguments
      In the first argument of ‘map’, namely ‘(recGame (xs ++) ts)’
      In the expression: map (recGame (xs ++) ts) [[x] | x <- (gen t)]
      In an equation for ‘recGame’:
          recGame xs (t : ts) = map (recGame (xs ++) ts) [[x] | x <- (gen t)]
   |
10 |     recGame xs (t:ts) = map (recGame (xs ++ ) ts) [[x] | x <- (gen t)]
   |                              ^^^^^^^^^^^^^^^^^^^

so.hs:10:39: error:
    • Couldn't match expected type ‘[String]’
                  with actual type ‘[String] -> [String]’
    • In the first argument of ‘recGame’, namely ‘(xs ++)’
      In the first argument of ‘map’, namely ‘(recGame (xs ++) ts)’
      In the expression: map (recGame (xs ++) ts) [[x] | x <- (gen t)]
   |
10 |     recGame xs (t:ts) = map (recGame (xs ++ ) ts) [[x] | x <- (gen t)]
   |                                       ^^^^^

因此,在(t:ts)情况下,您似乎将(xs++)作为recGame的参数—但是{​​{1}}是一个函数,因此您可以不要那样做!我不知道您要在这里做什么,所以我无法提出修复建议,但这绝对是错误,应该修复。