Getting odd and even position of items in a list - Haskell Mutual Recursion

I recently started to learn Haskell.

I found this code online that returns elements at all the even / odd list positions.

It uses mutual recursion, but I can’t understand how it works internally.

evens (x:xs) = x:odds xs
evens _ = []

odds (_:xs) = evens xs
odds _ = []

In particular, I don’t understand how the list progresses and evaluates all the elements. How it checks even positions even if there is no explicit index check

Can anyone give an idea?

+4
source share
3 answers

First, let's settle for something: we use 0-based indexes most of the time, right? So, if I asked you that the item in position 2 is in the list

a : b : c : d : []

c. : Haskell, : - , a : b , a b.

, a c , b d . even.

evens (x:xs) = x:odds xs
evens [] = []
  • :

  • , 0 (x) - , - , (x:xs) xs. , 2 (x:xs) 1 xs, 4 3 .. ..; ?

, , (x:xs) xs, odds .

+6

Debug.Trace, , . trace .

import Debug.Trace

evens (x:xs) = x : odds (trace (show (zip [0..] xs)) xs)
evens [] = []
odds (_:xs) = evens (trace (show (zip [0..] xs)) xs)
odds [] = []

main = print (evens "abcdefg")

[(0,'b'),(1,'c'),(2,'d'),(3,'e'),(4,'f'),(5,'g')]
[(0,'c'),(1,'d'),(2,'e'),(3,'f'),(4,'g')]
[(0,'d'),(1,'e'),(2,'f'),(3,'g')]
[(0,'e'),(1,'f'),(2,'g')]
[(0,'f'),(1,'g')]
[(0,'g')]
[]

, , "" . g, , , .

+1

evens . "abcde" -recall, String [Char], ['a', 'b', 'c', 'd', 'e'] 'a' : 'b' : 'c' : 'd' : 'e' : [].

:

evens "abcde"

evens, 'a' :

evens "abcde"
-------------

-- evens (x : xs) = x : odds xs
-- x = 'a'
-- xs = "bcde"
-- evens "abcde" = 'a' : odds "bcde"

'a' : odds "bcde"
-----------------

odds, 'b' :

'a' : odds "bcde"
      -----------

-- odds (_ : xs) = evens xs
-- xs = "cde"
-- odds "bcde" = evens "cde"

'a' : evens "cde"
      -----------

evens, 'c':

'a' : evens "cde"
      -----------

-- evens (x : xs) = x : odds xs
-- x = 'c'
-- xs = "de"
-- evens "cde" = 'c' : odds "de"

'a' : 'c' : odds "de"
      ---------------

odds, 'd':

'a' : 'c' : odds "de"
            ---------

-- odds (_ : xs) = evens xs
-- xs = "e"
-- odds "de" = evens "e"

'a' : 'c' : evens "e"
            ---------

evens, 'e':

'a' : 'c' : evens "e"
            ---------

-- evens (x : xs) = x : odds xs
-- x = 'e'
-- xs = "" = []
-- evens "e" = 'e' : odds ""

'a' : 'c' : 'e' : odds ""
            -------------

, , odds , [] _ : _, ( ) :

'a' : 'c' : 'e' : odds ""
                  -------

-- odds _ = []
-- odds "" = []

'a' : 'c' : 'e' : []
                  --

:

"ace"

"" : evens , odds ; odds , evens .

, , . ( 0), evens , odds , , , 1 , 0 :

zip [0..] "abcde" == [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e')]

'a' 'b' 'c' 'd' 'e'
 0   1   2   3   4
 |   |   |   |   |
 x   /   /   /   /
    /   /   /   /
   /   /   /   /
  /   /   /   /
 |   |   |   |
'b' 'c' 'd' 'e'
 0   1   2   3

zip [0..] "bcde" == [(0, 'b'), (1, 'c'), (2, 'd'), (3, 'e')]

, . :

evens xs = [x | (i, x) <- zip [0..] xs, even i]

odds xs = [x | (i, x) <- zip [0..] xs, odd i]

map filter:

evens = map snd . filter (even . fst) . zip [0..]

odds = map snd . filter (odd . fst) . zip [0..]

:

indices f = map snd . filter (f . fst) . zip [0..]

evens = indices even

odds = indices odd
0

Source: https://habr.com/ru/post/1696198/


All Articles