如何在不使用求和类型或副本的情况下创建异构数据类型的列表

Feenaboccles

用例:一个应用程序,可通过多个消息传递服务跟踪用户。有一个TwitterAccount数据类型,一个FacebookAccount数据类型等。可以很容易地将它们与Account求和类型结合在一起,但是层次结构的下一个层次导致了我的问题。

ATwitterAccount具有TwitterPosts的列表,aFacebookAccount具有FacebookPosts的列表,依此类推。

我的任务:我希望能够将所有帐户中最近10天的所有帖子放到一个列表中,并从中提取常见的时间和邮件正文字段以进行显示。

我没办法:我想,如果每个类的Post实现像一个类型类SimplePost暴露的功能messageBody,并messageTime认为这可能解决我的问题,但我不能创建列表[SimpleMessage]

我想保持aTwitterAccount 只能包含TwitterPosts的不变性,依此类推,因此我不能使用sum-types。我宁愿不创建对象的副本来执行此操作。

解决此问题的最佳,最干净,最Haskell式设计是什么?

更新这不是一个答案,但是作为recursion.ninja和Helder Pereira提供的四种解决方案的替代方案,我一直在考虑是否可以使用幻像类型满足我的不变量,Account并且这些Post类型可以容纳所有人所需的所有可能信息。提供者。但是,使用元组和笨拙的逻辑意味着它不能很好地扩展。也许这应该是一个不同的问题。

