我想知道如何通常实现模式匹配.例如在Erlang中你认为它是在字节码级实现的(它有一个字节码,以便它有效地完成),还是由编译器生成一系列指令(字节码系列)?它是如此有用的东西,我只需要把它变成玩具语言我非常感谢你
(链接更受欢迎)
我想申请filter一个迭代器,我想出了这个并且它可以工作,但它超级详细:
.filter(|ref my_struct| match my_struct.my_enum { Unknown => false, _ => true })
Run Code Online (Sandbox Code Playgroud)
我宁愿写这样的东西:
.filter(|ref my_struct| my_struct.my_enum != Unknown)
Run Code Online (Sandbox Code Playgroud)
这给了我一个编译错误
binary operation `!=` cannot be applied to type `MyEnum`
Run Code Online (Sandbox Code Playgroud)
有冗长模式匹配的替代方案吗?我寻找一个宏但找不到合适的宏.
我需要一个遍历文档的模式,并获取所有在其href中有mailto的链接:
<a href="mailto:an@email.com">text</a>
Run Code Online (Sandbox Code Playgroud)
我当然可以轻松获取所有a元素($("a"))并检查每个href属性以查看它是否指向mailto但我认为jQuery具有某种形式的模式匹配,这将允许我这样做.
实现这一目标的最佳方法是什么?
假设我有以下单一案例歧视联盟:
type OrderId = OrderId of string
Run Code Online (Sandbox Code Playgroud)
在某些时候我需要实际的字符串.我发现它的提取方式是:
let id = match orderId with OrderId x -> x
Run Code Online (Sandbox Code Playgroud)
这样做有更简洁的方法吗?
我知道我的使用是一个特殊的情况,并且匹配是有意义的,以确保你已经涵盖了可能性,只是想知道是否有办法做一些事情,如:
let OrderId id = orderId
Run Code Online (Sandbox Code Playgroud) 我正在寻找一种在不需要实际数据时简化功能模式的方法:
data X = A | B String | C Int Int String
myfn :: X -> Int
myfn A = 50
myfn (B _) = 200
myfn (C _ _ _) = 500
Run Code Online (Sandbox Code Playgroud)
有没有办法为匹配C制作一个更简单的模式,只是丢弃这些值?
hsdev添加了一个提示"提示:使用记录模式",但谷歌并没有帮助我.
我想从简单类型List创建一个更复杂的对象类型List.例如,List[String] => List[MyType].
我已经使用基于地图的方法给了它三个.带通配符的简单地图:
> case class telecom (name:String, longitude:Double, latitude:Double)
defined class telecom
> List("foo","bar").map(x:String => telecom(x,0,0)):List[telecom]
:1: error: ';' expected but ')' found.
Run Code Online (Sandbox Code Playgroud)
使用case类构造函数的模式匹配方法:
> def foo(c:List[String]){
| c match {
| case tc:List[telecom] => tc.map(telecom(_,0,0)):List[telecom]; println("matched telephonecomapny");
| case _ => println("matched nothing"); throw new ClassCastException(); }}
warning: there were unchecked warnings; re-run with -unchecked for details
foo: (c: List[String])Unit
> foo(List("foo","bar"))
java.lang.ClassCastException: java.lang.String cannot be cast to usda.rd.broadband.model.DatabaseTables$TelephoneCompany
at $anonfun$foo$1.apply(<console>:11)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:206)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:206) …Run Code Online (Sandbox Code Playgroud) Haskell中的vanilla数据类型具有零个或多个构造函数,每个构造函数都扮演两个角色.
在表达式中,它支持引入,它是从零个或多个参数到数据类型的函数.
在模式中,它支持消除,它有点像从数据类型到Maybe(参数类型的元组)的函数.
模块签名是否有可能在暴露后者时隐藏前者?
用例是这样的:我有一个类型T,它的构造函数类型有时可以用来构造废话.我有构造函数,可用于构建保证不是废话的类型的实例.在这种情况下隐藏构造函数是有意义的,但是对于调用者来说,能够通过构造函数构建的保证非废话模式匹配仍然是有用的.
我怀疑这是不可能的,但万一有人有办法做到这一点,我会问.
接下来最好的事情是隐藏构造函数并从T - > Maybe(This,That),T - > Maybe(The,Other,Thing)等创建一堆函数.
如果我取消注释指示的行,则下面的代码不会编译.编译器抱怨:"需要稳定的标识符".
val Empty = Stream.empty
val a = Stream.range(0, 5)
a match {
// case Stream.empty => println("nope") <-- does not work
case Empty => println("compiles") <-- works
case _ => println("ok")
}
Run Code Online (Sandbox Code Playgroud)
如果我首先赋值Stream.empty给Empty它,它会起作用,但是如果没有这样的黑客,你就无法在这样的基本值上进行模式匹配.
我错过了什么吗?
我已将项目升级到目标C#7,并使用Visual Studio 2017 RC在我的解决方案中实现模式匹配.在执行此操作之后,引入了与通用参数的模式匹配相关的一些错误.
请考虑以下代码:
public class Packet
{
}
public class KeepalivePacket : Packet
{
}
public void Send<T>(T packet)
where T : Packet
{
if (packet is KeepalivePacket keepalive)
{
// Do stuff with keepalive
}
switch (packet)
{
case KeepalivePacket keepalivePacket:
// Do stuff with keepalivePacket
break;
}
}
Run Code Online (Sandbox Code Playgroud)
无论是if语句和case声明产生一个编译错误.
类型为T的表达式不能由KeepalivePacket类型的模式处理
如果我首先转换参数以键入object模式匹配按预期工作.罗斯林然后将演员标记object为多余.
if ((object)packet is KeepalivePacket keepalive)
{
// This works
}
Run Code Online (Sandbox Code Playgroud)
此错误仅适用于通用参数和变量.Roslyn似乎不知道这个问题,因为它建议更改代码以通过分析器使用模式匹配,并允许我应用"代码修复"导致代码损坏.
我不明白varC#7 中模式的用例.MSDN:
与模式匹配的
var模式总是成功的.它的语法是
expr is var varname
Run Code Online (Sandbox Code Playgroud)
其中expr的值始终分配给名为的局部变量
varname.varname是一个与expr.相同类型的静态变量.
在我看来,MSDN上的例子非常无用,特别是因为它if是多余的:
object[] items = { new Book("The Tempest"), new Person("John") };
foreach (var item in items) {
if (item is var obj)
Console.WriteLine($"Type: {obj.GetType().Name}, Value: {obj}");
}
Run Code Online (Sandbox Code Playgroud)
在这里我没有看到任何好处,如果你item直接访问也是类型的循环变量,你可以有相同的Object.这if也是令人困惑的,因为它永远不会false.
我可以使用var otherItem = item或使用item.有人可以更好地解释用例吗?