分裂字符串时分裂头发

时间:2015-06-01 21:34:39

标签: string pattern-matching idris

我试图在Idris中创建一个函数,如下所示:

strSplit : String -> Maybe (Char, String)

这将是“不合情理的”。将字符串放入其第一个Char和字符串的其余部分,如果它是空的,则返回Nothing

所以我写了这篇文章,但失败了:

strSplit x = case strM of
    StrNil       => Nothing
    StrCons c cd => Just (c, cs)

所以我尝试了这个,有点像Prelude.Strings

strSplit x with (strM x)
    strSplit ""             | StrNil         = Nothing
    strSplit (strCons c cs) | (StrCons c cs) = Just (c, cs)

编译并运行没有任何问题。

我的问题是,为什么我必须使用with规则以这种方式拆分字符串,为什么我的原始方法会失败?

注意:很抱歉,我目前无法访问翻译,因此我无法在此处撰写错误消息。

1 个答案:

答案 0 :(得分:4)

这里有两个问题。首先,在'case'块中,参数是strM而不是strM x,因为它在'with'块中,所以你正在检查不同的东西。

但是有一个更有趣的问题,那就是如果你尝试修复第一个问题:

strSplit : String -> Maybe (Char, String)
strSplit x = case strM x of
    StrNil       => Nothing
    StrCons c cd => Just (c, cs)

你会得到一个不同的错误(这是来自当前的主人,它有重写的错误信息):

Type mismatch between
    StrM "" (Type of StrNil)
and
    StrM x (Expected type)

因此,'case'和'with'之间的区别在于'with'考虑到您正在检查的事物可能会影响左侧的类型和值。在'case'中,匹配strM x意味着x 必须为“”,但“case”可以出现在任何地方,并且不考虑对其他参数类型的影响(制定适当的对此类型检查规则将是一个非常大的挑战......)。

另一方面,'with'只能出现在顶层:实际上它正在做的是添加另一个顶级的东西来匹配,作为顶级,可以影响类型和其他模式的价值。

所以,简短的回答是'with'支持依赖模式匹配,但'case'不支持。