haskell中单词和值元组的较低值

时间:2014-07-25 21:33:27

标签: list haskell tuples

我正在尝试编写一个函数来选择具有较低值的元组,而元组由一个单词和一个值组成。

例如,对于像这样的元组列表:[(“CHURCH”,262),(“PENCIL”,311),(“FLOUR”,175),(“FOREST”,405),(“ CLASS“,105)],函数将返回(”CLASS“,105)

有人可以帮帮我吗? :)

非常感谢你!

3 个答案:

答案 0 :(得分:7)

您正在寻找minimumBy模块中的Data.List函数。它的类型是

minimumBy :: (a -> a -> Ordering) -> [a] -> a

在您的情况下,从comparing模块导入Data.Ord也很有用,该模块的类型为

comparing :: Ord a => (b -> a) -> b -> b -> Ordering

这可以让你给它一个“访问者”功能来创建一个订单。所以在这种情况下你可以做到

minimumSnd :: [(String, Int)] -> (String, Int)
minimumSnd = minimumBy (comparing ???)

我会让你填写???,此时应该很容易。您的访问者函数传递给comparing的类型是什么?


如果您想为此编写自定义函数,我建议使用fold模式。我们也可以借此机会通过返回Maybe类型使其更安全,更一般的是不要求它成为(String, Int)的列表:

minimumSnd :: (Ord b) => [(a, b)] -> Maybe (a, b)
minimumSnd = go Nothing
    where
        -- If the list is empty, just return our accumulator
        go acc [] = acc
        -- If we haven't found a minimum yet, grab the first element and use that
        go Nothing (x:xs) = go (Just x) xs
        -- If we have a minimum already, compare it to the next element
        go (Just currentMin) (x:xs)
            -- If it's <= our current min, use it
            | snd x <= snd currentMin = go (Just x) xs
            -- otherwise keep our current min and check the rest of the list
            | otherwise = go (Just currentMin) xs

答案 1 :(得分:1)

试试这个:

foldl1 (\acc x -> if snd x < snd acc then x else acc) <your list>

通过将列表的当前元素与下一个元素进行比较来折叠列表。如果下一个元素的第二个值小于当前元素的值,则它是累加器的新值。否则累加器保持不变。重复此过程,直到遍历整个列表。

答案 2 :(得分:1)

我是Haskell的初学者,但无论如何我想找到一个有效的解决方案并提出:

minTup' :: [(String, Int)] -> Maybe (String, Int) -> (String, Int)
minTup' [] (Just x)= x
minTup' (x:xs) Nothing = minTup' xs (Just x)
minTup' ((s,n):xs) (Just (s',n'))
    | n < n' = minTup' xs (Just (s,n))
    | otherwise = minTup' xs (Just (s',n'))


minTup :: [(String, Int)] -> (String, Int)
minTup [] = error "Need a list of (String,Int)"
minTup x  = minTup' x Nothing

main = do
    print $ minTup [("CHURCH",262),("PENCIL",311),("FLOUR",175),("FOREST",405),("CLASS",105)]
    print $ minTup [("CHURCH",262)]
    print $ minTup []