3
\$\begingroup\$

I am following CIS 194: Introduction to Haskell (Spring 2013) online to teach myself Haskell. Following is my response to first exercise of Homework 3. Since I don't have anyone to show my code, I am posting here to get a little feedback. In which ways I could improve this, without getting too much into advanced topics of Haskell?

{-
Exercise 1 Hopscotch
Your first task is to write a function

skips :: [a] -> [[a]]

The output of skips is a list of lists. The first list in the output should
be the same as the input list. The second list in the output should
contain every second element from the input list. . . and the nth list in
the output should contain every nth element from the input list.
For example:

skips "ABCD" == ["ABCD", "BD", "C", "D"]
skips "hello!" == ["hello!", "el!", "l!", "l", "o", "!"]
skips [1] == [[1]]
skips [True,False] == [[True,False], [False]]
skips [] == []

Note that the output should be the same length as the input.
-}

takeEvery :: Integer -> [a] -> [a]
takeEvery n xs =
    let zipped = zip [1..] xs
    in
        map (\x -> snd x ) . filter (\(x,_) -> x `mod` n == 0) $ zipped

skips :: [a] -> [[a]]
skips x = map (\(x,y) -> takeEvery x y) $ take (length x) (zip [1..] $ repeat x)
\$\endgroup\$
2
\$\begingroup\$

Give fewer names, such as by inlining what's only used once.

takeEvery :: Integer -> [a] -> [a]
takeEvery n = map snd . filter (\(x,_) -> x `mod` n == 0) . zip [1..]

skips :: [a] -> [[a]]
skips x = zipWith takeEvery [1..length x] $ repeat x
-- or skips x = map (`takeEvery` x) [1..length x]
\$\endgroup\$
1
  • \$\begingroup\$ Second solution looks very elegant +1 \$\endgroup\$
    – yasar
    Dec 10 '19 at 13:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.