我是一个完整的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
答案 0 :(得分:9)
调查类型错误时,首先要记下你所知道的函数的类型签名。
这里,solve可以有类型
solve :: String -> String -> String -> [String] -> String
或
solve :: String -> String -> String -> [String] -> IO String
取决于在计算值时是否应该有任何副作用。在整个地方看到您使用mapM
和return
,我猜可能是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
来更改调用,代码编译并运行!唯一的问题是它将所有可能的句子连接成一个字符串而没有任何分隔。