如何指定整数的最小范围

时间:2018-11-29 01:36:19

标签: haskell

我正在尝试解决the Haskell Book中的一个练习题,想知道应该在启动累加器中指定哪个最小值,以便可以使用文件夹找到DBNumber的最大值?

我无法指定minBound :: Integer,因为没有下限。我可能可以通过其他方式找到它,但想知道是否可以按以下方式使用文件夹?

import Data.Time

data DatabaseItem = DbString String | DbNumber Integer | DbDate UTCTime deriving (Eq, Ord, Show)

theDatabase :: [DatabaseItem]
theDatabase = [DbDate (UTCTime (fromGregorian 1911 5 1) 
                      (secondsToDiffTime 34123)),
               DbNumber -9001,
               DbString "Hello World",
               DbNumber -9002,
               DbNumber -109001,
               DbDate (UTCTime (fromGregorian 1921 5 1) (secondsToDiffTime 34123))]



maxDbNumber xs = foldr (\x y -> case x of 
                       DbNumber z | z > y -> z
                       otherwise -> y) (minBound::Integer) xs

1 个答案:

答案 0 :(得分:2)

并不十分优雅,但也不复杂-您可以将Nothing < Just x用作任何x的事实:

foldr (\x acc -> case x of
  DbNumber z -> Just z `max` acc
  _ -> acc) Nothing xs

可以通过定义一个提取数字(如果存在的话)的函数来将其写得更紧凑:

fromDbNumber :: DatabaseItem -> Maybe Integer
fromDbNumber (DbNumber z) = Just z
fromDbNumber _ = Nothing

maxDbNumber = foldr (max . fromDbNumber) Nothing

无点max . fromDbNumber的派生方式如下:

-- Original:
\x acc -> max (fromDbNumber x) acc

-- Eta-reduce:
\x -> max (fromDbNumber x)

-- Definition of ‘(.)’:
max . fromDbNumber

这当然会将结果更改为Maybe Integer,但这是适当的:您需要执行某事来处理没有最大值的情况,即使它只是返回一个默认值。