繁体   English   中英

如何在Haskell的字符串列表中添加字符串的字母?

[英]How to add letters of a String in a String list in Haskell?

我正在尝试在String列表中添加String某些字母。

例如: "Haskell" -> ['a', 's'] (仅as

运行后,我收到错误消息“范围内的注释: xs ”。 因此它缺少一个列表(我认为)。 将列表转换为新列表(例如,mirrorList)没有问题,但是在获得字符串输入后如何“创建”列表?

letterList :: String -> [String]
letterList s = let x = head s in 
                     if x == 'a' || x == 's' then x:xs 
                     else letterList (tail x)

在提出您的确切问题之前,让我们修复类型。 您的示例"Haskell" -> ['a', 's']指示此函数的类型为String -> String ,而不是String -> [String] 请注意, String只是[Char]的类型别名。

该错误消息表示您有一个引用值xs的表达式,但在任何地方都没有定义任何名为xs东西。 我怀疑您打算使用x:xs是模式匹配。 模式位于=的左侧,并声明xxs ,您可以在右侧引用它们。 而且由于不能将空列表分解为头和尾,因此您需要使用单独的大小写。

我猜您想要的结果看起来像这样:

letterList :: String -> String
letterList []     = []
letterList (x:xs) = if x == 'a' || x == 's' then x:rest else rest
                    where rest = letterList xs

我认为您在这里使用递归只是为了练习,但是对于它的价值,我建议将其写为

letterList :: String -> String
letterList = filter (`elem` "as")
  • 不在范围内: xs

    这就是说的意思:找不到名为xs变量,但是您尝试使用它。 尝试调用未定义位置的方法时,您在Java中也会遇到同样的错误。

  • 我没有问题将列表转换为新列表(例如,mirrorList)

    这东西你永远需要在Haskell。 有了列表后,您始终可以直接使用它,也可以随意使用它。 由于参照透明性,值和它的副本之间永远不会有差异。 而且我不确定在这里“转换”是什么意思,但是通常避免在Haskell中转换任何内容:参数多态通常允许您从一开始就生成正确的类型。

现在,关于“我如何创建列表” –您已经做到了! x:xs的cons(前置)运算符: 构造一个新列表。 ...授予,它基于已经存在的列表xs 实际上,这是生成新列表的唯一方法,因为列表构造函数始终需要尾部在元素之前添加前缀。 如果您不想要/不需要/有任何这样的列表,请使用空的 []始终可用。


即使在Haskell中,有时也需要使用可变数据(通常是ST monad中的数组–内部可变,但从外部查看时仍可保证参照转换)。 在这种计算中,可能有必要像在程序语言中一样复制数组。

错误消息显示-您正在右侧使用xs ,但不要在使用xs之前对其进行定义(即,之前没有let语句,之后没有where语句,也没有在左侧。

除了这个答案

您还有另一个问题,您基本上是在实现过滤器,但是结果类型是String而不是[String]

letterList :: String -> [String]
letterList [] = []
letterList (x:xs) = if x == 'a' || x == 's'
                      then [x]: letterList xs 
                      else letterList xs
  • 如果提供空的String则第一种情况可防止错误!
  • 下一行解构head = xtail = xsString ,这更具可读性和正确性(您尝试将单个字母的末尾作为tail x是错误的!)
  • next [x]String = [Char]的单个字母Char转换。

更优雅/作业

letterList str = [[x] | x <- str, x `elem` "as"]

这就是列表理解,这将是我要考虑的下一个“作业”。

要么

letterList str = map (\x -> [x]) $ filter (`elem` "as") str

它使用高阶函数( filtermap ),这是我要给您的第二项任务。

编辑

当然也可以改变类型签名String -> String作为@ChrisMartin显示-那么可以省略[][x]语句,以及分别省略map (\\x -> [x])的东西。

似乎是复制粘贴错误:尝试将xs替换为(tail x)...,然后考虑emoty-list问题……也许您也将替换左侧的;-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM