标签: pattern-matching

当模式匹配失败时,为什么Haskell列表推导不会导致错误?

我试图理解Haskell列表理解如何在模式匹配方面"在幕后"工作.以下ghci输出说明了我的观点:

Prelude> let myList = [Just 1, Just 2, Nothing, Just 3]
Prelude> let xs = [x | Just x <- myList]
Prelude> xs
[1,2,3]
Prelude>
Run Code Online (Sandbox Code Playgroud)

如您所见,它可以跳过"Nothing"并仅选择"Just"值.我知道List是一个monad,定义为(源自Real World Haskell,第14章):

instance Monad [] where
    return x = [x]
    xs >>= f = concat (map f xs)
    xs >> f = concat (map (\_ -> f) xs)
    fail _ = []
Run Code Online (Sandbox Code Playgroud)

因此,列表推导基本上为列表推导中选择的每个元素构建一个单例列表并将它们连接起来.如果模式匹配在某个步骤失败,则使用"失败"功能的结果.换句话说,"Just x"模式不匹配,因此在调用"concat"之前,[]用作占位符.这就解释了为什么"Nothing"似乎被忽略了.

我不明白的是,Haskell如何知道称之为"失败"功能?它是"编译魔术",还是你可以在Haskell中自己编写的功能?是否可以编写以下"select"函数以与列表推导相同的方式工作?

select :: (a -> b) -> [a] -> [b]
select (Just x -> x) myList       -- how to …
Run Code Online (Sandbox Code Playgroud)

haskell list-comprehension pattern-matching

20
推荐指数
3
解决办法
2438
查看次数

模式匹配中的Haskell(n + 1)

我在做99点的问题在Haskell当我遇到了一个解决方案,以问题19,我没有完全理解.

任务是编写一个像这样工作的旋转函数

*Main> rotate ['a','b','c','d','e','f','g','h'] 3
"defghabc"

*Main> rotate ['a','b','c','d','e','f','g','h'] (-2)
"ghabcdef"
Run Code Online (Sandbox Code Playgroud)

提供的解决方案是

rotate [] _ = []
rotate l 0 = l
rotate (x:xs) (n+1) = rotate (xs ++ [x]) n
rotate l n = rotate l (length l + n)
Run Code Online (Sandbox Code Playgroud)

我不明白模式匹配如何达到第四行.它似乎与这个有关,(n+1)所以当n为负时,第三行不匹配,因此第四行被采用.如果是这种情况,为什么符号会以(n+1)这种方式起作用.是不是那么武断,或者是一个我不知道的惯例(数学?)?

因为我理解它的方式是在第三行递归调用rotate,参数n减1.所以我会这么认为

rotate [] _ = []
rotate l 0 = l
rotate (x:xs) n = rotate (xs ++ [x]) (n-1)
rotate l n …
Run Code Online (Sandbox Code Playgroud)

haskell pattern-matching

20
推荐指数
1
解决办法
3987
查看次数

模式匹配和无限流

所以,我正在努力自学Scala,而我一直在玩的其中一件事就是Stream上课.我试图使用经典的Haskell版本的Dijkstra解决汉明数字问题的天真翻译:

object LazyHammingBad {
  private def merge(a: Stream[BigInt], b: Stream[BigInt]): Stream[BigInt] =
    (a, b) match {
      case (x #:: xs, y #:: ys) =>
        if (x < y) x #:: merge(xs, b)
        else if (y < x) y #:: merge(a, ys)
        else x #:: merge(xs, ys)
    }

  val numbers: Stream[BigInt] =
    1 #:: merge(numbers map { _ * 2 },
      merge(numbers map { _ * 3 }, numbers map { _ * 5 }))
}
Run Code Online (Sandbox Code Playgroud)

以此为代表解释,导致很快失望: …

scala pattern-matching lazy-evaluation

20
推荐指数
2
解决办法
6462
查看次数

正则表达式匹配3个或更多连续顺序字符和连续相同字符

我需要正则表达式来匹配以下情况.

  1. 3个或更多连续的连续字符/数字; 例如123,abc,789,pqr等
  2. 3个或更多连续相同的字符/数字; 例如111,aaa,bbb,222等

java regex pattern-matching

20
推荐指数
4
解决办法
7万
查看次数

LCP如何帮助查找模式的出现次数?

我已经读过可以使用最长公共前缀(LCP)来查找字符串中模式的出现次数.

具体来说,您只需要创建文本的后缀数组,对其进行排序,然后不进行二进制搜索以找到范围,以便您可以计算出现次数,只需计算每个连续条目的LCP即可.后缀数组.

虽然使用二进制搜索来查找模式的出现次数是显而易见的,但我无法弄清楚LCP如何帮助找到这里出现的次数.

例如,对于此后缀数组banana:

LCP  Suffix entry
N/A  a  
1    ana  
3    anana  
0    banana  
0    na  
2    nana  
Run Code Online (Sandbox Code Playgroud)

