我正在编写一个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。有帮助吗?
答案 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