首页 > 解决方案 > 在 Haskell 中是否可以先编写包罗万象的模式?还是使用“负面”模式?

问题描述

有时,如果某个模式规则需要一些特殊的 rhs,通过 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

我认为它仍然不会被称为包罗万象,而是“包罗万象”,但是有什么办法可以做到这一点吗?

标签: haskellpattern-matchingreversefall-through

解决方案


如果你不需要绑定任何东西,你可以这样做:

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

推荐阅读