i need help with haskell i'm kinda confused.
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:
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. functors
and fmap
yet. Is there a way to edit the data directly like 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 :
mail1 = mail2
This will override the data in mail1 with the data from mail2. but i dont know how to code it in haskell with data type.
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. Each Contact
now has an Id
that we can use for getting to the right contact.
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. With m fn
we give them straight back as those don't need changing. But we're interested in contacts
so we pass it to this function updateContact id newfullName contacts
.
In updateContact
as inputs we have an Id
, FullName
and list of [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 () 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.
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
. If i
doesn't match id
then let's just leave those values alone and return them as they came.
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. :)
In Haskell lists are immutable which means every time you are given a list you must return a brand new list.
Check you contacts function. It should be
contacts (_,x) = x
MailAccount is a tuple, with first element as person and second as contact. So it cannot be ( , ,x) but should be (_,x).
The below updatecontact definition is working fine.
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. The error would have been understood easily without IO.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.