Haskell - "应用程序中的类型错误":"统一会给出无限类型"

Sam*_*inn 4 haskell

我正在开始使用Haskell,但是我试图制作的这种平等检查并没有成功.

我有一个函数,countLetter a [b] c其中a是char,b是一个字符列表,c是一个int.(类型声明通过罚款.)但是我遇到了这个表达式的问题:

if a == head(b)
Run Code Online (Sandbox Code Playgroud)

给我以下消息:

Type error in application

*** Expression     : a == head b
*** Term           : a
*** Type           : [a]
*** Does not match : a
*** Because        : unification would give infinite type
Run Code Online (Sandbox Code Playgroud)

如果需要,我的代码是完整的:

countLetter :: char -> [char] -> int

countLetter a [b] c = if null b

                       then []
                       else
                       if a == head(b)
                       then countLetter a tail(b) c+1
                    else
                    countLetter head(b) tail(b) c
Run Code Online (Sandbox Code Playgroud)

任何帮助或建议将不胜感激.谢谢.

sep*_*p2k 9

首先,Haskell中的类型以大写字母开头.如果在类型签名中使用以小写字母开头的标识符,则将它们解释为类型变量.所以你的类型char -> [char] -> int是相同的a -> [a] -> b,这对你的功能来说不是一个明智的类型.你想要的Char -> [Char] -> Int.

其次[]不是类型的有效值Int.修复您的类型签名应该会产生一条错误消息,告诉您不那么模糊的术语.

它应该告诉你这null b是一个类型错误,因为b它是类型Char(你的函数的第二个参数是类型[Char],你已经将它与模式匹配[b],绑定b到该Char列表中包含的单个)并null采取列表,而不是一个Char,作为它的论点.

最后一点澄清:

函数的第二个参数是一个列表.通过[b]在参数列表中写入,您可以将该参数与模式进行匹配[b].换句话说,写作countLetter a [b] c = blabla与写作相同:

countLetter a theList c =
    case theList of
        [b] -> blabla
Run Code Online (Sandbox Code Playgroud)

所以你要说:"函数的第二个参数必须是一个包含一个元素的列表,并且该元素应该被调用b".这不是你想要说的.你想要说的是"函数的第二个参数(顺便提一下,它是一个列表)应该被称为b".为此,你只需要写countLetter a b c = blabla.

类型列表的参数不必以与其他类型的参数不同的方式表示.