Ada*_*s07 5 lambda haskell functional-programming custom-data-type haskell-prelude
该示例取自"基于第一原理的Haskell编程".过滤函数的目标是除去"DbDate"类型之外的所有对象.
在somone的github上,我找到了一种用列表理解和模式匹配来过滤和类型的方法(1).现在我试图找到一种方法,用lambda函数(2)或"if then"函数的正常"case"重新定义这个过滤器.当我处理自定义数据类型时,我不知道如何正确检查函数的参数类型.
本书不会向读者介绍任何超级特定的库函数,只是标准的地图,折叠,过滤器以及您在前奏中找到的其他内容.
import Data.Time
data DatabaseItem = DbString String
| DbNumber Integer
| DbDate UTCTime
deriving (Eq, Ord, Show)
--List that needs to be filtered
theDatabase :: [DatabaseItem]
theDatabase =
[ DbDate (UTCTime (fromGregorian 1911 5 1)
(secondsToDiffTime 34123))
, DbNumber 9001
, DbString "Hello, world!"
, DbDate (UTCTime (fromGregorian 1921 5 1)
(secondsToDiffTime 34123))
]
--1 works fine, found on someone's git hub
filterDbDate :: [DatabaseItem] -> [UTCTime]
filterDbDate dbes = [x | (DbDate x) <- dbes]
--2 Looking for the eqivalents with lambda or "case" or "if then"
--pattern is not satisfactory
filterDbDate :: [DatabaseItem] -> [UTCTime]
filterDbDate dbes = filter (\(DbDate x) -> True) theDatabase
Run Code Online (Sandbox Code Playgroud)
小智 6
filter有类型,(a -> Bool) -> [a] -> [a]所以它无法更改列表的类型.
根据The Haskell 98 Report(第3.11节),你在github上发现的代码中使用的列表理解是:
filterDbDate2 :: [DatabaseItem] -> [UTCTime]
filterDbDate2 dbes = let extractTime (DbDate time) = [time]
extractTime _ = []
in concatMap extractTime theDatabase
Run Code Online (Sandbox Code Playgroud)
您可以重写extractTime使用case ... of:
filterDbDate3 :: [DatabaseItem] -> [UTCTime]
filterDbDate3 dbes = let extractTime item = case item of (DbDate time) -> [time]
_ -> []
in concatMap extractTime theDatabase
Run Code Online (Sandbox Code Playgroud)
并用lambda替换它:
filterDbDate4 :: [DatabaseItem] -> [UTCTime]
filterDbDate4 dbes = concatMap (\item ->
case item of
(DbDate time) -> [time]
_ -> [])
theDatabase
Run Code Online (Sandbox Code Playgroud)
但是imho你使用列表理解的原始解决方案看起来最好:
filterDbDate dbes = [x | (DbDate x) <- dbes]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
169 次 |
| 最近记录: |