I am a beginner. So, please correct me if this is wrong or sub-optimal.

internalSplit :: [a] -> Int -> [a] -> [[a]]
split :: [a] -> [[a]]

internalSplit (first:rest) count firstPart
    | count == 0 = [firstPart, (first:rest)]
    | otherwise  = internalSplit rest (count - 1) (firstPart ++ [first])

split myList =
    let listLength = length myList
    in
        if listLength `mod` 2 == 0 then
            internalSplit myList (listLength `div` 2) []
        else
            internalSplit myList ((listLength `div` 2) + 1) []

main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

Output

[[1,2,3],[5,6]]
[[1,2,3],[4,5,6]]

Edit:

Managed to use builtin functions and came up with this

internalSplit :: [a] -> Int -> [[a]]
split :: [a] -> [[a]]

internalSplit myList splitLength = [(take splitLength myList), (drop splitLength myList)]

split myList =
    let listLength = length myList
    in
        if listLength `mod` 2 == 0 then
            internalSplit myList (listLength `div` 2)
        else
            internalSplit myList ((listLength `div` 2) + 1)

main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

Output

[[1,2,3],[5,6]]
[[1,2,3],[4,5,6]]

Edit 1:

internalSplit :: [a] -> Int -> ([a], [a])
split :: [a] -> ([a], [a])

internalSplit myList splitLength = splitAt splitLength myList

split myList =
    let listLength = length myList
    in
        if listLength `mod` 2 == 0 then
            internalSplit myList (listLength `div` 2)
        else
            internalSplit myList ((listLength `div` 2) + 1)

main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

Output

([1,2,3],[5,6])
([1,2,3],[4,5,6])

Edit2

As suggested by Bogdon in the comments section, this can be greatly simplified to this

split :: [a] -> ([a], [a])
split myList = splitAt (((length myList) + 1) `div` 2) myList
main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

Output

([1,2,3],[5,6])
([1,2,3],[4,5,6])
Answer from thefourtheye on Stack Overflow
Top answer
1 of 1
11

I am a beginner. So, please correct me if this is wrong or sub-optimal.

internalSplit :: [a] -> Int -> [a] -> [[a]]
split :: [a] -> [[a]]

internalSplit (first:rest) count firstPart
    | count == 0 = [firstPart, (first:rest)]
    | otherwise  = internalSplit rest (count - 1) (firstPart ++ [first])

split myList =
    let listLength = length myList
    in
        if listLength `mod` 2 == 0 then
            internalSplit myList (listLength `div` 2) []
        else
            internalSplit myList ((listLength `div` 2) + 1) []

main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

Output

[[1,2,3],[5,6]]
[[1,2,3],[4,5,6]]

Edit:

Managed to use builtin functions and came up with this

internalSplit :: [a] -> Int -> [[a]]
split :: [a] -> [[a]]

internalSplit myList splitLength = [(take splitLength myList), (drop splitLength myList)]

split myList =
    let listLength = length myList
    in
        if listLength `mod` 2 == 0 then
            internalSplit myList (listLength `div` 2)
        else
            internalSplit myList ((listLength `div` 2) + 1)

main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

Output

[[1,2,3],[5,6]]
[[1,2,3],[4,5,6]]

Edit 1:

internalSplit :: [a] -> Int -> ([a], [a])
split :: [a] -> ([a], [a])

internalSplit myList splitLength = splitAt splitLength myList

split myList =
    let listLength = length myList
    in
        if listLength `mod` 2 == 0 then
            internalSplit myList (listLength `div` 2)
        else
            internalSplit myList ((listLength `div` 2) + 1)

main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

Output

([1,2,3],[5,6])
([1,2,3],[4,5,6])

Edit2

As suggested by Bogdon in the comments section, this can be greatly simplified to this

split :: [a] -> ([a], [a])
split myList = splitAt (((length myList) + 1) `div` 2) myList
main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

Output

([1,2,3],[5,6])
([1,2,3],[4,5,6])
🌐
Hackage
hackage.haskell.org › package › split-0.2.5 › docs › Data-List-Split.html
Data.List.Split
The Data.List.Split module contains a wide range of strategies for splitting lists with respect to some sort of delimiter, mostly implemented through a unified combinator interface. The goal is to be flexible yet simple. See below for usage, examples, and detailed documentation of all exported ...
Discussions

