I am trying to invert two-elements lists in xs
. For example, invert [[1,2], [5,6,7], [10,20]]
will return [[2,1], [5,6,7], [20,10]]
. It doesn't invert [5,6,7]
because it is a 3 element list.
So I have written this so far:
invert :: [[a]] -> [[a]]
invert [[]] = [[]]
which is just the type declaration and an empty list case. I am new to Haskell so any suggestions on how to implement this problem would be helpful.
Here's one way to do this:
First we define a function to invert one list (if it has two elements; otherwise we return the list unchanged):
invertOne :: [a] -> [a]
invertOne [x, y] = [y, x]
invertOne xs = xs
Next we apply this function to all elements of an input list:
invert :: [[a]] -> [[a]]
invert xs = map invertOne xs
(Because that's exactly what map
does: it applies a function to all elements of a list and collects the results in another list.)
Your inert function just operations on each element individually, so you can express it as a map
:
invert xs = map go xs
where go = ...
Here go
just inverts a single list according to your rules, ie:
go [1,2] = [2,1]
go [4,5,6] = [4,5,6]
go [] = []
The definition of go
is pretty straight-forward:
go [a,b] = [b,a]
go xs = xs -- go of anything else is just itself
I would do this:
solution ([a,b]:xs) = [b,a] : solution xs
solution (x:xs) = x : solution xs
solution [] = []
This explicitly handles 2-element lists, leaving everything else alone.
Yes, you could do this with map
and an auxiliary function, but for a beginner, understanding the recursion behind it all may be valuable.
Note that your 'empty list case' is not empty. length [[]]
is 1.
Examine the following solution:
invert :: [[a]] -> [[a]]
invert = fmap conditionallyInvert
where
conditionallyInvert xs
| lengthOfTwo xs = reverse xs
| otherwise = xs
lengthOfTwo (_:_:_) = True
lengthOfTwo _ = False
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.