You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PureScript嵌套穷举模式匹配的静态检查可行方案问询

Haskell编译器无法自动推断other不可能是Bar构造器,因此会判定后续的case语句非穷举。要实现静态可检查的穷举匹配,可通过以下几种方式:

方案1:拆分类型(最直观)

将Foo拆分为包含Bar的主类型,以及仅包含Quux、Baz的子类型,让编译器明确子类型的构造器范围:

data Foo = Bar Int | NonBar NonBarFoo
data NonBarFoo = Quux Int | Baz Int

f :: Foo -> Int
f (Bar n) = n
f (NonBar nb) = case nb of
  Quux n -> 2 * n
  Baz n -> 3 * n

g :: Foo -> Int
g foo = case foo of
  Bar n -> n
  NonBar nb -> case nb of
    Quux n -> 2 * n
    Baz n -> 3 * n

处理NonBarFoo的case语句会被编译器判定为完全穷举,因为NonBarFoo仅包含Quux和Baz两个构造器,不存在其他分支。

方案2:使用GHC扩展的COMPLETE编译指示(保留原类型)

如果不想拆分类型,可借助GHC的PatternSynonyms和ViewPatterns扩展,手动告知编译器已排除Bar构造器:

{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}

data Foo = Bar Int | Quux Int | Baz Int

-- 定义视图模式,匹配非Bar的构造器
pattern NonBar :: Foo -> Foo
pattern NonBar x <- (filterBar -> Just x)
  where NonBar x = x

filterBar :: Foo -> Maybe Foo
filterBar (Bar _) = Nothing
filterBar x = Just x

-- 告知编译器:匹配NonBar视图返回的Foo时,Quux和Baz是穷举的
{-# COMPLETE Quux, Baz #-}

f :: Foo -> Int
f (Bar n) = n
f (NonBar other) = case other of
  Quux n -> 2 * n
  Baz n -> 3 * n

COMPLETE编译指示会让GHC确认,此时无需再处理Bar分支,从而判定case语句穷举。

方案3:合并模式匹配(最简洁)

如果不需要拆分逻辑,直接将所有构造器放在同一个case中,天然满足静态穷举检查:

data Foo = Bar Int | Quux Int | Baz Int

f :: Foo -> Int
f foo = case foo of
  Bar n -> n
  Quux n -> 2 * n
  Baz n -> 3 * n

g :: Foo -> Int
g = \case
  Bar n -> n
  Quux n -> 2 * n
  Baz n -> 3 * n

内容的提问来源于stack exchange,提问作者Brennan Vincent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 07:13:16