Haskell - 在列表中查找最小元素

时间:2017-03-01 11:09:06

标签: haskell recursion functional-programming pattern-matching parse-error

我有一个获取List的函数,必须返回它的最小元素。

不幸的是我一直在遇到这个问题:

  

模式中的解析错误:minim

我做错了什么?

minim :: [Int] -> Int
minim []       = 0
minim [x]      = x
minim x:xs     = min x (minim xs)

min :: Int -> Int -> Int
min a b
    | a > b  = b
    | a < b  = a

4 个答案:

答案 0 :(得分:5)

如果你想以最大的Haskell方式解决它。我会这样解决它:

-- Does not work for empty lists (so maybe needs to be wrapped in some logic)
foldr1 min [-3,1,2,3]
-- Works for empty but needs a "default value" (in this case 0)
foldr min 0 [-3,1,2,3]

如果您想通过自己实施来学习,那么这对我有用

minim :: [Int] -> Int
minim []       = 0
minim [x]      = x
minim (x:xs)   = min x (minim xs)

min :: Int -> Int -> Int
min a b
    | a > b  = b
    | a < b  = a
    | a == b = a

但是我会让它更安全,因为如果它是空的,那么列表中的最小int是0吗?我认为你应该使用Nothing作为结果。

import Data.Maybe

import Prelude hiding (min)

main = print $  minim [1,3,4, 6,6,-9]

minim :: [Int] -> Maybe Int
minim []       = Nothing
minim [x]      = Just x
minim (x:xs)   = min x <$> minim xs

min :: Int -> Int -> Int
min a b
    | a > b  = b
    | a < b  = a
    | a == b = a

答案 1 :(得分:0)

您有一个要匹配的参数(Int的列表)。如果要匹配该列表的某些部分,则需要将这些部分放在括号中,以显示编译器是否匹配一件事。因此,最后一个模式应为(x:xs)

答案 2 :(得分:0)

这是另一种实现您所要求的内容的方法,而无需使用诸如min之类的辅助功能

minElem::[Int]->Int
minElem [] = 0
minElem [x] = x
minElem (x:y:xs) 
 |x > y = minElem (y:xs)
 |x < y = minElem (x:xs)
 |x == y = minElem (x:xs)

答案 3 :(得分:0)

这个函数不应该使用列表,因为想象出最少的例如0 表示空列表,当元素类型甚至可能允许负值时。为了完全安全和通用,我们可以使用 Min type。首先,让我们做一个示例输入值:

exampleList = 1 :| [2, 3, 4]

:| 是非空列表的构造函数,更适合。

要找到最小值,我们可以使用 sconcat,它使用半群运算组合非空列表的所有元素,在这种情况下,这类似于对两个元素的 min 函数显示在其他答案中。

> sconcat $ fmap Min exampleList
Min {getMin = 1}

要从 Min 中提取数字,您可以使用 getMin