我正在尝试解决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
答案 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
,但这是适当的:您需要执行某事来处理没有最大值的情况,即使它只是返回一个默认值。