想要从列表中选择第k个元素,可以像这样调用函数
selectN 5 aList
和我的功能
selectN :: Int -> a -> a
selectN 1 (x:_) = x
selectN [] _ = error "Index out of bounds"
selectN k (_:xs)
| n < 1 = error "Index out of bounds"
| otherwise = selectN xs (n - 1)
答案 0 :(得分:3)
好的,所以你的代码存在一些问题,所以首先让我们解决一下问题:
selectN :: Int -> a -> a --You take in a list of a ie [a] and return a. So this is bit off
selectN 1 (x:_) = x
selectN [] _ = error "Index out of bounds" -- Fine but not strictly needed
selectN k (_:xs)
| n < 1 = error "Index out of bounds"
| otherwise = selectN xs (n - 1) --You've got the params backwards here.
所以要解决这个问题,首先要找一个好的签名:
selectN :: Int -> [a] -> a
现在基本情况:
selectN 1 (x:_) = x --I would suggest using 0 not 1.
--Most things in Haskell are 0 based.
selectN n (x:xs) = selectN (n-1) xs
这样可行,没有有用的错误消息,但您可以弄清楚如何添加这些消息。
使用类型签名为
的(!!)
也可以轻松完成此操作
(!!) :: [a]->Int->a
所以
selectN = flip (!!)
查看hoogle这对这类事情有用。
答案 1 :(得分:1)
要选择列表的第k个元素,请使用!!
。第一个元素是索引0
selectN = (!!)
ghci> let test = "abracadabra"
ghci> test !! 0
ghci> 'a'
ghci> test !! 9
ghci> 'r'
但请注意indexOutOfRange
例外
ghci> test !! 11
*** Exception: Prelude.(!!): index too large
版本:使功能安全
可以编写safeSelectN
来处理错误异常,并允许程序在没有任何IO
操作的情况下安全地继续。要做到这一点,需要进行以下修改
safeSelectN :: Int -> [a] -> [a]
safeSelectN n xs = if null xs || length xs < n then [] else [xs !! n]
在这种情况下,将通过接收空列表来检测错误。
ghci> safeSelectN 3 ""
[]
ghci> safeSelectN 0 ""
[]
ghci> safeSelectN 3 "abcd" --like this
['d']
因此,当结果正确时,您不会仅使用第k个元素,而是使用仅包含第k个元素的列表。