String 一丝不苟

String 一丝不苟,string,pattern-matching,idris,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) 然后我尝试了这个,有点像《序曲.字符串》: str

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

strSplit : String -> Maybe (Char, String)
这会将字符串“反编译”为其第一个
Char
和字符串的其余部分,如果字符串为空,则返回
Nothing

所以我写了这个,失败了:

strSplit x = case strM of
    StrNil       => Nothing
    StrCons c cd => Just (c, cs)
然后我尝试了这个,有点像《序曲.字符串》:

strSplit x with (strM x)
    strSplit ""             | StrNil         = Nothing
    strSplit (strCons c cs) | (StrCons c cs) = Just (c, cs)
编译并运行时没有问题

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


注意:抱歉,我目前无法访问解释器,因此我还无法在此处写入错误消息。

这里有两个问题。首先,在“case”块中,参数是
strM
,而不是
strM x
,因为它在“with”块中,所以您要检查不同的内容

不过,还有一个更有趣的问题,即如果您尝试修复第一个问题:

strSplit : String -> Maybe (Char, String)
strSplit x = case strM x of
    StrNil       => Nothing
    StrCons c cd => Just (c, cs)
您将收到一个不同的错误(这是来自已重写错误消息的当前主机):

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

另一方面,“with”只能出现在顶层:实际上,它所做的是添加另一个顶层匹配,作为顶层,它可以影响其他模式的类型和值


因此,简单的回答是,“with”支持依赖模式匹配,但“case”不支持。

哎呀,上面的代码就是我的意思,但我打错了。谢谢你纠正我!我不知道伊德里斯,但你有一个关于stackoverflow的标题最好的问题,我的朋友:-)
Type mismatch between
    StrM "" (Type of StrNil)
and
    StrM x (Expected type)