劈毛劈弦
Splitting hairs whilst splitting strings
我试着在 Idris 中创建一个函数,如下所示:
strSplit : String -> Maybe (Char, String)
这会将字符串 'un-cons' 分为第一个 Char
和字符串的其余部分,如果它是空的 return 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
规则以这种方式拆分字符串,为什么我原来的方法会失败?
注意:抱歉,我暂时无法访问翻译,所以我还不能在这里写错误信息。
这里有两个问题。首先,在 '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' 不支持。
我试着在 Idris 中创建一个函数,如下所示:
strSplit : String -> Maybe (Char, String)
这会将字符串 'un-cons' 分为第一个 Char
和字符串的其余部分,如果它是空的 return 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
规则以这种方式拆分字符串,为什么我原来的方法会失败?
注意:抱歉,我暂时无法访问翻译,所以我还不能在这里写错误信息。
这里有两个问题。首先,在 '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' 不支持。