递归地将整数与元组列表进行比较

时间:2012-10-01 13:43:54

标签: haskell recursion functional-programming

我正在编写一个Haskell函数,它递归地将整数i与元组列表进行比较。特别是,我想将整数i与列表中a中的每个(a,b)进行比较。如果i < a,则打印与b

对应的a

示例输入/输出

check 0.01 [(0.25, 'x'),(0.50,'y'),(0.75,'z')] = 'x'
check 0.4 [(0.25, 'x'),(0.50,'y'),(0.75,'z')] = 'y'
check 100 [(0.25, 'x'),(0.50,'y'),(0.75,'z')] = ' '

我写了一个关于如何处理它的伪代码但是我在将该伪代码转换为实际的Haskell函数时遇到了麻烦。以下是我到目前为止的情况:

check :: a -> [(a,b)] -> b
check i (a,b):xs = tuples d xs
    | if d <= a in (a,b) then = b //pseudocode
    | id d !<= a in (a,b) then recursively check the next tuple //pseudocode
    | otherwise ' ' // d is larger than all the a's of the tuple so return a space

我相信我正在思考它的方式是正确的,但我无法弄清楚如何遍历元组,比较整数i与元组的a s。有帮助吗?

1 个答案:

答案 0 :(得分:5)

需要注意的一些要点:

  • 您不能在同一个函数中将1' '之类的字符一起返回,因为它们的类型不同。你可以做的就是使用Maybe b返回Nothing,以便返回' 'Just 1,以便返回1

  • 由于您正在对类型a进行比较,因此您需要a属于Ord类型类。

所以修改后的程序变为

check :: (Ord a) => a -> [(a,b)] -> Maybe b
check d [] = Nothing
check d ((a,b):xs) | d <= a = Just b
                 | otherwise = check d xs

尝试使用ghci中的函数

> check 0.01 [(0.25, 1),(0.50,2),(0.75,3)]
Just 1
> check 0.4 [(0.25, 1),(0.50,2),(0.75,3)]
Just 2
> check 100 [(0.25, 1),(0.50,2),(0.75,3)]
Nothing

您还可以使用find中的Data.List来编写类型为

的函数
find :: (a -> Bool) -> [a] -> Maybe a

所以你的功能检查变为

check2 :: (Ord a) => a -> [(a,b)] -> Maybe b
check2 a = fmap snd . find ((> a) . fst)

(编辑)根据编辑的问题进行更改

check :: (Ord a) => a -> [(a,Char)] -> Char
check d [] = ' '
check d ((a,b):xs) | d <= a = b
                   | otherwise = check d xs

为了能够使用原始检查功能,您还可以使用fromMaybe中的Data.Maybe

newCheck ::  Ord a => a -> [(a, Char)] -> Char
newCheck d xs = fromMaybe ' ' $ check d xs