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

埃琳娜

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

--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 }

但它返回以下错误:

automaton.hs:25:48: error:
    • Couldn't match expected type ‘[Transaction]’
                  with actual type ‘Automaton -> [Transaction]’
    • Probable cause: ‘transactions’ is applied to too few arguments
      In the second argument of ‘(:)’, namely ‘transactions’
      In the ‘transactions’ field of a record
      In the expression: a {transactions = t : transactions}
   |
25 | insert_transaction t a = a{transactions =  t : transactions }
   |                                                ^^^^^^^^^^^^

我该如何实施?谢谢!

左转

transactions是不是真的类型的值[Transaction],它是通过自身只有一个记录字段访问一个字段类型[Transaction]即,它是一个函数。GHCi 可以告诉你:

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

因此,要访问这些交易,您需要通过将其作为参数来明确说明来自 的自动机

insertTransaction :: Transaction -> Automaton -> Automaton
insertTransaction t a = a{ transactions =  t : transactions a }

“本身”的意思:当你在没有特殊记录语法的普通 Haskell 表达式中使用它时,如a{transactions = ...}. 在那里,它transactions根本不是一个真正的独立实体。


您可以考虑以下几种替代方案:

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

    insertTransaction t a{transactions = oldTransactions}
            = a{ transactions =  t : oldTransactions }
    
  • RecordWildCards扩展可以在范围上把整个记录的字段重载变量,有点像,就好像你在包含这些领域的类的面向对象的方法。这允许您基本上编写您最初拥有的内容:

    {-# LANGUAGE RecordWildCards #-}
    insertTransaction t a{..} = a{ transactions =  t : transactions }        
    

    不会推荐这个:RecordWildCards是围绕 Haskell98' 记录类型的限制的一种单一的黑客攻击。

  • 镜头是在 Haskell 中使用记录的现代和相应的方式。您可以通过稍微更改数据定义来最轻松地获得它们:

    {-# LANGUAGE TemplateHaskell #-}
    import Control.Lens
    data Automaton = Automaton {
       _initialState :: Int
     , _states :: Set.Set Int
     , _transactions :: [Transaction]
     , _finalStates :: Set.Set Int
     } deriving (Show)
    makeLenses ''Automaton  -- Generates `transactions` etc. not as plain accessor
                            -- functions, but as “optics” which can both get
                            -- and set field values.
    
    insertTransaction :: Transaction -> Automaton -> Automaton
    insertTransaction t = transactions %~ (t:)
    

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

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

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章