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

如何为基于Maybe的newtype Property自定义正确的Show实例?

为什么需要用showsPrec 11而不是10?

核心原因是Haskell中showsPrec的括号规则,以及函数应用的优先级特性:

  1. 函数/构造函数应用的优先级是10
    所有函数(包括构造函数)的应用操作优先级都是10,且是左结合的。比如Just 5是优先级10的表达式,Property Just 5会被解析为(Property Just) 5——这显然不是你想要的,你需要的是Property (Just 5),让Just 5作为Property的单个参数。

  2. showsPrec的括号判定规则
    showsPrec d x生成表达式x的字符串时,会根据x的固有优先级和传入的d(当前上下文优先级)决定是否加括号:

    • 如果x的固有优先级 小于 d,则给x包裹括号;
    • 否则直接输出,不加括号。
  3. 为什么用11?
    你的参数x(比如Just 5)是一个优先级为10的构造函数应用。要让它被括号包裹,必须满足10 < d——也就是d要大于10,最小的取值就是11。

    • 当用showsPrec 10 x时,10 < 10不成立,所以直接输出Just 5,导致最终结果是Property Just 5,产生歧义;
    • 当用showsPrec 11 x时,10 < 11成立,所以输出(Just 5),最终得到正确的Property (Just 5)。
  4. 完整的Show实例参考
    结合你的需求,正确的Show实例应该是这样的:

    instance Show a => Show (Property a) where
      showsPrec _ (Property Nothing) = showString "NoProperty"
      showsPrec d (Property (Just x)) =
        showParen (d > 10) $
          showString "Property " . showsPrec 11 x
    

    这里的showParen (d > 10)是为了遵循Show类的规范:当Property ...处于优先级高于10的上下文时(虽然Haskell中没有这种场景),会给整个表达式加括号,保持输出的正确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 07:35:57