LCP如何帮助找到像"banana"或"na"这样的子字符串的出现次数对我来说并不明显.

有什么帮助搞清楚LCP如何帮助吗?

java algorithm pattern-matching suffix-array data-structures

20
推荐指数
1
解决办法
4299
查看次数

Scala - 模式匹配相关类型的元组

我有以下类层次结构:

class A
class B extends A
class C extends A
Run Code Online (Sandbox Code Playgroud)

然后,还有另一个类,它接受这些类的实例,并且有一个方法,其中两种模式匹配的情况是这样的:

class D (one: A, two: A) {

  def work {
    (one, two) match {
      case (o, t): (B, B) => ... blablabla
      case (o, t): (B, C) => ... blablabla
      case _ =>
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,当它应该解决匹配而支持第二种情况时(B, C),它会尝试将其解析为(B, B)并提出类强制转换异常C cannot be cast to B.为什么?该怎么办?我怎么能绕过这个?

scala tuples pattern-matching

20
推荐指数
2
解决办法
2万
查看次数

当模式匹配时,为什么这在Haskell中是一个有用的警告?"已定义但未使用"

在为函数定义多个模式匹配时,例如如下:

1: takeTree 0 tree                           = Leaf
2: takeTree levels (Leaf)                    = Leaf
3: takeTree levels (Branch value left right) = Branch value (takeTree...
Run Code Online (Sandbox Code Playgroud)

我特别得到两个警告:

Source.hs:1:警告:已定义但未使用:`tree'

Source.hs:2:警告:已定义但未使用:`levels'

我并不是立即相信这些是有用的警告.如果我的代码是:

1: takeTree 0 _                              = Leaf
2: takeTree _ (Leaf)                         = Leaf
3: takeTree levels (Branch value left right) = Branch value (takeTree...
Run Code Online (Sandbox Code Playgroud)

哪个,修复了警告,我现在发现它的可读性要低得多,并且混淆了我期望作为输入值的语义.

为什么这里有Defined but not used一个合理的警告,当我的详尽模式中,每个参数实际上至少使用过一次?

warnings haskell pattern-matching

20
推荐指数
3
解决办法
1576
查看次数

是否有任何基本限制阻止Scala在函数上实现模式匹配?

在像SML,Erlang这样的语言中,我们可以定义这样的函数:

fun reverse [] = []
|   reverse x :: xs  = reverse xs @ [x];
Run Code Online (Sandbox Code Playgroud)

我知道我们可以像这样在Scala中编写模拟(我知道,下面的代码中有很多缺陷):

def reverse[T](lst: List[T]): List[T] = lst match {
  case Nil     => Nil
  case x :: xs => reverse(xs) ++ List(x)
}
Run Code Online (Sandbox Code Playgroud)

但我想知道,如果我们可以在Scala中编写前代码,也许可以放弃后者.

这种语法在未来是否有任何基本限制(我的意思是,真的很基础 - 例如类型推断在scala中的工作方式,或者除了解析器之外的其他东西)?

UPD
以下是它的外观片段:

type T
def reverse(Nil: List[T]) = Nil
def reverse(x :: xs: List[T]): List[T] = reverse(xs) ++ List(x)
Run Code Online (Sandbox Code Playgroud)

syntax functional-programming scala pattern-matching

20
推荐指数
2
解决办法
571
查看次数

PostgreSQL对数组不敏感的SELECT

我在谷歌或文档中找到答案时遇到问题......
我需要针对数组类型做一个不区分大小写的选择.

因此,如果:

value = {"Foo","bar","bAz"}
Run Code Online (Sandbox Code Playgroud)

我需要

SELECT value FROM table WHERE 'foo' = ANY(value)
Run Code Online (Sandbox Code Playgroud)

匹配.

我尝试了很多lower()的组合而没有成功.

ILIKE而不是=似乎工作,但我一直很紧张LIKE- 这是最好的方式吗?

sql postgresql case-insensitive pattern-matching

20
推荐指数
3
解决办法
9018
查看次数

SBT中非穷举匹配使编译失败

让我们说我有一个特点,父母,有一个孩子,孩子.

scala> sealed trait Parent
defined trait Parent

scala> case object Boy extends Parent
defined module Boy
Run Code Online (Sandbox Code Playgroud)

我写了一个函数,模式匹配密封的特征.我的f功能是完全的,因为只有一个Parent实例.

scala> def f(p: Parent): Boolean = p match { 
     |   case Boy => true
     | }
f: (p: Parent)Boolean
Run Code Online (Sandbox Code Playgroud)

然后,2个月后,我决定添加一个Girl孩子Parent.

scala> case object Girl extends Parent
defined module Girl
Run Code Online (Sandbox Code Playgroud)

然后重新编写f方法,因为我们正在使用REPL.

scala> def f(p: Parent): Boolean = p match { 
     |   case Boy => true
     | }
<console>:10: warning: match may …
Run Code Online (Sandbox Code Playgroud)

scala pattern-matching sbt

20
推荐指数
2
解决办法
2403
查看次数