我一直在努力学习哈斯克尔的书,学习自己一个哈克尔.本书涵盖take了以下方式的实现:
take' :: (Num i, Ord i) => i -> [a] -> [a]
take' n _
| n <= 0 = []
take' _ [] = []
take' n (x:xs) = x : take' (n-1) xs
Run Code Online (Sandbox Code Playgroud)
我对这段代码有两个问题:
在函数声明中我们为什么要使用相同的字母i来声明(Num i, Ord i)?这难道不是覆盖的事实,i是类型Num与i类型是Ord?
我想修改,take'以便如果n大于列表的长度,则打印出一条消息.我试图通过使用定义中的函数长度来实现这个'但是然后函数无法加载:
拿'n _
| n > length _ = print "n greater than length of list"
Run Code Online (Sandbox Code Playgroud)在函数声明中为什么我们使用相同的字母i来声明(Num i,Ord i)?这不会覆盖我是Num类型的事实,我的类型是Ord吗?
这不是类型声明,而是类型约束.这意味着" i某种类型既可以是数字也可以订购"(您可以使用不可订购的数字和不可数的可订购数据).
| n> length _ = print"n大于列表的长度"
这是行不通的,因为它_是一个通配符模式 - list参数实际上并没有绑定到任何东西._用一种模式写作意味着"我知道有些东西应该去那里,但我不在乎它是什么".如果你想使用那里的列表,你必须给它一个名字.
(提示:您不需要计算列表的长度 - 在另一种情况下,您可以检查调用者是否尝试从列表中取出比预期更多的元素)
(提示2:print "n greater than length of list"不会在那里工作,因为它是类型IO ()而不是[a]- 请记住该函数仍然需要返回正确的类型!如果您认为某些输入无效并且想要打印错误消息并终止您的程序,您可以使用error功能代替).