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

Haskell能否通过模式匹配解构数字?如f(n+1)=n实现前驱函数

Fixing the Parse Error for n + 1 Pattern Matching in Haskell

Great question! That n + 1 pattern you're trying to use is called N+K Patterns—a GHC-specific extension that's not enabled by default in standard Haskell, which is exactly why you're hitting that parse error. Let's break down how to resolve this, plus some better alternatives (since this extension is actually deprecated in modern GHC versions).

Option 1: Enable the N+K Patterns Extension

To get your original pattern working, you just need to turn on the right GHC flag:

  • In GHCi, run this first before defining your function:
    :set -XNPlusKPatterns
    f (n + 1) = n
    
  • In a source file, add the extension pragma at the very top:
    {-# LANGUAGE NPlusKPatterns #-}
    f (n + 1) = n
    

This will let GHC parse the n + 1 pattern correctly. But a heads-up: this extension is marked as deprecated, so it's not the long-term recommended approach for production code.

Option 2: Use Guards (Standard Haskell)

A cleaner, extension-free way to write your predecessor function is using guards. This works with all standard Haskell compilers and is more readable for most developers:

f n | n > 0 = n - 1
    | otherwise = error "f requires a positive integer (0 has no predecessor)"

No special flags needed, and it plays nicely with all Haskell tooling.

Option 3: Use Standard Library or Explicit Pattern Matching

If you just need a predecessor function, Haskell's standard library already has pred—pred 6 returns 5, pred 5 returns 4. Note that pred 0 will give you -1 for Int types, or throw an error if you're using the unsigned Natural type.

If you want to roll your own without extensions, explicit pattern matching works too:

f 0 = error "0 has no predecessor"
f n = n - 1

Or, if you're working with naturals specifically, a custom algebraic data type is even more idiomatic (pure functional style, no extensions required):

data Nat = Zero | Succ Nat deriving (Show)

f (Succ n) = n  -- Match any successor value, return its underlying natural
f Zero = error "Zero has no predecessor"

About That n'@(n + 1) Syntax You Saw

The n'@(n + 1) pattern combines N+K patterns with an as-pattern (@) to bind both the full value (n') and the decomposed part (n). This also requires the NPlusKPatterns extension, like so:

{-# LANGUAGE NPlusKPatterns #-}
facCPS n'@(n + 1) k = facCPS n (\x -> k (n' * x))
facCPS 0 k = k 1

But to avoid relying on deprecated features, rewrite it with guards instead (this is the modern recommended approach):

facCPS n k | n > 0 = facCPS (n - 1) (\x -> k (n * x))
           | otherwise = k 1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 18:52:30