【问题标题】:Recursively compare an integer to a list of tuples递归地将整数与元组列表进行比较
【发布时间】:2012-10-01 23:00:04
【问题描述】:

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

示例输入/输出

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

【问题讨论】:

    标签: haskell recursion functional-programming


    【解决方案1】:

    需要注意的几点:

    • 您不能在同一个函数中同时返回像1 这样的数字和像' ' 这样的字符,因为它们属于不同的类型。你可以做的是使用Maybe b在你想要返回' '的地方返回Nothing,在你想要返回1的地方使用Just 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
    

    您也可以使用Data.List 中的find 来编写具有类型的函数

    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 from Data.Maybe

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

    【讨论】:

    • 好吧,这是有道理的。既然您指出它们不返回相同的类型,那么如果它们都返回 Char,是否仍然可以这样做。我编辑了示例输出以反映该想法
    • @NuNu 给定任何固定类型,您可以将此解决方案与fromMaybe defaultValue 结合使用以获得所需的结果。函数fromMaybe 可从Data.Maybe 获得。
    • @NuNu 我添加了你想要的。
    • @Satvik 谢谢我现在看到了不同之处。感谢您的解释
    • 很好的解释。更简洁:check d = maybe ' ' snd . find ((d &lt;=) . fst)
    猜你喜欢
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    相关资源
    最近更新 更多