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

dpi*_*ers 4 haskell functional-programming

我是一个完整的Haskell noob,我希望有人可以帮助我,因为我已经在这里工作了几个小时,我只知道我做了一些荒谬可笑的事情.

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

防爆."insidewaysoften"可以分解为"经常","内部软化"等.

我在python中编写了我的原型,它工作得很好(就像我的Java实现一样),但是这个课程需要一个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
Run Code Online (Sandbox Code Playgroud)

Rot*_*sor 9

调查类型错误时首先要记下你所知道的函数的类型签名.

这里,解决可能有类型

solve :: String -> String -> String -> [String] -> String
Run Code Online (Sandbox Code Playgroud)

要么

solve :: String -> String -> String -> [String] -> IO String
Run Code Online (Sandbox Code Playgroud)

取决于在计算值时是否应该有任何副作用.看到你使用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)'
Run Code Online (Sandbox Code Playgroud)

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

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 ""
Run Code Online (Sandbox Code Playgroud)

,它显示了问题的确切位置.函数应用程序在Haskell中具有最高优先级,因此return prefix ++ header相当于(return prefix) ++ header,这绝对不是您的意思.

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