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

Haskell二进制2^k位提取函数的参数校验与错误修正求助

修正Haskell函数stelle的问题

我需要实现两项任务,其中第二项是用Haskell编写名为stelle的函数:

  • 任务2:输入两个自然数n、k(非负整数),输出n的二进制表示中2^k位上的数字。

我两次尝试编写代码都存在问题,第一次代码最后一行有语法错误,原本想校验n和k必须为非负整数,不满足就抛出错误;第二次代码逻辑仍有问题,现寻求修正。

两次尝试的代码

第一次尝试

stelle :: Int -> Int -> Int
stelle n 0 = mod n 2
stelle n k = stelle (div n 2) (k-1)
stelle n k = n k <= O = error

第二次尝试

stelle :: Int -> Int -> Int                                  
stelle n 0 = mod n 2                                         
stelle n k
| n < 0 && k < 0 = error "Vorraussetzung nicht erfüllt" 
| n >= 0 && k >= 0 = (div n 2) (k-1)

问题分析

  1. 第一次尝试的问题:

    • 最后一行完全不符合Haskell语法,既不是合法的模式匹配也不是守卫表达式,O是拼写错误(应为数字0),整体写法导致语法报错。
    • 参数校验逻辑的位置错误,Haskell模式匹配按顺序执行,错误分支写在最后无法被触发。
  2. 第二次尝试的问题:

    • 守卫条件n < 0 && k < 0仅校验两者同时为负的情况,但只要其中一个参数为负就属于非法输入,应使用逻辑或||而非逻辑与&&。
    • 合法分支里的(div n 2) (k-1)是错误写法:div n 2计算的是整数结果,不是函数,无法接收参数,正确做法是递归调用stelle函数。
    • 缺少对部分非法情况的处理(比如n负k正、n正k负),会导致非穷尽模式匹配错误。

修正后的代码

stelle :: Int -> Int -> Int
stelle n k
  | n < 0 || k < 0 = error "参数必须为非负整数"
  | k == 0 = mod n 2
  | otherwise = stelle (div n 2) (k - 1)

修正说明

  • 优先通过守卫表达式做参数校验,只要n或k为负就抛出错误,覆盖所有非法输入场景。
  • 将k=0的终止条件放到守卫中,和递归分支清晰区分,避免模式匹配顺序问题。
  • 递归分支正确调用stelle函数,传递div n 2(二进制右移一位的结果)和k-1作为新参数,符合二进制位提取的逻辑。
  • 用otherwise覆盖所有合法的k>0情况,保证模式匹配穷尽,避免运行时错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 21:45:29