[英]Editing data type in Haskell
i need help with haskell i'm kinda confused. 我需要Haskell的帮助,我有点困惑。
I have custom types/Data like this: 我有这样的自定义类型/数据:
type Name = String
type LastName = String
type Mail = String
type FullName = (LastName, Name)
data Person = Person Mail FullName deriving (Show, Read)
type Contact = (FullName,Mail)
type MailAccount = (Person,[Contact])
Let's assume that mail account is stored in a data_base , what i want from now is update the list of contact and i don't know how to do it using this signature: 假设邮件帐户存储在一个data_base中,我现在要更新联系人列表,而我不知道如何使用此签名来做到这一点:
updateContact :: Mail -> LastName -> Name ->MailAccount -> IO MailAccount
I tried with this : 我尝试了这个:
updateContact l n m macc = do
x <- createPerson l n m
return $ mailAccountUpdate macc x
I created these three function: 我创建了以下三个功能:
--return my list of contacts
contacts:: MailAccount->[Contact]
contacts (_,_,con) = con
createPerson l n m = do
return (Person m (l,n))
mailAccountUpdate acc x = do
return (x:contact acc)
$ mailAccountUpdate macc x
retruns a list and not an IO MailAccount. $ mailAccountUpdate macc x
重新运行列表,而不是IO MailAccount。 functors
and fmap
yet. functors
和fmap
。 Is there a way to edit the data directly like OOP ex : MailAccount.contact()
? 有没有办法像OOP
ex : MailAccount.contact()
这样直接编辑数据? if not how can i create a function that can do the work. 如果没有,我怎么能创建一个可以完成这项工作的功能。
Is there a way to have for example two mailAccount with the same type and code it to do the equivalent of this in the ghci terminal : 有没有办法让例如两个具有相同类型的mailAccount并对其进行编码以在ghci终端中做到这一点:
mail1 = mail2
This will override the data in mail1 with the data from mail2. 这将用mail2中的数据覆盖mail1中的数据。 but i dont know how to code it in haskell with data type.
但是我不知道如何用数据类型在haskell中编码。
Thank you everyone in advance for helping me. 预先感谢大家对我的帮助。
There is a neater version of this but I'm doing like this so it can be more understanding: 有一个更整洁的版本,但是我这样做是为了让它更加理解:
type Name = String
type LastName = String
type Mail = String
type Id = Int
type FullName = (LastName, Name)
type Contact = (Id, FullName)
data Person =
Person Mail FullName [Contact]
deriving (Show, Read)
updatePersonContact :: Person -> FullName -> Id -> Person
updatePersonContact (Person m fn contacts) newfullName id =
Person m fn (updateContact id newfullName contacts)
updateContact :: Id -> FullName -> [Contact] -> [Contact]
updateContact id newfullName contacts =
map (\(i, fn) ->
if i == id
then (i, newfullName)
else (i, fn)) contacts
person1 :: Person
person1 = Person "email@me.com"("last","first")
[(1,("last1","first1")), (2,("last2","first2"))]
then using it you would: 然后使用它,您将:
> updatePersonContact person1 ("NEW","NEWW") 2
-- Person "email@me.com" ("last","first") [(1,("last1","first1")),(2,("NEW","NEWW"))]
We've update Person
to have a list of [Contact]
so now contacts are attached to a person. 我们更新了
Person
来拥有[Contact]
的列表,因此现在联系人已附加到人员上。 Each Contact
now has an Id
that we can use for getting to the right contact. 现在,每个
Contact
都有一个Id
,我们可以使用该Id
来找到正确的联系人。
You can deconstruct your types in the input like so updatePersonContact (Person m fn contacts)
so now we can use all the bits we need to reconstruct our person. 您可以在输入中解构您的类型,例如
updatePersonContact (Person m fn contacts)
因此现在我们可以使用重构人所需的所有位。 With m fn
we give them straight back as those don't need changing. 通过
m fn
我们可以直接将其退回,因为这些不需要更改。 But we're interested in contacts
so we pass it to this function updateContact id newfullName contacts
. 但是我们对
contacts
感兴趣,因此我们将其传递给此函数updateContact id newfullName contacts
。
In updateContact
as inputs we have an Id
, FullName
and list of [Contact]
. 在
updateContact
作为输入中,我们有一个Id
, FullName
和[Contact]
列表。 the way to loop over a list is to use map
so here we are using map to go through our list of contacts one by one. 遍历列表的方法是使用
map
因此在这里我们使用地图来逐一浏览我们的联系人列表。 map () contacts
the ()
needs to be a function from a -> b
and our a
when it loops the first time is (1,("last1","first1")
so as you can see it has 2 values which we deal with by having \\(i, fn) ->
. So i == 1
and fn == ("last1","first1")
. These would update on every iteration of the list like any loop. ()
必须是(1,("last1","first1")
a -> b
的函数,并且我们的a
第一次循环时是(1,("last1","first1")
因此您可以看到它具有2个值,我们通过\\(i, fn) ->
。 i == 1
和fn == ("last1","first1")
。它们会像任何循环一样在列表的每次迭代中更新。
The next part we check if i == id
and if it does then that's the contact we want to update so we return (i, newfullName)
which is our new full name originally passed into updatePersonContact
. 下一部分我们检查
i == id
,如果是,那么这就是我们要更新的联系人,因此我们返回(i, newfullName)
这是我们最初传递给updatePersonContact
新全名。 If i
doesn't match id
then let's just leave those values alone and return them as they came. 如果
i
与id
不匹配,那么我们就不理会这些值,并在它们出现时返回它们。
map
is a functor so as you might see it's not that bad you might need to do a bit more reading on it to get a better understanding. map
是一个函子,因此您可能会发现它并不坏,您可能需要对其进行更多阅读才能更好地理解。 :) :)
In Haskell lists are immutable which means every time you are given a list you must return a brand new list. 在Haskell中,列表是不可变的,这意味着每次给您列表时,您都必须返回一个全新的列表。
Check you contacts function. 检查您的联系人功能。 It should be
它应该是
contacts (_,x) = x
MailAccount is a tuple, with first element as person and second as contact. MailAccount是一个元组,第一个元素是person,第二个元素是contact。 So it cannot be ( , ,x) but should be (_,x).
因此它不能是( ,, x),而应该是(_,x)。
The below updatecontact definition is working fine. 下面的updatecontact定义工作正常。
updateContact l n m macc = let myP = Person l (n,m)
newMacc = (myP,((n,m),l):contacts macc)
in return newMacc
I agree with others that there is no need for using IO in definition. 我同意其他人的观点,即无需在定义中使用IO。 The error would have been understood easily without IO.
没有IO,该错误将很容易理解。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.