haskell - 无法将预期类型与实际类型匹配

标签 haskell functional-programming

我是一个彻头彻尾的 Haskell 菜鸟,我希望有人能帮助我解决这个问题,因为我已经做了几个小时了,我只知道我正在做一些可笑的愚蠢的事情。

该程序应该扫描字典文件,以确定删除了空格的句子集合的所有有效单词序列。

例如。 “insidewaysoften”可以分割为“insidewayoften”、“insidewaysoften”等。

我用 python 编写了我的原型(prototype),它工作得很好(我的 Java 实现也是如此),但是该类(class)需要 Haskell 实现,而我无法让它工作。提前为我对语言和 GHC 犯下的罪行致歉,代码如下:

import System.Environment   

main = do
  [dictFilename,sentFilename] <- getArgs  
  dictFile <- readFile dictFilename
  sentFile <- readFile sentFilename

  mapM (\sentence -> solve "" "" sentence (words dictFile)) (words sentFile)

solve prefix header [] dict =
  if (header `elem` dict) 
  then return prefix ++ header
  else return ""

solve prefix header sent dict = do
  let more = solve prefix (header ++ (take 1 sent)) (drop 1 sent) dict

  if (header `elem` dict) 
  then return (solve (prefix ++ header ++ " ") "" sent dict) ++ more
  else return more

最佳答案

调查类型错误时的第一件事是写下您知道的函数的类型签名。

这里,solve可能有类型

solve :: String -> String -> String -> [String] -> String

solve :: String -> String -> String -> [String] -> IO String

取决于计算值时是否应该有任何副作用。看到您到处使用 mapMreturn,我猜 IO 版本可能是有意为之。

现在,如果您写下签名,您就会开始收到更有意义的错误消息。例如,而不是这样:

tmp.hs:19:16:
    Couldn't match expected type `Char' with actual type `[Char]'
    Expected type: [Char]
      Actual type: [[Char]]
    In the return type of a call of `solve'
    In the first argument of `return', namely
      `(solve (prefix ++ header ++ " ") "" sent dict)'

,这没有多大意义,你会得到:

tmp.hs:14:8:
    Couldn't match expected type `IO String' with actual type `[a0]'
    In the expression: return prefix ++ header
    In the expression:
      if (header `elem` dict) then return prefix ++ header else return ""
    In an equation for `solve':
        solve prefix header [] dict
          = if (header `elem` dict) then
                  return prefix ++ header
            else
                return ""

,它准确地表明了问题所在。函数应用在Haskell中具有最高优先级,因此return prefix++ header相当于(return prefix)++ header,这绝对不是你的意思。

顺便说一句,如果我从返回类型中删除 IO,请删除所有 return 并通过添加 putStrLn 更改调用,代码编译并运行!唯一的问题是它将所有可能的句子连接成一个字符串,没有任何分隔。

关于haskell - 无法将预期类型与实际类型匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5853129/

相关文章:

c - Haskell Foldr C 实现

Haskell:调试堆栈项目的长编译时间

haskell - Haskell中有态射吗?

javascript - 用简单的英语解释使用高阶函数的好处

C++ 函数对象模板参数推导风格

haskell - Haskell中使用NaN的最大值和最小值

haskell - 为什么 GeneralizedNewtype 不派生一个安全的 Haskell?

Haskell 在基本包中缺少文件

c++ - 使用模板函数将转换应用于具有索引的 vector

javascript - 使用 foreach 或带有 javascript 的 map 将复杂对象添加到数组中