haskell - 关于 LYAH 执行 take 的问题
问题描述
我一直在尝试通过《自学haskell》一书来学习haskell。本书涵盖了take
以下方式的实现:
take' :: (Num i, Ord i) => i -> [a] -> [a]
take' n _
| n <= 0 = []
take' _ [] = []
take' n (x:xs) = x : take' (n-1) xs
我对此代码有两个问题:
在函数声明中为什么我们使用相同的字母
i
来声明(Num i, Ord i)
?这不会用is of type覆盖i
is of type的事实吗?Num
i
Ord
我想修改
take'
,以便如果 n 大于列表的长度,则打印出一条消息。我试图通过使用 take' 定义中的函数长度来实现这一点,但是该函数无法加载:拿'n_
| n > length _ = print "n greater than length of list"
解决方案
在函数声明中为什么要使用相同的字母 i 来声明 (Num i, Ord i)?这不会覆盖 i 是 Num 类型而 i 是 Ord 类型的事实吗?
这不是类型声明,而是类型约束。这意味着“i
是某种既是数字又是可排序的类型”(您可以拥有不可排序的数字和非数字的可排序事物)。
| n > 长度 _ = print "n 大于列表长度"
这不起作用,因为_
它是通配符模式 - list 参数实际上并未绑定到任何东西。以模式书写_
意味着“我知道有一些东西应该去那里,但我不在乎它是什么”。如果你想使用那里的列表,你必须给它一个名字。
(提示:您不需要计算列表的长度 - 还有另一种情况,您可以检查调用者是否试图从列表中取出比预期更多的元素)
(提示 2:print "n greater than length of list"
不会在那里工作,因为它是类型IO ()
而不是[a]
- 请记住,该函数仍然需要返回正确的类型!如果您认为某些输入无效并且想要打印错误消息并终止您的程序,您可以使用error
代替功能)。
推荐阅读
- java - Tarjan 算法对于这个测试用例是否失败?参考:gfg 和 Tushar roy 的教程
- php - onclick ajax 删除确认模式导致先前的请求 ajax 也处理
- c++ - 知道为什么 Doxygen 找到 version.h.in 但不将其解析为 C 或 C++?
- material-ui - 从 Material-UI 主题创建可以跨组件重用的样式?
- excel - 循环浏览文件夹并合并 Excel 文件 - 1 个 Excel 文件,多个工作表
- generics - 有没有办法为智能指针中的对象通用实现特征?
- android - Spinner当前选中的item被重复选中
- swift - 如何克服这个“无法使用类型为'(String?)'的参数列表调用类型'Double'的初始化程序”
- python - 有没有办法在没有 for 循环的情况下在 Django 中呈现表单集?
- python - 如何从三个数组创建 x、y、z 坐标,其中 x 和 y 是使用 meshgrid 生成的,而 z 取决于 x?