学习Haskell:与反向函数和递归混淆

tur*_*tle 5 haskell

我刚刚开始学习Haskell,我正在尝试编写一个简单的函数,它接受一个字符串列表并反转列表中的每个字符串:

revComp :: [String] -> [String]
revComp [] = []
revComp [x] = [] ++ [reverse x]
revComp (x:xs) = revComp [xs]
Run Code Online (Sandbox Code Playgroud)

当我尝试在GHCI中加载我的代码时,我收到一个错误:

Couldn't match expected type `Char' with actual type `[Char]'
Expected type: String
Actual type: [String]
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释我的问题是什么和在哪里?非常感谢.

ehi*_*ird 9

前三行很好.你的类型签名是正确的,第二行是正确的,第三行也是正确的.(但是,[] ++ [reverse x]是一样的[reverse x].)

然而,第四行是错误的.您不仅没有x在右侧使用,而且还有类型错误:使用单元素列表revComp [xs]调用revComp,该列表具有xs唯一的元素.这x是列表的第一个元素,也是列表xs的其余部分.所以,既然xs有类型[String],[xs]有类型[[String]],但revComp需要一个[String]!您想要反转x,并将其添加到反转列表其余部分的结果中.

您可以使用它revComp xs来反转列表其余部分中的每个字符串,并将(:)值添加到列表中(x:xs使用在左侧使用的模式中看到的相同语法).这应该足以让您修复最后一行.顺便说一句,这使第三行变得冗余,因为[x]它只是x:[].


Ric*_* T. 6

ehird的答案非常完整,但我想指出 - 作为参考 - 在实际代码中实现该功能的"好/短"方式,因为你是新手.它可以被定义为的局部应用mapreverse:

Prelude> let revComp = map reverse
Prelude> revComp ["olleh", "dlrow"]
["hello","world"]
Run Code Online (Sandbox Code Playgroud)

这导致功能revComp :: [[a]] -> [[a]](而不是[String] -> [String]因为这两个mapreverse工作在任何类型的列表)映射reverse到输入列表中的每一个元素,返回结果的列表.