haskell中的minBound和MaxBound

时间:2017-02-26 18:59:27

标签: haskell

我有以下代码:

minmax1, minmax2, minmax3 :: [Int] -> (Int, Int)
minBound :: Int = -9223372036854775808
maxBound :: Int = 9223372036854775807
minmax1 arr = (minimum(arr), maximum(arr))

main = do
    let list1 = [1, 2, 3]
    let list2 = [1, 9, 3]
    let list3 = [3, 2, 1, 0]
    let list4 = [100]
    let list5 = []
    putStrLn $ show list1 ++ " -> " ++ show (minmax1 list1)
    putStrLn $ show list2 ++ " -> " ++ show (minmax1 list2)
    putStrLn $ show list3 ++ " -> " ++ show (minmax1 list3)
    putStrLn $ show list4 ++ " -> " ++ show (minmax1 list4)
    putStrLn $ show list5 ++ " -> " ++ show (minmax1 list5)

为了获得以下结果:

--   minmax1 [1,2,3] = (1,3)
--   minmax1 [1,9,3] = (1,9)
--   minmax1 [3,2,1,0] = (0,3)
--   minmax1 [100]   = (100,100)
--   minmax1 [] = (9223372036854775807,-9223372036854775808)

如果数组不为空,则很容易获得上面的值。但是当minmax1的输入是一个空数组时,我应该如何修改我的代码以获得上面的值呢?

3 个答案:

答案 0 :(得分:6)

您只需使用支票查看空清单:

minmax1 [] = (maxBound,minBound)
minmax1 arr = (minimum arr, maximum arr)

请注意,您无需自己定义minBoundmaxBound IntBounded的实例,因此具有此类界限:

Prelude> maxBound :: Int
9223372036854775807
Prelude> minBound :: Int
-9223372036854775808

答案 1 :(得分:3)

您可以在列表上进行模式匹配以查看它是否为空:

minmax1 :: [Int] -> (Int, Int)
minmax1 [] = (maxBound,minBound)
minmax1 arr = (minimum(arr), maximum(arr))

如果列表为空,将使用第一个等式。如果列表不为空,则忽略第一个等式,并使用第二个等式。

答案 2 :(得分:3)

作为替代方案,请考虑在列表上进行单一折叠而不是两次单独传递:

minmax1 = foldl' (\(a,b) c -> (min a c,max b c)) (maxBound,minBound)

作为一个例子使用:

> minmax1 [1,5893549,192,55] :: (Int,Int)
(1,5893549)