【问题标题】:Haskell: Couldn't match type `Char' with `[Char]'Haskell:无法将类型“Char”与“[Char]”匹配
【发布时间】:2021-10-18 13:00:08
【问题描述】:

我是 Haskell 的新手,我正在尝试创建一个简单的函数来操作类似于其他语言中的 toLowertoUpperswitchCase 的字符串。但是,每当我尝试将 isUpperisLower 传递给模板函数时,它都会向我抛出这个错误。

* Couldn't match type `Char' with `[Char]'
      Expected: [Char] -> Bool
        Actual: Char -> Bool
    * In the second argument of `lambdaTextConv', namely `isLower'
      In the expression: lambdaTextConv str isLower
      In an equation for `toLower':
          toLower str = lambdaTextConv str isLower
   |
53 | toLower str = lambdaTextConv str isLower
   |                                  ^^^^^^^
Failed, no modules loaded.

代码本身是一个简单的函数,它接受一个字符串,并在适当的时候切换大小写。

import System.IO
import Data.List
import Data.Maybe  

letters = take 26 (zip ['A'..] ['a'..])
upperLetters = ['A'..'Z']
lowerLetters = ['a'..'z']

lambdaTextConv str ltrFnc =
    [
        lambdaNewLetter x ltrFnc
    | x <- str ]
lambdaNewLetter x ltrFnc =
    if (ltrFnc x)
    then x
    else ((switchCase x:[]) !! 0)

isUpper char = char `elemIndex` upperLetters /= Nothing
isLower char = char `elemIndex` lowerLetters /= Nothing

toUpper str = lambdaTextConv str isUpper
toLower str = lambdaTextConv str isLower

switchCase str =
    [
        if (isUpper x)
        then snd(letters !! fromJust(x `elemIndex` upperLetters))
        else fst(letters !! fromJust(x `elemIndex` lowerLetters))
    | x <- str ]

【问题讨论】:

  • Haskell 推断isLower 的类型为Char -&gt; Bool,但lambdaTextConv 的第二个参数应该是String -&gt; BoolString[Char] 的另一个名称)。我建议您为每个函数编写类型(使用::)以确保每个函数都具有您期望的类型。如果其中一个函数的类型错误,编译器会抱怨:: 声明与实际函数不匹配,因此您将能够看到它是哪个函数。
  • 我会建议你给你的每个函数一个type。这样更容易定位问题。虽然没有必要,但为顶级定义定义类型非常常见。
  • @user253751 我非常了解函数类型,但问题是isLower 应该属于Char -&gt; Bool 类型,这不是错误。它只在 lambdaNewLetter 中调用,它接受并返回一个 Char 而不是 String。
  • @WillemVanOnsem 请查看我之前的评论
  • @user253751 现在查看您的评论我发现我应该给lambdaTextConv 一个可以解决问题的类型。非常感谢!

标签: haskell types ghci


【解决方案1】:

结果证明解决方案非常简单。 GHC 编译器推断 lambdaTextConv[Char] -&gt; ([Char] -&gt; Bool) -&gt; [Char] 类型,因为该行

    else ((switchCase x:[]) !! 0)

应该是什么时候

    else ((switchCase (x:[])) !! 0)

源现在看起来更像这样(省略导入)

letters = take 26 (zip ['A'..] ['a'..])
upperLetters = ['A'..'Z']
lowerLetters = ['a'..'z']

lambdaTextConv :: [Char] -> (Char -> Bool) -> String
lambdaTextConv str ltrFnc =
    [
        lambdaNewLetter x ltrFnc
    | x <- str ]

lambdaNewLetter :: Char -> (Char -> Bool) -> Char
lambdaNewLetter x ltrFnc =
    if (ltrFnc x)
    then x
    else ((switchCase (x:[])) !! 0)

isUpper char = char `elemIndex` upperLetters /= Nothing
isLower char = char `elemIndex` lowerLetters /= Nothing

toUpper str = lambdaTextConv str isUpper
toLower str = lambdaTextConv str isLower

switchCase str =
    [
        if (isUpper x)
        then snd(letters !! fromJust(x `elemIndex` upperLetters))
        else fst(letters !! fromJust(x `elemIndex` lowerLetters))
    | x <- str ]

【讨论】:

    猜你喜欢
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-08
    • 2014-08-30
    相关资源
    最近更新 更多