1

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

样本输入/输出

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与元组的as 进行比较。有什么帮助吗?

4

1 回答 1

5

需要注意的几点:

  • 你不能在同一个函数中同时返回一个数字1和一个字符,因为它们是不同的类型。' '你可以做的 insted 是用来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

您还可以使用findfromData.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

为了能够使用原始检查功能,您还可以使用fromMaybefromData.Maybe

newCheck ::  Ord a => a -> [(a, Char)] -> Char
newCheck d xs = fromMaybe ' ' $ check d xs
于 2012-10-01T13:56:36.550 回答