I have a function like the one provided below:
zip :: [a] -> [b] -> Maybe [(a,b)]
zip (headX:tailX) (headY:tailY) = (headX,headY):zip tailX tailY
zip _ _ = Nothing
Now
zip tailX tailY
Will return a type of Maybe list, and I am trying to prepend (headX,headY) to it using the : operator. Is there an easy way to do this? If I try to prepend it directly the compiler gives me errors because : operator only works on lists.
CodePudding user response:
One way would be to use fmap
to convert your prepending-to-a-list operation to a prepending-to-every-list-in-a-container-of-lists operation.
zip (headX:tailX) (headY:tailY) = fmap ((headX,headY):) (zip tailX tailY)
Sometimes it's more clear to use the infix version of fmap
.
zip (headX:tailX) (headY:tailY) = ((headX,headY):) <$> zip tailX tailY
I don't have a strong preference in this case; let your heart guide you.
CodePudding user response:
Maybe []
is not []
. You cannot use :
directly.
But you can define a function to do it for you, using pattern matching to get to the list contained within (if there is a list).
mycons :: a -> Maybe [a] -> Maybe [a]
mycons _ Nothing = Nothing
mycons v (Just lst) = Just (v:lst)
Now:
mycons 1 $ mycons 2 $ mycons 3 $ Just []
-- Just [1,2,3]
mycons 1 $ mycons 2 $ mycons 3 $ Nothing
-- Nothing