String 一丝不苟
我尝试在Idris中创建一个函数,如下所示: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
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)