例如,在 Elixir 的case 语句中,以下代码是有效的,并且将匹配 10 到 1:
x = 1
case 10 do
^x -> "Won't match"
_ -> "Will match"
end
Run Code Online (Sandbox Code Playgroud)
然而,在 Rust 中,^ 不是此用例的有效运算符。它只是给出一个错误,显示类似“预期模式,找到 ^”之类的内容。我尝试这样做:
let x = 1;
match 10 {
x => "Won't match",
_ => "Will match",
}
Run Code Online (Sandbox Code Playgroud)
但它将 10 绑定到 x 并返回“Won't match”(相当于“x @ _”)。有没有一种方法可以动态包含 x,以便无论 x 是什么,它都会与其值匹配?(注意:我意识到我可以只使用 if 语句,但我很好奇 match 语句是否提供了解决方案)
我必须根据模式匹配块中的情况执行一些操作,但仅限于选择性情况,其余情况无需执行任何操作。那么剩下的情况就直接 return() 就可以了吗?像这样的东西:
val x = ....
val y = ....
(x, y) match {
case (Some(number), Some(text)) => {
......
}
case (Some(number), None) => {
......
}
case (_, _) => () // do nothing
}
Run Code Online (Sandbox Code Playgroud) 所以我在 Scala 中有一个 Try 块
def fromString(s: String): Option[Pitch] = scala.util.Try {
val (pitchClassName, octaveName) = s.partition(c => !c.isDigit)
val octave = if octaveName.nonEmpty then octaveName.toInt else 5
Pitch(pitchClassIndex(pitchClassName) + octave * 12)
} match {
case scala.util.Success(value) => Some(value)
case scala.util.Failure(e) =>
case scala.util.Failure(e) => throw e
}
Run Code Online (Sandbox Code Playgroud)
现在,我知道这里有很多代码需要解释。为了这个问题的目的,需要知道的是:
当使用给定音符(如“D#4”)创建 Pitch 实例时,可能有两个我想要专门处理的不同异常。第一个是如果映射的pitchClassIndex 找不到给定的键pitchClassName,第二个是如果Pitch 参数超出给定范围。
音高等级索引:
val pitchClassIndex: Map[String, Int] = pitchClassNames.zipWithIndex.toMap
Run Code Online (Sandbox Code Playgroud)
音调类别名称:
val pitchClassNames: Vector[String] = Vector("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B") …Run Code Online (Sandbox Code Playgroud) 在 Scala 2.12 中,我使用模式匹配循环一个数组来创建一个新数组,如下所示。
val arrNew=arrText.map {
case x if x.startsWith("A") =>x.substring(12, 20)
case x if x.startsWith("B") =>x.substring(21, 40)
case x => "0"
}.filter(_!="0")
Run Code Online (Sandbox Code Playgroud)
如果一个元素与两个模式之一匹配,则将一个新元素添加到新数组中arrNew。那些不匹配的将被丢弃。我的代码实际上arrText使用过滤器循环两次。如果我不包含case x =>"0",则会出现错误,抱怨某些元素未匹配。下面的代码是循环一次的唯一方法吗?有什么办法可以通过case匹配只循环一次吗?
map { x =>
if (condition1) (output1)
else if (condition2) (output2)
}
Run Code Online (Sandbox Code Playgroud) 我有一个特质
trait A {
def doSomething(a: Seq[Int]): Seq[String] = {
a.map {
case AA(s) => s // want to use unapply defined in trait (this(AA) not allowed)
case _ => "idc"
}
}
def unapply(a: Int): Option[String] = getString(a)
def getString(a: Int): Option[String] = {
a match {
case 1 => Some("one")
case 2 => Some("two")
case _ => None
}
}
}
object AA extends A
object AA2 extends A {
override def getString(a: Int): Option[String] = {
super.getString(a).orElse{ …Run Code Online (Sandbox Code Playgroud) 我对 F# 完全陌生,我有一个函数可以计算两个不同点的总和,x如下y所示let vAdd (x1, y1) (x2, y2) : float * float = (x1 + x2, y1 + y2),然后我有另一个函数,它获取点列表,然后用于vAdd进行计算。let vSum [(x1, y1); (x2, y2)] = vAdd (x1, y1) (x2, y2)
现在我的问题是,如果给定的列表为空,我将如何检查并抛出一些错误?我尝试过 if ... then failwith "list is empty"但IsEmpty没有工作。我看过的另一件事是pattern matching,,但我不知道它如何与我的特定功能一起工作。F# 检查列表是否为空
任何帮助将不胜感激,并提前致谢!
我有这样的类型:
data MyType = I Int | C Char -- and lots of other options
Run Code Online (Sandbox Code Playgroud)
我希望能够找出这种类型的值是否是特定的变体。我可以使用模式匹配来定义函数isInt、isChar等。但我宁愿只编写一个函数,如下所示:
hasBaseType :: MyType -> (a -> MyType) -> Bool
hasBaseType (f _) = True
hasBaseType _ = False
Run Code Online (Sandbox Code Playgroud)
我将传递适当的构造函数(I或C)作为第二个参数。不幸的是,你不能像这样进行模式匹配。
我还想“解开”这个值。我可以再次使用模式匹配来编写函数unwrapInt、unwrapChar等。但我宁愿只编写一个函数,如下所示:
unwrap :: MyType -> (a -> MyType) -> a
unwrap (f x) = x
unwrap _ = error "wrong base type"
Run Code Online (Sandbox Code Playgroud)
有没有一些奇特的魔法可以让我做到这一点?我想也许PatternSynonyms会有所帮助,但我不知道如何帮助。
match该表达式是如何在高层次上实现的?编译器在幕后发生了什么才能知道如何将某些代码片段定向到一个分支与另一个分支,并在编译时弄清楚它?我不明白如果不存储运行时使用的类型信息,这怎么可能。
像这个例子:
\nfn tree_weight_v1(t: BinaryTree) -> i32 {\n match t {\n BinaryTree::Leaf(payload) => payload,\n BinaryTree::Node(left, payload, right) => {\n tree_weight_v1(*left) + payload + tree_weight_v1(*right)\n }\n }\n}\n\n/// Returns tree that Looks like:\n///\n/// +----(4)---+\n/// | |\n/// +-(2)-+ [5]\n/// | | \n/// [1] [3]\n///\nfn sample_tree() -> BinaryTree {\n let l1 = Box::new(BinaryTree::Leaf(1));\n let l3 = Box::new(BinaryTree::Leaf(3));\n let n2 = Box::new(BinaryTree::Node(l1, 2, l3));\n let l5 = Box::new(BinaryTree::Leaf(5));\n\n BinaryTree::Node(n2, 4, l5)\n}\n\n#[test]\nfn tree_demo_1() {\n let tree = sample_tree();\n assert_eq!(tree_weight_v1(tree), (1 …Run Code Online (Sandbox Code Playgroud) 我有这个功能
let f = function
| 1 -> "a"
| 2 -> "b"
| _ -> failwith "Argument should be less than 3 and more than 0 but it was found to be x"
Run Code Online (Sandbox Code Playgroud)
如何将此处的值设置x为等于函数的输入?
我对 haskell 有点陌生
data Tree a = Leaf | Branch (Tree a) a (Tree a)
deriving (Show, Eq)
insert :: (Ord a, Eq a) => a -> Tree a -> Tree a
insert x Leaf = Branch Leaf x Leaf
insert x (Branch l v r)
| x <= v = Branch (insert x l) v r
| x > v = Branch l v (insert x r)
Run Code Online (Sandbox Code Playgroud)
该代码给出以下警告(但可以编译):
app\Main.hs:10:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for …Run Code Online (Sandbox Code Playgroud)