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

使用PatternSynonyms为何触发非穷尽匹配警告?

为什么PatternSynonyms写法会触发非穷尽匹配警告?

你用ViewPatterns实现的BFS没有匹配警告,但改用PatternSynonyms后编译器提示非穷尽匹配,核心原因是默认的模式同义词是单向的,编译器无法推导你定义的Empty和:>能覆盖所有Sequence的可能情况。

原因拆解

  • 在ViewPatterns的写法里,你直接将序列传给Seq.viewr,编译器明确知道Seq.viewr的返回类型ViewR a只有EmptyR和(:>)两种构造器,因此能判定你的匹配是穷尽的。
  • 但你定义的Empty和:>是单向模式同义词(只有匹配方向的<−定义,没有构造方向的=定义),编译器无法将它们与Sequence的内部构造逻辑关联起来,自然会认为存在未覆盖的情况(比如内部的EmptyT构造器),从而抛出警告。

修复方案

方案一:用COMPLETE编译指示声明模式完备性

直接告诉编译器,Empty和:>这两个模式可以覆盖所有Seq.Seq a的情况,不需要额外构造逻辑:

{-# LANGUAGE PatternSynonyms #-}

import qualified Data.Sequence as Seq
import qualified Data.Set as Set

pattern Empty :: Seq.Seq a
pattern Empty <- (Seq.viewr -> Seq.EmptyR)

pattern (:>) :: Seq.Seq a -> a -> Seq.Seq a
pattern xs :> x <- (Seq.viewr -> xs Seq.:> x)

-- 告诉编译器这两个模式覆盖所有Sequence情况
{-# COMPLETE Empty, (:>) #-}

bfsPat :: Seq.Seq ((Int, Int), Int) -> Set.Set (Int, Int) -> Int
bfsPat Empty _ = -1
bfsPat (coords :> (coord@(r, c), dist)) seen = -- 你的搜索逻辑

方案二:定义双向模式同义词(支持匹配和构造)

给模式同义词加上构造方向的定义,让编译器既能用它匹配,也能用来构造序列,同时自动识别其完备性:

{-# LANGUAGE PatternSynonyms #-}

import qualified Data.Sequence as Seq
import qualified Data.Set as Set

-- 双向模式:既匹配空序列,也能构造空序列
pattern Empty :: Seq.Seq a
pattern Empty = Seq.empty
pattern Empty <- (Seq.viewr -> Seq.EmptyR)

-- 双向模式:匹配尾部元素,也能通过尾部添加构造序列
pattern (:>) :: Seq.Seq a -> a -> Seq.Seq a
pattern xs :> x <- (Seq.viewr -> xs Seq.:> x)
  where xs :> x = xs Seq.|> x

bfsPat :: Seq.Seq ((Int, Int), Int) -> Set.Set (Int, Int) -> Int
bfsPat Empty _ = -1
bfsPat (coords :> (coord@(r, c), dist)) seen = -- 你的搜索逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 08:45:32