Ale*_*rov 4 haskell functional-programming
我正在尝试通过本课程学习 Haskell ,但我对第一个模块中的最后一个作业有点困惑。问题陈述听起来如下:
编写一个函数,它接受一个数字和一个数字列表并返回一个字符串,说明列表中有多少元素严格大于给定数字并严格小于给定数字。
Run Code Online (Sandbox Code Playgroud)lowerAndGreater 3 [1 .. 9] "3 is greater than 2 elements and lower than 6 elements"解释:列表 [1 .. 9] 包含 9 个元素: [1, 2, 3, 4, 5, 6, 7, 8, 9] 给定数字 3 大于 2 个元素(1 和 2)且小于6 个元素(4、5、6、7、8 和 9)。
提示:使用递归来实现此功能。
这是我解决问题的尝试:
lowerAndGreater :: Int -> [Int] -> String
lowerAndGreater n list = show(n) ++ " is greater than " ++ show(lesserThanN n list) ++ " elements and lower than " ++ show(greaterThanN n list) ++ " elements"
where
greaterThanN :: Int -> [Int] -> Int
greaterThanN greater l =
if null l
then greater
else if head l > n
then greaterThanN (greater + 1) (tail l)
else greaterThanN greater (tail l)
lesserThanN :: Int -> [Int] -> Int
lesserThanN lesser l =
if null l
then lesser
else if head l < n
then lesserThanN (lesser + 1) (tail l)
else lesserThanN lesser (tail l)
Run Code Online (Sandbox Code Playgroud)
不幸的是,执行结果不是我所期望的,例如
lowerAndGreater 3 [1 .. 9]
"3 is greater than 5 elements and lower than 9 elements"
Run Code Online (Sandbox Code Playgroud)
你能告诉我我的错误在哪里吗?
一次性枚举该列表可能会更好。我们可以使用返回 2 元组的函数来完成此操作:
import Control.Arrow (first, second)
lowerAndGreater :: Ord a => a -> [a] -> (Int, Int)
lowerAndGreater y = foldr go (0, 0)
where
go x
| x < y = first (+ 1)
| x > y = second (+ 1)
| otherwise = idRun Code Online (Sandbox Code Playgroud)
这给了我们:
ghci> lowerAndGreater 3 [1 .. 9]
(2,6)
Run Code Online (Sandbox Code Playgroud)