模式匹配在F#中的幕后如何工作? [英] How does pattern matching work behind the scenes in F#?

查看:87
本文介绍了模式匹配在F#中的幕后如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对F#完全陌生(通常是函数式编程),但我看到示例代码中随处可见的模式匹配。我想知道如何模式匹配实际工作?例如,我想象它与其他语言的for循环一样工作,并检查集合中每个项目的匹配。这可能远不是正确的,它是如何在幕后工作的?


解决方案

这要看是什么样的模式匹配你的意思 - 这是相当强大的构造,可以在各种使用方法。但是,我会尝试解释模式匹配如何在列表上工作。您可以编写例如这些模式:

  match l with 
| [1; 2; 3] - > // 3个元素的具体列表
| 1 ::休息 - > //从1开始,然后是更多元素
| x :: xs - > //带元素'x'的非空列表,后面跟着一个列表
| [] - > //空列表(无元素)

F#列表实际上是一个区分的联合,它包含两种情况 - code> [] 表示一个空列表或 x :: xs 表示第一个元素 x 后跟其他一些元素。在C#中,这可能表示如下:

  //表示任何列表
抽象类列表< T> {}
//表示空列表的Case'[]'
class EmptyList< T> :列表< T> {}
// Case'x :: xs'表示元素后面跟着其他列表
class ConsList< T> :列表< T> {
public T Value {get;组; }
public List< T>休息{get;组; }
}

上面的模式将被编译为以下内容(我正在使用伪如果(l是ConsList)&&& amp;& amp;& amp;& (l.Value == 1)&&
(l.Rest是ConsList)&& (l.Rest.Value == 2)&&
(l.Rest.Rest是ConsList)&& (l.Rest.Rest.Value == 3)&&
(l.Rest.Rest.Rest为EmptyList)然后
// 3个元素的具体列表
else if(l是ConsList)&& (l.Value == 1),然后
var rest = l.Rest;
//从1开始,然后是更多元素的列表
else if(l是ConsList)然后
var x = l.Value,xs = l.Rest;
//带元素'x'的非空列表,后跟一个列表
else if(l是EmptyList)然后
//空列表(无元素)

正如您所看到的那样,不存在循环。当在F#处理列表,你可以使用递归来实现循环,但图案匹配上各个元件( ConsList ),它们一起构成整个列表使用。



列表中的模式匹配是由 sepp2k 讨论的区分联合的特定情况。还有其他的构造可能出现在模式匹配中,但基本上所有的构造都是使用一些(复杂的)如果语句编译的。


I am completely new to F# (and functional programming in general) but I see pattern matching used everywhere in sample code. I am wondering for example how pattern matching actually works? For example, I imagine it working the same as a for loop in other languages and checking for matches on each item in a collection. This is probably far from correct, how does it actually work behind the scenes?

解决方案

It depends on what kind of pattern matching do you mean - it is quite powerful construct and can be used in all sorts of ways. However, I'll try to explain how pattern matching works on lists. You can write for example these patterns:

match l with
| [1; 2; 3] ->  // specific list of 3 elements
| 1::rest ->    // list starting with 1 followed by more elements
| x::xs ->      // non-empty list with element 'x' followed by a list
| [] ->         // empty list (no elements)

The F# list is actually a discriminated union containing two cases - [] representing an empty list or x::xs representing a list with first element x followed by some other elements. In C#, this might be represented like this:

// Represents any list
abstract class List<T> { }
// Case '[]' representing an empty list
class EmptyList<T> : List<T> { }
// Case 'x::xs' representing list with element followed by other list
class ConsList<T> : List<T> {
  public T Value { get; set; } 
  public List<T> Rest { get; set; }
}

The patterns above would be compiled to the following (I'm using pseudo-code to make this simpler):

if (l is ConsList) && (l.Value == 1) &&
   (l.Rest is ConsList) && (l.Rest.Value == 2) &&
   (l.Rest.Rest is ConsList) && (l.Rest.Rest.Value == 3) &&
   (l.Rest.Rest.Rest is EmptyList) then
   // specific list of 3 elements
else if (l is ConsList) && (l.Value == 1) then
   var rest = l.Rest;
   // list starting with 1 followed by more elements
else if (l is ConsList) then
   var x = l.Value, xs = l.Rest;
   // non-empty list with element 'x' followed by a list
else if (l is EmptyList) then 
   // empty list (no elements)

As you can see, there is no looping involved. When processing lists in F#, you would use recursion to implement looping, but pattern matching is used on individual elements (ConsList) that together compose the entire list.

Pattern matching on lists is a specific case of discriminated union which is discussed by sepp2k. There are other constructs that may appear in pattern matching, but essentially all of them are compiled using some (complicated) if statement.

这篇关于模式匹配在F#中的幕后如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