我一直在从Haskell书中做一些Haskell练习,其中一个任务是我过滤某个类型的值并将它们作为列表返回。
import Data.Time
data Item = DbString String
| DbNumber Integer
| DbDate UTCTime
deriving (Eq, Ord, Show)
database :: [Item]
database =
[
DbDate (UTCTime (fromGregorian 1911 5 1) (secondsToDiffTime 34123)),
DbNumber 9001,
DbString "Hello World!",
DbDate (UTCTime (fromGregorian 1921 5 1) (secondsToDiffTime 34123))
]
这是我给予的代码,也是我的第一个任务:
Write a function that filters for DbDate values and returns a list of the UTCTime values inside them.
该功能的模板是:
filterDate :: [Item] -> [UTCTime]
filterDate = undefined
我在这里使用的是折叠,因为这是关注的问题。
我查看了Hoogle上的Data.Time
模块并没有真正帮助,因为我无法理解如何与模块进行交互。也许我从错误的角度看待这个问题因为我不认为它与filter
功能有关,我不认为它与类型有关不是::
。
如何获取UTCTime值,以及如何过滤它们?
答案 0 :(得分:4)
$ sudo -u yarn jps
11388 CoarseGrainedExecutorBackend
1854 Jps
11396 CoarseGrainedExecutorBackend
,则返回DbDate
,否则返回<that value> : <output list>
。通过折叠输入,您可以生成滤波输出。在How would you define map and filter using foldr in Haskell?处有一个相关问题可能会更好地解释这一点。
这会分解为:
<output list>
(这可能是语法失败)。此函数从我们的filterFn :: Item -> [UTCTime] -> [UTCTime]
filterFn (DbDate x) xs = x:xs
filterFn _ xs = xs
和模式匹配中取出一个项目。
[Item]
,则DbDate x
为x
,我们会将其附加到输入列表中。然后我们可以折叠:
UTCTime
这会让你得到答案吗?
答案 1 :(得分:0)
项目被定义为联合类型,这意味着它可以是DbString
,DbNumber
或DbDate
。
data Item = DbString String
| DbNumber Integer
| DbDate UTCTime
deriving (Eq, Ord, Show)
您可以使用pattern matching仅获取您感兴趣的值。您需要匹配某个项目,检查它是否为DbDate
,如果是这样,则提取{{1它持有的实例。
你说你想要使用fold,所以你需要一个累加器,你可以把你想要保留的值和一个函数填充它。
UTCTime
在上面的代码中,您有filterDate items = foldl accumulate [] items
where extractTime item = case item of DbDate time -> [time]
_ -> []
accumulate item accumulator = accumulator ++ (extractTime item)
该模式匹配项目,并返回包含时间的列表或返回空列表。 extractTime
函数只是将前面步骤中的值(它们存储在accumulate
中)和将accumulator
应用于当前项目的值组合在一起。