我正在尝试添加一个定义为 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] 删除。
我来说两句