热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Haskell:尝试使用两个参数定义函数时出错

如何解决《Haskell:尝试使用两个参数定义函数时出错》经验,为你挑选了1个好方法。

我正在尝试定义一个简单的函数,将单个整数列表转换为一个更大的整数.例如,给定列表[1,5,2,0]它将返回1520.为了在基数10中执行此操作,我使用了:

calc_nr [] = 0
calc_nr (a:y) = a * 10^(length y) + (calc_nr y)

现在,我想将它扩展到不同的基础,这可以通过将表达式中的基数10幂更改为所需的基数来完成.为此,我考虑接受另一个论点b,并将基数为10的幂替换为基本b幂.
但是,当我尝试这样做时,我遇到了一些错误.写作:

calc_nr b [] = 0
calc_nr b (a:y) = a * b^(length y) + (calc_nr y)

给我错误:

* Occurs check: cannot construct the infinite type: t ~ [t]
  Expected type: [t] -> t
    Actual type: t -> [t] -> t
* Relevant bindings include
    calc_nr :: [t] -> t (bound at calc_nr.hs:39:1)

我是Haskell的新手,所以也许这是一个非常愚蠢的错误,但任何帮助都会非常感激!



1> leftaroundab..:

首先,一些一般建议:

始终为顶级函数编写类型签名.这有很多优点(稍后会详细介绍),但也许最重要的是,阅读代码的人会理解它应该做什么.你的旧固定基础功能将是

fromBase10rep :: [Int] -> Int

(你也可以使它与其他数字类型一起使用Int,但我不会为了简单起见而这样做.)

避免不必要的括号.

fromBase10Rep (a:y) = a * 10 ^ length y + calc_nr y

避免length并索引到列表中.这是低效的(每次执行时都需要遍历整个列表).

如果你只是按照第一点,你可能会自己回答这个问题......

fromBaseRep :: Int -> [Int] -> Int
fromBaseRep b [] = 0
fromBaseRep b (a:y) = a * b ^ length y + fromBaseRep y

因为,由于类型签名,编译器现在能够提供更清晰的错误消息:

/tmp/wtmpf-file21653.hs:3:42: error:
    • Couldn't match expected type ‘Int’
                  with actual type ‘[Int] -> Int’
    • Probable cause: ‘fromBaseRep’ is applied to too few arguments
      In the second argument of ‘(+)’, namely ‘fromBaseRep y’
      In the expression: a * b ^ length y + fromBaseRep y
      In an equation for ‘fromBaseRep’:
          fromBaseRep b (a : y) = a * b ^ length y + fromBaseRep y
  |
3 | fromBaseRep b (a:y) = a * b ^ length y + fromBaseRep y
  |                                          ^^^^^^^^^^^^^

基本上它会告诉你究竟是什么问题:你fromBaseRep在递归调用中应用了太少的参数.它仍然需要知道在哪个基础上重新组合其余的数字!

所以b再次传递它,你会没事的.

fromBaseRep b (a:y) = a * b ^ length y + fromBaseRep b y

正如我所说,由于这个length电话,这仍然是非常低效的.解决这个问题的一个好方法是在向列表深处递归的同时将左数字乘以:

fromBaseRep b = go 0
 where go acc [] = acc
       go acc (a:y) = go (b*acc + a) y

请注意,将递归委托给本地"循环函数" go也允许我省略显式传递b- 它只是从fromBaseRep b = ...绑定中重新使用.

这也可以优雅地写成折叠:

fromBaseRep b = foldl' ((+) . (b*)) 0


推荐阅读
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 本文讨论了一个数列求和问题,该数列按照一定规律生成。通过观察数列的规律,我们可以得出求解该问题的算法。具体算法为计算前n项i*f[i]的和,其中f[i]表示数列中有i个数字。根据参考的思路,我们可以将算法的时间复杂度控制在O(n),即计算到5e5即可满足1e9的要求。 ... [详细]
  • node.jsrequire和ES6导入导出的区别原 ... [详细]
  • node.jsurlsearchparamsAPI哎哎哎 ... [详细]
  • 本文介绍了在Go语言中可见性与scope的规则,包括在函数内外声明的可见性、命名规范和命名风格,以及变量声明和短变量声明的语法。同时,还介绍了变量的生命周期,包括包级别变量和局部变量的生命周期,以及变量在堆和栈上分配的规则和逃逸分析的概念。 ... [详细]
  • 本文介绍了一种求解最小权匹配问题的方法,使用了拆点和KM算法。通过将机器拆成多个点,表示加工的顺序,然后使用KM算法求解最小权匹配,得到最优解。文章给出了具体的代码实现,并提供了一篇题解作为参考。 ... [详细]
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
author-avatar
手机用户2502875333
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有