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

Haskell模式同义词中提取公共常量的相关技术疑问

Haskell模式同义词相关问题解答

问题背景

我原本有这段代码:

newtype T = T Text

pattern Alice = T "Alice" 

这没问题,但因为其他地方也要用到"Alice",我把它提取成了顶层值:

alice :: Text
alice = "Alice"

pattern Alice = T alice

开启警告编译时收到了未使用变量的警告,这时候我才意识到,pattern Alice = T alice其实会匹配所有T类型的值,而非仅匹配T "Alice"。另外我还觉得T "Alice"能作为模式被允许有点奇怪,毕竟"Alice"是计算得到的Text值。后来在Overloaded Strings的文档里看到:

字符串字面量的行为非常类似整数字面量,即可同时用于表达式和模式中。若用于模式中,字面量会被替换为相等性测试,就像整数字面量一样。

由此引出两个问题:

  1. 不启用Overloaded Strings扩展,我能否编写Alice模式?
  2. 能否创建右侧需要计算的模式同义词,让GHC像处理数值和字符串字面量一样使用Eq进行匹配?还是数值和字符串字面量是特殊情况,GHC不允许泛化该功能?

问题解答

1. 不启用Overloaded Strings能否编写Alice模式?

可以,但需要结合其他扩展调整写法:

  • 不启用Overloaded Strings时,字符串字面量"Alice"的类型是String,而T构造器接受的是Text,直接写T "Alice"会出现类型不匹配。
  • 使用ViewPatterns扩展可实现单向匹配模式:
{-# LANGUAGE ViewPatterns #-}
import Data.Text (Text, pack)

newtype T = T Text

pattern Alice <- T (pack "Alice" -> ())
  • 如果需要既能匹配又能构造的双向模式,可结合PatternSynonyms扩展:
{-# LANGUAGE PatternSynonyms #-}
import Data.Text (Text, pack)

newtype T = T Text

pattern Alice :: T
pattern Alice = T (pack "Alice")

这里的pack "Alice"会在构造时被求值,匹配时则依赖GHC对这种“字面量转换表达式”的特殊处理,本质上是把它当作常量模式来匹配。

2. 能否创建依赖计算值的模式同义词,让GHC用Eq匹配?

数值和字符串字面量确实是GHC的特殊处理情况,编译器会自动将它们的模式匹配转换为相等性测试,但目前没有直接语法支持将任意计算值泛化为这种模式。不过可以通过以下方式实现类似效果:

  • 使用ViewPatterns实现匹配逻辑:通过视图模式提取值并显式做相等性检查:
{-# LANGUAGE ViewPatterns #-}
import Data.Text (Text)

alice :: Text
alice = "Alice"

newtype T = T Text

pattern Alice <- T (\x -> x == alice -> True)

这个模式会提取T包裹的Text,检查它是否等于预定义的alice,符合条件则匹配成功。

  • 定义双向模式同义词:如果需要模式既能匹配又能构造,可结合PatternSynonyms和ViewPatterns:
{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
import Data.Text (Text)

alice :: Text
alice = "Alice"

newtype T = T Text

pattern Alice :: T
pattern Alice <- T (== alice -> True)
  where Alice = T alice

where子句定义了模式的构造逻辑,匹配时则通过视图模式做相等性检查。

简单来说:数值、字符串字面量是编译器特殊优化的情况,但你可以通过ViewPatterns或带显式逻辑的模式同义词,实现基于Eq实例的自定义匹配模式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 19:07:08