[英]Getting stack overflow error when trying Haskell-style lazy evaluation in Scala
[英]Is Haskell-style pattern matching on Scala Strings possible?
我只是好奇
我尝试使用Haskell方式在Scala中进行模式匹配字符串(作为字符列表)
例如,此函数删除字符串中的第一个“ /”字符:
import scala.language.implicitConversions
implicit def stringToChars(s: String): List[Char] = s.toCharArray.toList
implicit def charsToString(a: List[Char]): String = a.mkString
def filterFirstSlash: Function[List[Char], String] = {
case Nil => ""
case '/' :: Nil => ""
case '/' :: xs => xs
case xs => xs
}
用法:
println(filterFirstSlash("/test"))
我可以使用模式匹配删除前导斜线吗? 以这种方式这样做好吗?
更新
这将删除头部和尾部的所有条目:
def removeAllSlashes: Function[List[Char], String] = {
case Nil => ""
case '/' :: xs => removeAllSlashes(xs)
case xs :+ '/' => removeAllSlashes(xs)
case xs => xs
}
这只会删除第一个条目:
def removeFirstSlash: Function[List[Char], String] = {
case Nil => ""
case ('/' :: xs) :+ '/' => xs
case '/' :: xs => xs
case xs :+ '/' => xs
case xs => xs
}
ps不要那么认真。 这只是为了好玩。 感谢参与讨论的每个人。
不,那不是一个好方法。 String
不是字符列表。 在JVM上,字符串是UTF-16代码单元的不变数组。 它们与链接列表无关。 您的filterFirstSlash
将始终忽略前三种情况,并始终返回不变的输入。
要降低斜线,您可以执行以下操作:
"////abcd".dropWhile(_ == '/') // returns `"abcd"`
要么
"/abcd".replaceAll("^/", "")
要么
((s: String) => if (s startsWith "/") s.tail else s )("/abcd")
或者,也许,如果您确实坚持模式匹配,则可以使用预编译的正则表达式模式来匹配前导斜杠和字符串的其余部分:
val Rgx = "^/(.*)$".r
"/abcd" match { case Rgx(s) => s; case s => s } // evaluates to `"abcd"`
从技术上讲,这是可能的:
def filterFirstSlash(s: String) = {
case '/' +: xs => xs
case xs => xs
}
当然,效率不如链表的相同代码,因为+:
每次都会复制整个字符串,因此您不希望使用它来递归地挑选字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.