无法将预期类型与实际类型匹配
我是一个彻头彻尾的 Haskell 菜鸟,我希望有人能帮助我解决这个问题,因为我已经做了几个小时了,我只知道我正在做一些可笑的愚蠢的事情。
该程序应该扫描字典文件,以确定删除了空格的句子集合的所有有效单词序列。
前任。 “insidewaysoften”可以分解为“insidewayoften”、“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
I am a total Haskell noob and I was hoping someone could help me with this because I've been at this for hours and I just know that I'm doing something ridiculously stupid.
The program is supposed to scan a dictionary file to determine all valid word sequences for a collection of sentences with spaces removed.
Ex. "insidewaysoften" could be broken down to "in side ways often", "inside way soften", etc.
I wrote my prototype in python and it works just fine (as does my Java implementation), but the course requires a Haskell implementation and I cannot get it to work. Apologies in advance for the crimes I have committed against the language and GHC with the following code:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
调查类型错误时的第一件事是写下您知道的函数的类型签名。
这里,solve 可能有类型
或
取决于它在计算值时是否应该有任何副作用。看到您到处使用
mapM
和return
,我猜IO
版本可能是有意为之。现在,如果您写下签名,您就会开始收到更有意义的错误消息。例如,
您得到的不是没有多大意义的:
,它准确地显示了问题所在。函数应用在Haskell中具有最高优先级,因此
return prefix ++ header
相当于(return prefix)++ header
,这绝对不是你的意思。顺便说一句,如果我从返回类型中删除
IO
,删除所有return
并通过添加putStrLn
更改调用,代码将编译并且有效!唯一的问题是它将所有可能的句子连接在一起形成一个字符串,没有任何分隔。The first thing when investigating type errors is to write down the type signatures of functions you know.
Here, solve may have type
or
Depending on whether it should have any side-effects while computing the value. Seeing you using
mapM
andreturn
all over the place, I guess theIO
version may have been intended.Now, if you write down the signature, you start getting much more meaningful error messages. For example, instead of this:
, which does not make much sense, you get this:
,which shows exactly where the problem is. Function application has the highest priority in Haskell, so
return prefix ++ header
is equivalent to(return prefix) ++ header
, which is definitely not what you meant.By the way, if I remove
IO
from the return type, remove all thereturn
s and change the invocation by addingputStrLn
, the code compiles and works! The only problem is that it concatenates all the possible sentences together into a single string without any delimiting.