{-# LANGUAGE EmptyDataDecls #-}   

-- Some FSharpisms
(|>) = flip ($)
(<|) = ($)
infixr 0 <|


data Twitter
data Facebook
data LinkedIn

data Post a = Post{
    postBody :: String,
    postDate :: UTCTime,
    postForwarded :: Bool,
    postFriendMentions :: [UserName]
    } deriving (Show, Eq)

data Account a = Account {
    accountName  :: String,
    accountPosts :: [Post a]
    } deriving (Show, Eq)

data User = User {
    userName   :: String,
    userTweets :: Account Twitter,
    userFaces  :: Account Facebook,
    userLinks  :: Account LinkedIn
    }

prettyShowUtc :: UTCTime -> String
prettyShowUtc utc = ...

prettyShow :: Post a -> String
prettyShow p = prettyShowUtc (postDate p) ++ " : " ++ show (postBody p)

showOrderedOf2 :: ([Post a], [Post b]) -> [String]
showOrderedOf2 ([], []) = []
showOrderedOf2 (ls, []) = map prettyShow ls
showOrderedOf2 ([], rs) = map prettyShow rs
showOrderedOf2 ((l:ls), (r:rs)) = 
    if postDate l < postDate r
    then prettyShow l : showOrderedOf2 (ls, (r:rs))
    else prettyShow r : showOrderedOf2 ((l:ls), rs)

showOrderedOf3 :: ([Post a], [Post b], [Post c]) -> [String]
showOrderedOf3 ([], [], []) = []
showOrderedOf3 (as, [], []) = map postBody as
showOrderedOf3 ([], bs, []) = map postBody bs
showOrderedOf3 ([], [], cs) = map postBody cs
showOrderedOf3 (as, bs, []) = showOrderedOf2 (as, bs)
showOrderedOf3 ([], bs, cs) = showOrderedOf2 (bs, cs)
showOrderedOf3 (as, [], cs) = showOrderedOf2 (as, cs)
showOrderedOf3 ((a:as), (b:bs), (c:cs)) =
    let (adate, bdate, cdate) = (postDate a, postDate b, postDate c)
        minDate = minimum [adate, bdate, cdate]
    in
    if adate == minDate
    then prettyShow a : showOrderedOf3 (as, (b:bs), (c:cs))
    else (if bdate == minDate
         then prettyShow b : showOrderedOf3 ((a:as), bs, (c:cs))
         else prettyShow c : showOrderedOf3 ((a:as), (b:bs), cs))

createAndShowSample :: IO ()
createAndShowSample =
    let faceAc = Account {...} :: Account Facebook
        twitAc = Account {...} :: Account Twitter
        linkAc = Account {...} :: Account LinkedIn
    in 
    showOrderedOf3 (accountPosts faceAc, accountPosts twitAc, accountPosts linkAc)
        |> intercalate "\n"
        |> putStrLn
递归忍者

您应该抽象FaceBookAccount和的TwitterAccount实例SocialMediaAccount

Haskell代码:

import Control.Applicative ((<$>))
import Data.List
import Data.Ord
import Data.Time

data FaceBookAccount = FaceBookAccount [FaceBookPost]
data TwitterAccount  = TwitterAccount  [TwitterPost]
data FaceBookPost    = FaceBookPost String UTCTime
data TwitterPost     = TwitterPost  String UTCTime

data SocialMediaAccount 
   = SocialMediaAccount 
   { accountPosts :: [SocialMediaPost]
   }
data SocialMediaPost 
   = SocialMediaPost
   { postBody :: String
   , postTime :: UTCTime
   }

class SocialMedia a where
  simpleAccount  :: a -> SocialMediaAccount  

instance SocialMedia FaceBookAccount where
  simpleAccount (FaceBookAccount xs) = SocialMediaAccount $ f <$> xs
    where 
      f (FaceBookPost text time) = SocialMediaPost text time

instance SocialMedia TwitterAccount where
  simpleAccount (TwitterAccount xs) = SocialMediaAccount $ f <$> xs
    where 
      f (TwitterPost text time) = SocialMediaPost text time

getAllMessages :: (SocialMedia a, SocialMedia b) => a -> b -> [SocialMediaPost]
getAllMessages xs ys = sortBy (comparing postTime) 
                     $ extract xs
                    ++ extract ys
  where
    extract :: SocialMedia a => a -> [SocialMediaPost]
    extract = accountPosts . simpleAccount

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在没有数据类型的情况下从DataFrame打印字符串值

来自分类Dev

Matlab:如何在不扩展基础数据类型的情况下执行定点运算?

来自分类Dev

如何在不使用任何用户定义的数据类型的情况下,用C或C ++构建大小为n的全新数据类型?

来自分类Dev

如何在不使用auto的情况下声明std :: make_tuple结果的类型

来自分类Dev

如何在函数的参数中不使用类型的情况下指定函数的类型?

来自分类Dev

如何在不使用类型::feature的情况下使用水豚?

来自分类Dev

如何在不使用Blob的情况下向多部分请求添加内容类型

来自分类Dev

使用Laravel Migration,如何在不使用原始SQL查询的情况下更改列的数据类型并更新其现有数据以适应新的数据类型?

来自分类Dev

如何在不使用Freebase API的情况下访问包含的类型

来自分类Dev

如何在不删除依赖项的情况下更改数据类型

来自分类Dev

如何在不使用Python实例化的情况下获取类的类型?

来自分类Dev

如何在不使用Delphi约束的情况下确定泛型类型是否为nil?

来自分类Dev

如何在不使用python初始化的情况下获取类对象的属性类型

来自分类Dev

如何在不使用findall的情况下创建列表?序言

来自分类Dev

如何在不使用列名的情况下将列表追加到数据框?

来自分类Dev

Matlab:如何在不扩展基础数据类型的情况下执行定点算术?

来自分类Dev

如何在不使用任何用户定义的数据类型的情况下,在C或C ++中构建大小为n的全新数据类型?

来自分类Dev

如何在不使用单元格的情况下创建数据验证列表?

来自分类Dev

如何在嵌入符号的情况下解码数字数据类型?

来自分类Dev

如何在不使用instanceOf或getClass()的情况下知道类类型?

来自分类Dev

如何在不使用INDIRECT函数的情况下从表创建下拉列表

来自分类Dev

如何在不使用提交按钮的情况下从多个下拉列表中获取数据

来自分类Dev

abas-ERP:如何在不使用.make-command的情况下创建数据集

来自分类Dev

如何在不使用或getClass()实例的情况下检查对象的类型

来自分类Dev

如何在不使用XPath的情况下查找表类型元素的地址

来自分类Dev

如何在列数据类型为NON INTEGER的情况下添加NOT NULL约束(例如VARCHAR(50))

来自分类Dev

如何在不使用协议的情况下将jQuery验证用于输入类型的url?

来自分类Dev

如何在不丢失数据类型的情况下读取 xlsx 文件

来自分类Dev

如何在不丢失Mysql中的数据的情况下更改列数据类型

Related 相关文章

  1. 1

    如何在没有数据类型的情况下从DataFrame打印字符串值

  2. 2

    Matlab:如何在不扩展基础数据类型的情况下执行定点运算?

  3. 3

    如何在不使用任何用户定义的数据类型的情况下,用C或C ++构建大小为n的全新数据类型?

  4. 4

    如何在不使用auto的情况下声明std :: make_tuple结果的类型

  5. 5

    如何在函数的参数中不使用类型的情况下指定函数的类型?

  6. 6

    如何在不使用类型::feature的情况下使用水豚?

  7. 7

    如何在不使用Blob的情况下向多部分请求添加内容类型

  8. 8

    使用Laravel Migration,如何在不使用原始SQL查询的情况下更改列的数据类型并更新其现有数据以适应新的数据类型?

  9. 9

    如何在不使用Freebase API的情况下访问包含的类型

  10. 10

    如何在不删除依赖项的情况下更改数据类型

  11. 11

    如何在不使用Python实例化的情况下获取类的类型?

  12. 12

    如何在不使用Delphi约束的情况下确定泛型类型是否为nil?

  13. 13

    如何在不使用python初始化的情况下获取类对象的属性类型

  14. 14

    如何在不使用findall的情况下创建列表?序言

  15. 15

    如何在不使用列名的情况下将列表追加到数据框?

  16. 16

    Matlab:如何在不扩展基础数据类型的情况下执行定点算术?

  17. 17

    如何在不使用任何用户定义的数据类型的情况下,在C或C ++中构建大小为n的全新数据类型?

  18. 18

    如何在不使用单元格的情况下创建数据验证列表?

  19. 19

    如何在嵌入符号的情况下解码数字数据类型?

  20. 20

    如何在不使用instanceOf或getClass()的情况下知道类类型?

  21. 21

    如何在不使用INDIRECT函数的情况下从表创建下拉列表

  22. 22

    如何在不使用提交按钮的情况下从多个下拉列表中获取数据

  23. 23

    abas-ERP:如何在不使用.make-command的情况下创建数据集

  24. 24

    如何在不使用或getClass()实例的情况下检查对象的类型

  25. 25

    如何在不使用XPath的情况下查找表类型元素的地址

  26. 26

    如何在列数据类型为NON INTEGER的情况下添加NOT NULL约束(例如VARCHAR(50))

  27. 27

    如何在不使用协议的情况下将jQuery验证用于输入类型的url?

  28. 28

    如何在不丢失数据类型的情况下读取 xlsx 文件

  29. 29

    如何在不丢失Mysql中的数据的情况下更改列数据类型

热门标签

归档