首页 > 解决方案 > 关于 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  

我对此代码有两个问题:

  1. 在函数声明中为什么我们使用相同的字母i来声明(Num i, Ord i)?这不会用is of type覆盖iis of type的事实吗?NumiOrd

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

    拿'n_

        | n > length _ = print "n greater than length of list"
    

标签: haskell

解决方案


在函数声明中为什么要使用相同的字母 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代替功能)。


推荐阅读