简体   繁体   English

如何在haskell中显示给定范围的列表

[英]How display list given range in haskell

How do I write a function that displays a given range in a list in Haskell? 如何编写在Haskell列表中显示给定范围的函数? Say that I have the function: 说我有功能:

dispRange l x y

that when given values: 当给定值时:

dispRange [1,2,4,5,6,7] 0 3 

displays all the elements from position 0 to 3, thus the list returned would be: 显示从位置0到3的所有元素,因此返回的列表为:

[1,2,4,5]

We can use a combination of drop :: Int -> [a] -> [a] and take :: Int -> [a] -> [a] for this: 我们可以使用drop :: Int -> [a] -> [a]take :: Int -> [a] -> [a]

For a range i to j , we first drop i elements, and then take j-i+1 elements (since both indices are inclusive , we thus need to add one). 对于从ij的范围,我们首先删除 i元素,然后 j-i+1元素(由于两个索引都包含在内 ,因此我们需要添加一个)。

For example: 例如:

dispRange :: [a] -> Int -> Int -> [a]
dispRange l i j = take (j-i+1) (drop i l)

We can guard against negative numbers and j being less than i with: 我们可以防止负数和j小于i情况:

dispRange :: [a] -> Int -> Int -> Maybe [a]
dispRange l i j | i < 0 || j < i = Nothing
                | otherwise = Just (take (j-i+1) (drop i l))

dispRange consumes a list: l , the start: x and the end: y of a range inclusively. dispRange一个列表: l ,范围的dispRangex和结束值: y It returns the elements within that range if the range is not negative. 如果范围不是负数,它将返回该范围内的元素。

import Data.List ((\\))

dispRange :: Eq a => [a] -> Int -> Int -> [a]
dispRange l x y  
  | x <= y = (\\) <$> take (y + 1) <*> take x $ l
  | otherwise = []

If you want to do it in a way that doesn't use built-in functions (for beginner's learning), you can break it into two stages: 如果您想以一种不使用内置功能的方式进行操作(供初学者学习),则可以将其分为两个阶段:

  1. Chop off the first x elements, recursively calling your function and changing the arguments as appropriate. 砍掉前x个元素,递归地调用函数并根据需要更改参数。
  2. Return the next y elements, recursively calling your function and changing the arguments as appropriate. 返回下一个y元素,以递归方式调用您的函数并根据需要更改参数。

Your code will look like this: 您的代码将如下所示:

dispRange :: …
dispRange … … … = []
dispRange … … … = dispRange … … …
⋮  ⋮  ⋮  ⋮  ⋮  ⋮  ⋮  ⋮  ⋮  ⋮
dispRange … … … = dispRange … … …

So, the questions are: 因此,问题是:

  • What are the types of the arguments and the value returned? 参数的类型和返回的值是什么?
  • What do the inputs of the base and recursive cases look like for stage one above? 对于上面的第一阶段,基本案例和递归案例的输入是什么样的?
  • What do the inputs of the base and recursive cases look like for stage two above? 上面第二阶段的基本案例和递归案例的输入是什么样的?

Now, you can write the type signature and the patterns on the left of the equal signs (remember that patterns above take priority over patterns below, so order them properly). 现在,您可以在等号的左侧写入类型签名和模式(请记住,上面的模式优先于下面的模式,因此请正确排序)。 Then, you can write the implementation of each case on the right of the equal sign. 然后,您可以在等号右边编写每种情况的实现。


If you have trouble, another way is to try making a function that does just stage one. 如果遇到麻烦,另一种方法是尝试制作一个仅阶段性的功能。 Then, try making a function that does just stage two. 然后,尝试制作仅执行第二阶段的功能。 Then, use those functions in your dispRange function. 然后,在dispRange函数中使用这些函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM