我正在将一些Haskell代码从使用列表更改为集合.我认为,我理解所需的一切,但我不确定如何在套装上进行模式匹配.列表有这个很好的文字语法,似乎很难用Set构造函数模拟.例如,我可能有一些像这样的代码:
foo [] = []
foo x = other_thing
Run Code Online (Sandbox Code Playgroud)
如何编写此代码,以便使用集而不是列表?
我最好写这样的东西:
myValue1 = 1 :: Int myValue2 = 2 :: Int myFunc :: Int -> Bool myFunc myValue1 = True myFunc myValue2 = False
致电myFunc myValue2回报True- 不是我想要的.我知道为什么会发生这种情况,但有没有办法在Haskell中表达这一点而不诉诸C风格的#define语句?
要创建一个可以在Scala中用于理解的新类,似乎所有你需要做的就是定义一个map函数:
scala> class C[T](items: T*) {
| def map[U](f: (T) => U) = this.items.map(f)
| }
defined class C
scala> for (x <- new C(1 -> 2, 3 -> 4)) yield x
res0: Seq[(Int, Int)] = ArrayBuffer((1,2), (3,4))
Run Code Online (Sandbox Code Playgroud)
但这仅适用于简单的for循环,其中左侧没有模式匹配<-.如果您尝试在那里进行模式匹配,则会收到filter未定义方法的投诉:
scala> for ((k, v) <- new C(1 -> 2, 3 -> 4)) yield k -> v
<console>:7: error: value filter is not a member of C[(Int, Int)]
for ((k, v) <- new C(1 -> 2, 3 -> …Run Code Online (Sandbox Code Playgroud) 我有一个字符串列表(实际上是文件名),我只想保留那些匹配过滤器表达式的字符串,如:\*_Test.txt.
实现这一目标最好的是什么?
以下是我提出的答案:
List<string> files = new List<string>();
files.Add("MyFile1.csv");
files.Add("MyFile1_Test.txt");
files.Add("MyFile2.csv");
files.Add("MyFile2_Test.txt");
files.Add("MyFile3.csv");
files.Add("MyFile3_Test.txt");
files.Add("MyFile_Testtxttxt.txt");
// Define a filter
string filter = "*_Test.txt";
// Make the filter regex safe
foreach (char x in @"\+?|{[()^$.#")
filter = filter.Replace(x.ToString(), @"\" + x.ToString());
filter = string.Format("^{0}$",filter.Replace("*", ".*"));
// Old School
List<string> resultList1 = files.FindAll(delegate(string s) { return Regex.IsMatch(s, filter, RegexOptions.IgnoreCase); });
// Version using LINQ
List<string> resultList2 = files.Where(x => Regex.IsMatch(x, filter, RegexOptions.IgnoreCase) == true ).ToList();
Run Code Online (Sandbox Code Playgroud) 当模式将异常与case语句匹配时,是否有更简单的方法将同一异常与一组异常类型匹配?而不是这个:
} catch {
case e if e.isInstanceOf[MappingException] || e.isInstanceOf[ParseException] =>
Run Code Online (Sandbox Code Playgroud)
像这样的东西会很好:
case e: MappingException | ParseException | SomeOtherException =>
Run Code Online (Sandbox Code Playgroud)
这样的事情可能吗?
编辑: WHOOPS!很大的承认,我搞砸了?in fnmatchpattern语法的定义,似乎已经提出(并且可能已经解决)一个更难的问题,就像它.?在正则表达式中一样.当然,它实际上应该像.正则表达式一样(恰好匹配一个字符,而不是零或一个).这反过来意味着我最初的减少问题的工作足以解决(现在相当无聊)原始问题.解决更难的问题仍然很有趣; 我可能会在某个时候写出来.
从好的方面来说,这意味着像2way/SMOA针分解这样的东西可能适用于这些模式的可能性要大得多,这反过来又可以产生比原本更好的O(n)甚至O(n/m)性能.
在问题标题中,m设为模式/针n的长度,并且是与其匹配的字符串的长度.
这个问题对我很感兴趣,因为我看到/使用过的所有算法都有病态性能不佳和可能的堆栈溢出漏洞,这是由于回溯或需要动态内存分配(例如DFA方法或者只是避免在回调时进行回溯)如果某个程序fnmatch用于授予/拒绝某种访问权限,则会出现故障情况.
我愿意相信正则表达式匹配不存在这样的算法,但文件名模式语言比正则表达式简单得多.我已经将问题简化到可以假设模式不使用该*字符的程度,并且在这个修改过的问题中,您不匹配整个字符串,而是搜索字符串中模式的出现(如子字符串)匹配问题).如果你进一步简化语言并删除?字符,语言只是由固定字符串和括号表达式的连接组成,这很容易在O(mn)时间和O(1)空间中匹配,O(n)如果针分解,也许可以改进2way和SMOA子串搜索中使用的技术可以扩展到这种括号模式.然而,天真的每一个都?要求试验有或没有?消耗一个角色,带来时间因素在2^q哪里q是?模式中的字符数.
有人知道这个问题是否已经解决,或者有解决问题的想法?
注意:在定义O(1)空间时,我使用的是Transdichotomous_model.
注2:本网站详细介绍了我引用的2way和SMOA算法:http://www-igm.univ-mlv.fr/~lecroq/string/index.html
Haskell编译器在以下函数上引发错误:
balancedMax :: Int -> Int -> Int
balancedMax -1 _ = -1
balancedMax _ -1 = -1
balancedMax a b = max a b
Run Code Online (Sandbox Code Playgroud)
翻转标志可以解决问题:
balancedMax :: Int -> Int -> Int
balancedMax 1 _ = -1
balancedMax _ 1 = -1
balancedMax a b = max a b
Run Code Online (Sandbox Code Playgroud)
为什么模式匹配在底片上失败,什么是干净的解决方法?
我有一个字符串值数组,有时会形成重复值模式('a','b','c','d')
$array = array(
'a', 'b', 'c', 'd',
'a', 'b', 'c', 'd',
'c', 'd',
);
Run Code Online (Sandbox Code Playgroud)
我想根据数组顺序找到重复的模式,并按相同的顺序对它们进行分组(以维护它).
$patterns = array(
array('number' => 2, 'values' => array('a', 'b', 'c', 'd')),
array('number' => 1, 'values' => array('c'))
array('number' => 1, 'values' => array('d'))
);
Run Code Online (Sandbox Code Playgroud)
请注意,[a,b],[b,c]和[c,d]本身不是模式,因为它们位于较大的[a,b,c,d]模式和最后的[c,d]集合中只出现一次因此它也不是一种模式 - 只是个别值'c'和'd'
另一个例子:
$array = array(
'x', 'x', 'y', 'x', 'b', 'x', 'b', 'a'
//[.......] [.] [[......] [......]] [.]
);
Run Code Online (Sandbox Code Playgroud)
哪个产生
$patterns = array(
array('number' => 2, 'values' => array('x')),
array('number' => 1, 'values' => array('y')),
array('number' => …Run Code Online (Sandbox Code Playgroud) 请考虑以下示例:
#lang racket
(match '(cat . doge)
[`(,a . ,b)
(match b
[a #t]
[_ #f])]
[_ "Not a pair"])
Run Code Online (Sandbox Code Playgroud)
如果我想匹配头部和尾部相同的对,我可能会写这个.这不起作用,因为第二个a绑定为一个新变量(并匹配任何东西).是否有任何模式形式允许我使用以前a从外部范围绑定的模式?
我知道这可以通过以下方式实现
(match* ('cat 'doge)
[(a a) #t]
[(_ _) #f])
Run Code Online (Sandbox Code Playgroud)
但我仍然想知道是否有办法从外部范围获取该变量(或者如果有理由不这样做,就像一些潜在的名称冲突问题或其他东西).
如果我有类似的类型data T = T Int String和这样的函数:
identity :: T -> T
identity (T a b) = T a b
Run Code Online (Sandbox Code Playgroud)
在模式匹配中解构之后,GHC是否创建了一个包含对同一个Int和String的引用的新T对象?或者它返回它收到的完全相同的对象(具有相同的内存地址)?我知道他们在语义上是等价的,我只是好奇.