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

问题描述 投票:0回答:6

我有一个获取列表的函数,并且必须返回其中的最小元素。

不幸的是,我不断遇到这个问题:

模式中的解析错误:最小

我可能做错了什么?

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
haskell recursion functional-programming pattern-matching parse-error
6个回答
11
投票

如果你想用最 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

不过我会让它更安全一点,因为如果列表为空,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

5
投票

使用最小

> minimum [2, 1, 3]
> 1

0
投票

您有一个要匹配的参数(

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


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)

0
投票

这个函数不应该接受列表,因为构造一个最小值是没有意义的。 0 表示空列表,当元素类型甚至可能允许负值时。为了具有完全的安全性和通用性,我们可以使用Min类型。首先,让我们制作一个示例输入值:

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

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

为了找到最小值,我们可以使用

sconcat
,它使用半群运算组合非空列表的所有元素,在这种情况下,这就像其他答案中显示的两个元素上的
min
函数。

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

要从

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


0
投票

在 GHC 9.6 中,添加了具有 Foldable1 类的 Data.Foldable1。 Foldable1 适用于所有非空结构。

该类有一个名为 minimum 的方法。

如果您使用旧版本的GHC,可以使用兼容包foldable1-classes-compat

© www.soinside.com 2019 - 2024. All rights reserved.