Haskell可以先写catch-all模式吗?或者使用 "negative" 模式?
Is it possible in Haskell to write the catch-all pattern first? Or use "negative" pattern?
有时,如果模式规则需要一些特殊的 rhs,通过 where
使其更具可读性,我最终会得到类似这样的东西
data D = A | B | C
func :: D -> b
func A = special_case
where
special_case = other helper
other = aaaa
helper = bbb
func _ = bla
由于冗长 where
,包罗万象的模式似乎与其他模式相去甚远。如果我能写这样的东西就好了:
func :: D -> b
func !A = bla -- imaginary syntax
func A = special_case
where
special_case = other helper
other = aaaa
helper = bbb
我不认为它仍然会被称为 catch-all,而是“catch-all-but”,但是有什么办法可以做到这一点吗?
如果你不需要绑定任何东西,你可以这样做:
isA :: D -> Bool
isA A = True
isA _ = False
func :: D -> b
func d | not (isA d) = bla
func A = special_case where ...
(您可以交替实现 isn'tA
来避免 not
。但是虽然我经常看到像 isA
这样的函数定义,但我不相信我已经在野外见过 isn'tA
的类似物。)
编译器可能无法明显看出此匹配已完成。你可以这样解决:
type A'sFields = () -- your specific D doesn't have any fields for A,
-- but this pattern is general enough to use for
-- constructors that do
fromA :: D -> Maybe A'sFields
fromA A = Just ()
fromA _ = Nothing
func :: D -> b
func d = case fromA d of
Nothing -> bla
Just () -> special_case where ...
有时,如果模式规则需要一些特殊的 rhs,通过 where
使其更具可读性,我最终会得到类似这样的东西
data D = A | B | C
func :: D -> b
func A = special_case
where
special_case = other helper
other = aaaa
helper = bbb
func _ = bla
由于冗长 where
,包罗万象的模式似乎与其他模式相去甚远。如果我能写这样的东西就好了:
func :: D -> b
func !A = bla -- imaginary syntax
func A = special_case
where
special_case = other helper
other = aaaa
helper = bbb
我不认为它仍然会被称为 catch-all,而是“catch-all-but”,但是有什么办法可以做到这一点吗?
如果你不需要绑定任何东西,你可以这样做:
isA :: D -> Bool
isA A = True
isA _ = False
func :: D -> b
func d | not (isA d) = bla
func A = special_case where ...
(您可以交替实现 isn'tA
来避免 not
。但是虽然我经常看到像 isA
这样的函数定义,但我不相信我已经在野外见过 isn'tA
的类似物。)
编译器可能无法明显看出此匹配已完成。你可以这样解决:
type A'sFields = () -- your specific D doesn't have any fields for A,
-- but this pattern is general enough to use for
-- constructors that do
fromA :: D -> Maybe A'sFields
fromA A = Just ()
fromA _ = Nothing
func :: D -> b
func d = case fromA d of
Nothing -> bla
Just () -> special_case where ...