简体   繁体   English

在 Haskell 中是否可以先编写包罗万象的模式? 还是使用“负面”模式?

[英]Is it possible in Haskell to write the catch-all pattern first? Or use “negative” pattern?

Sometimes, if one the pattern rules need some special rhs which is made more readable via where , I end up with something like this有时,如果模式规则需要一些特殊的 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 the catch-all pattern seems to be so far from the other pattern, because of the lengthy where . where 包罗万象的模式似乎与其他模式相去甚远,因为where很长。 It'd be nice if I could write something like this:如果我能写出这样的东西就好了:

func :: D -> b
func !A = bla -- imaginary syntax
func A = special_case
  where
    special_case = other helper
    other = aaaa
    helper = bbb

I don't think it would still be called catch-all, but rather "catch-all-but", but is there any way to do this?我认为它仍然不会被称为包罗万象,而是“包罗万象”,但是有什么办法可以做到这一点吗?

If you don't need to bind anything, you could do something like this:如果你不需要绑定任何东西,你可以这样做:

isA :: D -> Bool
isA A = True
isA _ = False

func :: D -> b
func d | not (isA d) = bla
func A = special_case where ...

(You could alternately implement isn'tA to avoid the not . But while I've seen functions like isA defined every so often, I don't believe I've ever seen an analog of isn'tA in the wild.) (您可以交替实现isn'tA来避免not 。但是,虽然我经常看到像isA这样定义的函数,但我不相信我曾经在野外见过isn'tA的类似物。)

It might not be obvious to the compiler that this match is complete.对于编译器来说,这个匹配是否完整可能并不明显。 You could fix that like this:你可以像这样解决这个问题:

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 ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM