如何返回给定列表中第n对的第二个项目(Haskell)

时间:2018-07-18 23:08:22

标签: haskell

我想知道如何在给定列表中返回第n对的第二个项目。所以我们有

header

因此,如果我们输入

nth :: Int -> [(Int,Int)] -> Int

它应该返回8,因为这是第三对的第二项。

这是我到目前为止所获得的,它不起作用...

nth 3 [(2,0),(1,4),(3,8)]

有人可以协助吗?

谢谢 山姆

4 个答案:

答案 0 :(得分:2)

要填写到目前为止的内容:

nth :: Int -> [(Int,Int)] -> Int
nth n [] = error "??"
nth 0 (x:xs) = snd x
nth n (x:xs)
  |n > 0 && n < length (x:xs) = nth (n-1) xs

snd函数仅返回一对的第二个元素)

但是,您可以尝试将!!snd这些函数简单地组合在一起:

nth' :: Int -> [(Int,Int)] -> Int
nth' n xs = snd (xs !! n)

答案 1 :(得分:1)

您需要在列表的 tail 递归。因此,您可以再次调用该函数,但要使用n-1和列表的末尾。作为基本情况,然后检查索引是否为大小写,返回此大小写的第二个元素,返回该元组的第二个元素。不使用任何内置函数的实现,可能看起来像这样:

nth :: Int -> [(a, b)] -> b
nth _ [] = error "Index too large"
nth n _ | n <= 0 = error "Index too small"
nth 1 ((_, b):_) = b
nth n (_: xs) = nth (n-1) xs

但是实际上我们可以使用(!!) :: [a] -> Int -> a(.) :: (b -> c) -> (a -> b) -> a -> csnd :: (a, b) -> b功能,因此可以这样写:

nth n = snd . (!! (n-1))

答案 2 :(得分:1)

您可以先将问题分解成小部分,然后进行工作,测试每个部分;你终于把它们放回去了。

InherTest

将以上3个放在一起即可得到:

-- 1. Pair each element with an index starting from 1   -> [(Int, (Int, Int))]
-- 2. Find the nth-index element                        -> Maybe (Int, (Int, Int))
-- 3. Get the 2nd element of the second element         -> Int

答案 3 :(得分:0)

nth2nd :: Int -> [(Int,Int)] -> Int
nth2nd n xs = head [b | (i,(_,b)) <- zip [1..] xs, i==n]

是您所需要的。当然,此函数是部分函数,​​即如果n大于列表的长度,则会导致错误;如果n小于1,则将尝试遍历整个列表,并且然后导致错误(如果列表无限,则无限循环。)

通常不认为这是件好事。我们通常更喜欢用Maybe来说明失败的可能性,从而使函数 total

import Data.Maybe

nth2ndMaybe :: Int -> [(Int,Int)] -> Maybe Int
nth2ndMaybe n xs = listToMaybe [b | (i,(_,b)) <- zip [1..] xs, i==n]

尽管如此,它仍会在非肯定的n上轰炸。添加警卫将有助于处理这种情况,最好通过显式返回Nothing

nth2ndMaybe n xs 
          | n < 1     = Nothing
          | otherwise = ......