Split a list in with liquidhaskell
I would like to split a list into two pieces of equal or nearly equal length. I tried this but I get an error with the function splitTwo: {-@ halfIndex :: i : [a] -> {j : Int | j == div (len i) 2} @-} halfIndex :: [a] -> Int halfIndex [] = 0 halfIndex x = div (length x) 2 {-@ splitTwo :: j ... More on discourse.haskell.org
🌐 discourse.haskell.org
0
0
September 15, 2023
Split list into groups of n in Haskell - Code Review Stack Exchange
When tasked to create 3 elements ... source list, two elements will be in the last sublist of the result. The following function also includes trailers. mklsts n = takeWhile (not.null) . map (take n) . iterate (drop n) I use this as pairs with a 2 for n and no n parameter. Pairs rock. ... The match up of iterate and splitOn is one made ... More on codereview.stackexchange.com
🌐 codereview.stackexchange.com
[Haskell] Recursion in a List Split Function
Break up the line into its important parts. In a hypothetical call to the function... splitList (x:y:xys) splitList takes a list with two elements (x and y) and possibly more (xys). (xs, ys) = splitList xys The possible rest of the list (xys) is then split recursively into two lists (xs and ys). (x:xs, y:ys) The return value is a pair of lists, the first element of the original list (x) at the front of the first half of the split list (xs), and the second element (y) at the front of the second half (ys). More on reddit.com
🌐 r/learnprogramming
5
6
September 28, 2012
Splitting a list into two parts
I want split a list into two list S and E and I want to find all possibilities to do so. So my idea was to map a filter function over a calculated power set, but I have quiet a few beginners trouble with this: -- power… More on discourse.haskell.org
🌐 discourse.haskell.org
0
0
March 27, 2021
🌐
Reddit
reddit.com › r/haskell › trying to split a list
r/haskell on Reddit: trying to split a list
September 18, 2020 -

So I'm trying to split a list in half, biasing towards more than half if the list has an odd number of elements.

I want to simply say drop (floor ((length lst) / 2)) mylist but what I've encountered is a messy labyrinth of type casting because haskell apparently needs to have 100 different types of number and none of them are compatible.

now my code looks more like secondHalf lst = drop (toInteger (floor ((fromIntegral (length lst)) / 2))) (lst) but even that doesn't work because drop takes an Int and toInteger returns an Integer

I feel like I've gone in completely the wrong direction, what am I supposed to do?

🌐
Educative
educative.io › answers › how-to-split-a-list-in-even-and-odd-indexes-in-haskell
How to split a list in even and odd indexes in Haskell
The split function divides a list into two halves based on odd and even index positions. Line 2: split :: [Int] -> ([Int], [Int]) is the type annotation for our function called split.
🌐
Educative
educative.io › answers › how-to-split-a-list-at-position-n-in-haskell
How to split a list at position n in Haskell
Haskell is statically typed, and every function or variable has a type. In this case, splitAtN is a function that takes an integer (the position n) and a list of any type as its argument and returns a tuple (the resulting lists after the split).
🌐
Hackage
hackage.haskell.org › package › split
split: Combinator library for splitting lists. - Hackage - Haskell
A collection of various methods for splitting lists into parts, akin to the "split" function found in several mainstream languages.
🌐
Haskell Community
discourse.haskell.org › learn
Split a list in with liquidhaskell - Learn - Haskell Community
September 15, 2023 - I would like to split a list into two pieces of equal or nearly equal length. I tried this but I get an error with the function splitTwo: {-@ halfIndex :: i : [a] -> {j : Int | j == div (len i) 2} @-} halfIndex :: [a] -> Int halfIndex [] = 0 halfIndex x = div (length x) 2 {-@ splitTwo :: j : [a] -> {i : ([a], [a]) | (len (fst i)) + (len (snd i)) == len j} @-} splitTwo :: [a] -> ([a], [a]) splitTwo a = splitAt (halfIndex a) a I am only verifying that the length of the two pieces adds up to th...
🌐
Hackage
hackage.haskell.org › package › split-0.2.5 › docs › Data-List-Split-Internals.html
Data.List.Split.Internals
Make a strategy that splits a list into chunks that all start with the given subsequence (except possibly the first). Equivalent to dropInitBlank . keepDelimsL . onSublist. >>> split (startsWith "app") "applyapplicativeapplaudapproachapple" ["apply","applicative","applaud","approach","apple"]
Find elsewhere
🌐
HaskellWiki
wiki.haskell.org › Data.List.Split
Data.List.Split - Haskell « HaskellWiki
February 22, 2012 - chunk :: Int -> [a] -> [[a]] chunk n [] = [] chunk n xs = ys : chunk n zs where (ys,zs) = splitAt n xs ... -- Author: mm_freak irc.freenode.net #haskell chunk' :: Int -> [a] -> [[a]] chunk' n = takeWhile (not.null) . map (take n) .
🌐
HaskellWiki
haskell.org › haskellwiki › Data.List.Split
Data.List.Split - HaskellWiki
chunk :: Int -> [a] -> [[a]] chunk n [] = [] chunk n xs = ys : chunk n zs where (ys,zs) = splitAt n xs ... -- Author: mm_freak irc.freenode.net #haskell chunk' :: Int -> [a] -> [[a]] chunk' n = takeWhile (not.null) . map (take n) .
Top answer
1 of 2
13

There are Data.List.Split.chunksOf and Data.List.Grouping.splitEvery implementations of this routine in specialized packages (and a number included in other application packages: search by Int -> [a] -> [[a]] signature on Hayoo).

I think splitEvery implementation is pretty elegant:

splitEvery :: Int -> [a] -> [[a]]
splitEvery _ [] = []
splitEvery n xs = as : splitEvery n bs 
  where (as,bs) = splitAt n xs
2 of 2
1

The ready made function chunksOf works very well. When tasked to create 3 elements in sublists with 11 elements in the source list, two elements will be in the last sublist of the result. The following function also includes trailers.

mklsts n = takeWhile (not.null) . map (take n) . iterate (drop n)

I use this as pairs with a 2 for n and no n parameter. Pairs rock.

Edit/Add 4/12/2018

The match up of iterate and splitOn is one made in hell. In the questioner above, placing splitOn in a lambda may have compounded the problems. It is possible to make splitOn work with iterate but you have to ditch the fst of the tuple produced. That defeats the entire purpose. It is way cleaner and easier to use drop n with iterate. The results are the same. That's what the preceding function does. Otherwise, it's the same idea.

Here is a novel way of producing the identical results using tails imported from Data.List in a list comprehension. It picks up stragglers, too.

ts n ls = [take n l|l<-init$tails ls,odd (head l)]

The parameters are size-of-sublist and list

Edit 4/17/2018

Well, since I had some time at work a list comprehension version that does not use tails, a recursive version and a map version.

ttx s ls=[take s.drop x$ls|x<-[0,s..s*1000]]

Recursive

tkn n []=[];tkn n xs=[take n xs]++(tkn n $ drop n xs)

Map

tp n ls=takeWhile(not.null)$   map(take n.flip drop ls) [0,n..]

The list comprehension is virtually infinite. Change [0,s..s*200] to [0,s..] for true infinity. The recursive is, of course, inherently infinite and the map function uses a big takeWhile (not.null) to end itself.

🌐
GitHub
github.com › byorgey › split
GitHub - byorgey/split: Standard Haskell list splitting library.
Data.List.Split provides a wide range of strategies and a unified combinator framework for splitting lists with respect to some sort of delimiter. See https://hackage.haskell.org/package/split/docs/Data-List-Split.html to get started using it.
Starred by 57 users
Forked by 11 users
Languages   Haskell 100.0% | Haskell 100.0%
🌐
Reddit
reddit.com › r/learnprogramming › [haskell] recursion in a list split function
r/learnprogramming on Reddit: [Haskell] Recursion in a List Split Function
September 28, 2012 -

I recently started learning Haskell and programming in general and have been doing a little bit of recursion. I have a pretty fair grasp of it but some functions still have me stumped. For instance, there's this function to split a list into two but I'm not completely sure how it works:

splitList [] = ([],[])
splitList [x] = ([x],[])
splitList (x:y:xys) = (x:xs, y:ys) where (xs, ys) = splitList xys

I would be extremely grateful if someone could provide me step-by-step guide on how this function works. I understand all of the pattern matching, it's just the last line that confuses me.

🌐
Google Groups
groups.google.com › g › comp.lang.haskell › c › 59Iejk26hKY
how to split at half a list?
No problem, we're here to help, ... what Haskell offers while you're still learning. I still try to make time to re-read the Prelude occasionally. ... Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message ... * ZeD wrote: > half :: [a] -> ([a],[a]) > half list = > splitAt (fromEnum ...
🌐
Haskell Community
discourse.haskell.org › learn
Splitting a list into two parts - Learn - Haskell Community
March 27, 2021 - [[a]] powerset [] = [[]] powerset (x:xs) = map (x:) (powerset xs) ++ powerset xs findSAndE ts = do ps
🌐
Hackage
hackage.haskell.org › package › split-0.1.3 › docs › src › Data-List-Split-Internals.html
Data/List/Split/Internals.hs
type SplitList a = [Chunk a] -- ... -> b -> b) -> [a] build g = g (:) [] -- * Implementation -- | Given a delimiter to use, split a list into an internal -- representation with chunks tagged as delimiters or text....
🌐
Hoogle
hoogle.haskell.org
splitOn - Hoogle - Haskell
Split a list into sublists delimited by the given element.