将元素添加到列表中,该列表是Haskell中类型的一部分

时间:2018-02-14 10:37:49

标签: haskell

我正在尝试添加一个类型为Transaction的新元素:

df=tibble(D1=c("YES","YES","YES","YES","NEVER"),D2=c("0-15 MINUTES","15-30 MINUTES","30- 60 MINUTES",NA,NA))
y=df$D2%>%str_replace("MINUTES","")%>%str_split("-")%>%unlist%>%na.omit%>%as.numeric%>%rollapply(FUN=mean,width=2,by=2)
df$D3=NA
df$D3[!is.na(df$D2)]=y
df$D3[is.na(df$D2)&df$D1=="NEVER"]=0

到以下类型的交易列表:

--Build type Transaction--
data Transaction = Transaction {
     start_state :: Int, 
     symbol :: Char, 
     end_state :: Int
} deriving Show

我试图实现以下功能:

--Build type Automaton--
data Automaton = Automaton {
     initial_state :: Int, 
     states :: Set.Set Int,
     transactions :: [Transaction],
     final_states :: Set.Set Int
} deriving Show 

但它返回以下错误:

--Add to the automaton a transaction 
insert_transaction :: Transaction -> Automaton -> Automaton
insert_transaction t a = a{transactions =  t : transactions }

我该如何实现? 谢谢!

1 个答案:

答案 0 :(得分:3)

transactions实际上并不是[Transaction]类型的值,它本身只是的记录字段访问者到类型{的字段 {1}}。即,这是一个功能。 GHCi本可以告诉你:

[Transaction]

因此,要访问这些事务,您需要明确来自的自动机,只需将其作为参数:

Main*> :t transactions
transactions :: Automaton -> Transactions

“本身”的含义:当您在普通的Haskell表达式中使用它时,没有像insertTransaction :: Transaction -> Automaton -> Automaton insertTransaction t a = a{ transactions = t : transactions a } 这样的特殊记录语法。在那里,a{transactions = ...}根本不是一个独立的实体。

您可以考虑以下几种方法:

  • 您可以在作为函数参数传递的记录的字段上“部分模式匹配”。

    transactions
  • insertTransaction t a{transactions = oldTransactions} = a{ transactions = t : oldTransactions } 扩展名可以将范围内的整个记录​​字段作为重载变量,就像您在包含这些字段的类的OO方法中一样。这允许您基本上写下您原来的内容:

    RecordWildCards

    我会推荐这个:{-# LANGUAGE RecordWildCards #-} insertTransaction t a{..} = a{ transactions = t : transactions } 是关于Haskell98记录类型限制的一个单一的黑客攻击。

  • Lenses是在Haskell中使用记录的现代方法。您可以通过稍微更改数据定义来最轻松地获取它们:

    RecordWildCards