关于LYAH实施的问题

Luk*_*ell 1 haskell

我一直在努力学习哈斯克尔的书,学习自己一个哈克尔.本书涵盖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)

我对这段代码有两个问题:

  1. 在函数声明中我们为什么要使用相同的字母i来声明(Num i, Ord i)?这难道不是覆盖的事实,i是类型Numi类型是Ord

  2. 我想修改,take'以便如果n大于列表的长度,则打印出一条消息.我试图通过使用定义中的函数长度来实现这个'但是然后函数无法加载:

    拿'n _

        | n > length _ = print "n greater than length of list"
    
    Run Code Online (Sandbox Code Playgroud)

Cub*_*bic 5

在函数声明中为什么我们使用相同的字母i来声明(Num i,Ord i)?这不会覆盖我是Num类型的事实,我的类型是Ord吗?

这不是类型声明,而是类型约束.这意味着" i某种类型既可以是数字也可以订购"(您可以使用不可订购的数字和不可数的可订购数据).

| n> length _ = print"n大于列表的长度"

这是行不通的,因为它_是一个通配符模式 - list参数实际上并没有绑定到任何东西._用一种模式写作意味着"我知道有些东西应该去那里,但我不在乎它是什么".如果你想使用那里的列表,你必须给它一个名字.

(提示:您不需要计算列表的长度 - 在另一种情况下,您可以检查调用者是否尝试从列表中取出比预期更多的元素)

(提示2:print "n greater than length of list"不会在那里工作,因为它是类型IO ()而不是[a]- 请记住该函数仍然需要返回正确的类型!如果您认为某些输入无效并且想要打印错误消息并终止您的程序,您可以使用error功能代替).