首页 > 解决方案 > Haskell:无法将类型“Char”与“[Char]”匹配

问题描述

我是 Haskell 的新手,我正在尝试创建一个简单的函数来操作类似于toLower,toUpperswitchCase其他语言的字符串。但是,每当我尝试传递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 ]

标签: haskelltypesghci

解决方案


结果证明解决方案非常简单。GHC 编译器推断它lambdaTextConv是类型[Char] -> ([Char] -> Bool) -> [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 ]

推荐阅读