Related
I am running into a wall when I'm trying to calculate % growth from a list of integers to a list of floats. I am new to Haskell with very little experience and not sure where or what to search for my problem thus I came here. :)
function :: [Ints] -> [Floats]
I have a list.
nums = [4561,3241,2345,3455,4567]
I need to iterate through the list and calculate the % percentage growth from nums[4] to nums[0]
and then output a list of floats. But I am not sure whether to use a map function or some other method to solve this. I need some way to retrieve two numbers from the list i.e. nums[4] and nums[3] and calculate the % growth.
I'm not sure what you need but if it's the growth from (n-1)th to the nth element you can do it like this:
growth :: [Int] -> [Float]
growths xs =
zipWith (\n n' -> fromIntegral (n'-n) / fromIntegral n * 100) xs (tail xs)
yielding
> growths [4561,3241,2345,3455,4567]
[-28.941021,-27.645788,47.334755,32.185238]
-- this one makes it a bit more obvious what is happening
> growths [1,2,3,4,5]
[100.0,50.0,33.333336,25.0]
I probably got the formula wrong and you want some other formula but the idea should be clear as long as you want to compare consecutive numbers.
The trick zipWith f xs (tail xs) is often useful to work with consecutive elements in a list. Here the first argument to f is the (n-1)th and the second is the nth element in the list.
if you need from n to n-1th (as you kind of seem to imply) just flip the arguments:
growths xs =
zipWith (\n' n -> fromIntegral (n'-n) / fromIntegral n * 100) xs (tail xs)
> growths [4561,3241,2345,3455,4567]
[40.72817,38.208954,-32.12735,-24.348589]
> growths [1,2,3,4,5]
[-50.0,-33.333336,-25.0,-20.0]
I have a simple function (used for some problems of project Euler, in fact). It turns a list of digits into a decimal number.
fromDigits :: [Int] -> Integer
fromDigits [x] = toInteger x
fromDigits (x:xs) = (toInteger x) * 10 ^ length xs + fromDigits xs
I realized that the type [Int] is not ideal. fromDigits should be able to take other inputs like e.g. sequences, maybe even foldables ...
My first idea was to replace the above code with sort of a "fold with state". What is the correct (= minimal) Haskell-category for the above function?
First, folding is already about carrying some state around. Foldable is precisely what you're looking for, there is no need for State or other monads.
Second, it'd be more natural to have the base case defined on empty lists and then the case for non-empty lists. The way it is now, the function is undefined on empty lists (while it'd be perfectly valid). And notice that [x] is just a shorthand for x : [].
In the current form the function would be almost expressible using foldr. However within foldl the list or its parts aren't available, so you can't compute length xs. (Computing length xs at every step also makes the whole function unnecessarily O(n^2).) But this can be easily avoided, if you re-thing the procedure to consume the list the other way around. The new structure of the function could look like this:
fromDigits' :: [Int] -> Integer
fromDigits' = f 0
where
f s [] = s
f s (x:xs) = f (s + ...) xs
After that, try using foldl to express f and finally replace it with Foldable.foldl.
You should avoid the use of length and write your function using foldl (or foldl'):
fromDigits :: [Int] -> Integer
fromDigits ds = foldl (\s d -> s*10 + (fromIntegral d)) 0 ds
From this a generalization to any Foldable should be clear.
A better way to solve this is to build up a list of your powers of 10. This is quite simple using iterate:
powersOf :: Num a => a -> [a]
powersOf n = iterate (*n) 1
Then you just need to multiply these powers of 10 by their respective values in the list of digits. This is easily accomplished with zipWith (*), but you have to make sure it's in the right order first. This basically just means that you should re-order your digits so that they're in descending order of magnitude instead of ascending:
zipWith (*) (powersOf 10) $ reverse xs
But we want it to return an Integer, not Int, so let's through a map fromIntegral in there
zipWith (*) (powersOf 10) $ map fromIntegral $ reverse xs
And all that's left is to sum them up
fromDigits :: [Int] -> Integer
fromDigits xs = sum $ zipWith (*) (powersOf 10) $ map fromIntegral $ reverse xs
Or for the point-free fans
fromDigits = sum . zipWith (*) (powersOf 10) . map fromIntegral . reverse
Now, you can also use a fold, which is basically just a pure for loop where the function is your loop body, the initial value is, well, the initial state, and the list you provide it is the values you're looping over. In this case, your state is a sum and what power you're on. We could make our own data type to represent this, or we could just use a tuple with the first element being the current total and the second element being the current power:
fromDigits xs = fst $ foldr go (0, 1) xs
where
go digit (s, power) = (s + digit * power, power * 10)
This is roughly equivalent to the Python code
def fromDigits(digits):
def go(digit, acc):
s, power = acc
return (s + digit * power, power * 10)
state = (0, 1)
for digit in digits:
state = go(digit, state)
return state[0]
Such a simple function can carry all its state in its bare arguments. Carry around an accumulator argument, and the operation becomes trivial.
fromDigits :: [Int] -> Integer
fromDigits xs = fromDigitsA xs 0 # 0 is the current accumulator value
fromDigitsA [] acc = acc
fromDigitsA (x:xs) acc = fromDigitsA xs (acc * 10 + toInteger x)
If you're really determined to use a right fold for this, you can combine calculating length xs with the calculation like this (taking the liberty of defining fromDigits [] = 0):
fromDigits xn = let (x, _) = fromDigits' xn in x where
fromDigits' [] = (0, 0)
fromDigits' (x:xn) = (toInteger x * 10 ^ l + y, l + 1) where
(y, l) = fromDigits' xn
Now it should be obvious that this is equivalent to
fromDigits xn = fst $ foldr (\ x (y, l) -> (toInteger x * 10^l + y, l + 1)) (0, 0) xn
The pattern of adding an extra component or result to your accumulator, and discarding it once the fold returns, is a very general one when you're re-writing recursive functions using folds.
Having said that, a foldr with a function that is always strict in its second parameter is a really, really bad idea (excessive stack usage, maybe a stack overflow on long lists) and you really should write fromDigits as a foldl as some of the other answers have suggested.
If you want to "fold with state", probably Traversable is the abstraction you're looking for. One of the methods defined in Traversable class is
traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
Basically, traverse takes a "stateful function" of type a -> f b and applies it to every function in the container t a, resulting in a container f (t b). Here, f can be State, and you can use traverse with function of type Int -> State Integer (). It would build an useless data structure (list of units in your case), but you can just discard it. Here's a solution to your problem using Traversable:
import Control.Monad.State
import Data.Traversable
sumDigits :: Traversable t => t Int -> Integer
sumDigits cont = snd $ runState (traverse action cont) 0
where action x = modify ((+ (fromIntegral x)) . (* 10))
test1 = sumDigits [1, 4, 5, 6]
However, if you really don't like building discarded data structure, you can just use Foldable with somewhat tricky Monoid implementation: store not only computed result, but also 10^n, where n is count of digits converted to this value. This additional information gives you an ability to combine two values:
import Data.Foldable
import Data.Monoid
data Digits = Digits
{ value :: Integer
, power :: Integer
}
instance Monoid Digits where
mempty = Digits 0 1
(Digits d1 p1) `mappend` (Digits d2 p2) =
Digits (d1 * p2 + d2) (p1 * p2)
sumDigitsF :: Foldable f => f Int -> Integer
sumDigitsF cont = value $ foldMap (\x -> Digits (fromIntegral x) 10) cont
test2 = sumDigitsF [0, 4, 5, 0, 3]
I'd stick with first implementation. Although it builds unnecessary data structure, it's shorter and simpler to understand (as far as a reader understands Traversable).
Here is my problem: I need a Haskell function that computes an approximation of the sine of some number, using the associated Taylor serie ...
In C++ I wrote this:
double msin(double number, int counter = 0, double sum = 0)
{
// sin(x) = x - (x'3 / 3!) + (x'5 / 5!) - (x'7 / 7!) + (x'9 / 9!)
if (counter <= 20)
{
if (counter % 2 == 0)
sum += mpow(number, counter * 2 + 1) / mfak(counter * 2 + 1) ;
else
sum -= mpow(number, counter * 2 + 1) / mfak(counter * 2 + 1) ;
counter++;
sum = msin(number, counter, sum);
return sum;
}
return (sum* 180.0 / _PI);
}
Now I am trying to do it in Haskell and I have no idea how... For now I was trying something like this (it doesn't really work, but it is work in progress ;) ):
This works:
mfak number = if number < 2
then 1
else number *( mfak (number -1 ))
mpow number potenca = if potenca == 0
then 0
else if potenca == 1
then 1
else (number * (mpow number (potenca-1)))
This doesn't work:
msin :: Double -> Int -> Double -> Double
msin number counter sum = if counter <= 20
then if counter `mod` 2==0
then let sum = sum + (msin 1 (let counter = counter+1 in counter) sum) in sum
else let sum = sum + (msin 1 (let counter = counter+1 in counter) sum) in sum
else sum* 180.0 / 3.14
Updated....doesn't compile :/ "Couldn't match expected type Double' with actual type Int'"
msin :: Double -> Int -> Double -> Double
msin number counter sum = if counter <= 20
then if counter `mod` 2==0
then let sum' = sum + ((mpow number (counter*2+1))/(mfak counter*2+1)) in msin number (counter+1) sum'
else let sum' = sum - ((mpow number (counter*2+1))/(mfak counter*2+1)) in msin number (counter+1) sum'
else sum* 180.0 / 3.14
As you can see, the biggest problem is how to add something to "sum", increase "counter" and go in recursion again with these new values...
P.S. I am new to Haskell so try to explain your solution as much as you can please. I was reading some tutorials and that, but I can't find how to save the result of some expression into a value and then continue with other code after it... It just returns my value each time I try to do that, and I don't want that....
So thanks in advance for any help!
I would rework the algorithm a bit. First we can define the list of factorial inverses:
factorialInv :: [Double]
factorialInv = scanl (/) 1 [1..] -- 1/0! , 1/1! , 1/2! , 1/3! , ...
Then, we follow with the sine coefficients:
sineCoefficients :: [Double]
sineCoefficients = 0 : 1 : 0 : -1 : sineCoefficients
Then, given x, we multiply both the above lists with the powers of x, pointwise:
powerSeries :: [Double] -- ^ Coefficients
-> Double -- ^ Point x on which to compute the series
-> [Double] -- ^ Series terms
powerSeries cs x = zipWith3 (\a b c -> a * b * c) cs powers factorialInv
where powers = iterate (*x) 1 -- 1 , x , x^2 , x^3 , ...
Finally, we take the first 20 terms and sum them up.
sine :: Double -> Double
sine = sum . take 20 . powerSeries sineCoefficients
-- i.e., sine x = sum (take 20 (powerSeries sineCoefficients x))
The problem is expressions like let stevec = stevec+1 in stevec. Haskell is not an imperative language. This does not add one to stevec. Instead it defines stevec to be a number that is one more than itself. No such number exists, thus you will get an infinite loop or, if you are lucky, a crash.
Instead of
stevec++;
vsota = msin(stevilo, stevec, vsota);
You should use something like
let stevec' = stevec + 1
in msin stevilo stevec' vsota
or just
msin stevilo (stevec + 1) vsota
(There's also something here that I don't understand. You are going to need mpow and mfak. Where are they?)
As you can see the biggest problem is how to add something to "vsota",
In a functional language you would use recursion here - the variable vstota is implemented as a function parameter which is passed from call to call as a list is processed.
For example, to sum a list of numbers, we would write something like:
sum xs = go 0 xs
where go total [] = total
go total (x:xs) = go (total+x) xs
In an imperative language total would be a variable which gets updated. Here is is a function parameter which gets passed to the next recursive call to go.
In your case, I would first write a function which generates the terms of the power series:
sinusTerms n x = ... -- the first n terms of x - (x'3 / 3!) + (x'5 / 5!) - (x'7 / 7!) ...
and then use the sum function above:
sinus n x = sum (sinusTerms n x)
You may also use recursive lists definitions to get [x, x^3, x^5 ...] and [1, 1/3!, 1/5! ...] infinite sequences. When they are done, the rest is to multiply their items each by other and take the sum.
sinus count x = sum (take count $ zipWith (*) ifactorials xpowers)
where xpowers = x : map ((x*x)*) xpowers
ifactorials = 1 : zipWith (/) ifactorials [i*(i+1) | i <- [2, 4 .. ]]
Also, it would be better to define xpowers = iterate ((x*x)*) x, as it seems to be much more readable.
I’ve tried to follow your conventions as much as I could. For mfak and mpow, you should avoid using if as it is clearer to write them using pattern matching :
mfak :: Int -> Int
mfak 0 = 1
mfak 1 = 1
mfak n = n * mfak (n - 1)
mpow :: Double -> Int -> Double
mpow _ 0 = 1
mpow x 1 = x
mpow x p = x * mpow x (p - 1)
Before calculating the sinus, we create a list of coefficients [(sign, power, factorial)] :
x - (x^3 / 3!) + (x^5 / 5!) - (x^7 / 7!) + (x^9 / 9!)
→ [(1,1,1), (-1,3,6), (1,5,120), (-1,7,5040), (1,9,362880)]
The list is created infinite by a list comprehension. First we zip the lists [1,-1,1,-1,1,-1...] and [1,3,5,7,9,11...]. This gives us the list [(1,1), (-1,3), (1,5), (-1,7)...]. From this list, we create the final list [(1,1,1), (-1,3,6), (1,5,120), (-1,7,5040)...]:
sinCoeff :: [(Double, Int, Double)]
sinCoeff = [ (fromIntegral s, i, fromIntegral $ mfak i)
| (s, i) <- zip (cycle [1, -1]) [1,3..]]
(cycle repeats a list indefinitely, [1,3..] creates an infinite list which starts at 1 with a step of 2)
Finally, the msin function is near the definition. It also uses a list comprehension to achieve its goeal (note that I kept the * 180 / pi though I’m not sure it should be there. Haskell knows pi).
msin :: Int -> Double -> Double
msin n x = 180 * sum [ s * mpow x p / f | (s, p, f) <- take n sinCoeff] / pi
(take n sinCoeff returns the first n elements of a list)
You may try the previous code with the following :
main = do
print $ take 10 sinCoeff
print $ msin 5 0.5
print $ msin 10 0.5
The expression is of the form x*P(x2).
For maximal efficiency, the polynomial in x2 must be evaluated using the Horner rule rather than computing the powers of x2 separately.
The coefficient serie with the factorial values can be expressed recursively in Haskell, just like is commonly done for the Fibonacci series. Using the ghci interpreter as our testbed, we have:
$ ghci
GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help
λ>
λ>
λ> nextCoeffs d c = c : (nextCoeffs (d+1) ((-c)/(fromIntegral $ (2*d+2)*(2*d+3))))
λ>
λ> allCoeffs = nextCoeffs 0 1.0
λ>
where d is the depth inside the serie and c the current coefficient.
Sanity check: the coefficient at depth 3 must be the inverse of 7!
λ>
λ> 1.0 /(allCoeffs !! 3)
-5040.0
λ>
The Horner rule can be rendered in Haskell thru the foldr1 :: (a -> a -> a) -> [a] -> a library function.
As is customary in Haskell, I take the liberty to put the term count as the leftmost argument because it is the one most likely to be held constant. This is for currying (partial evaluation) purposes.
So we have:
λ> :{
|λ> msin count x = let { s = x*x ; cs = take count allCoeffs ;
|λ> stepFn c acc = acc*s + c ; }
|λ> in x * (foldr1 stepFn cs)
|λ> :}
Sanity checks, taking 20 terms:
λ>
λ> pi
3.141592653589793
λ>
λ> msin 20 (pi/6)
0.49999999999999994
λ>
λ> msin 20 (pi/2)
1.0
λ>
Side note 1: final multiplication by 180 / π is only of interest for inverse trigonometric functions.
Side note 2: in practice, to get a reasonably fast convergence, one should reduce the input variable x into the [-π,+π] interval using the periodicity of the sine function.
I'm trying to iterate a list and square all the number and add them together
sumsq (x:xs) =
let total = 0
loop length(x:xs) (x:xs) total
loop 0 (x:xs) = return ()
loop n (x:xs) total =
do
let
sq = ((x:xs)!!n)^2
total = total + sq
loop ((n-1) (x:xs) total)
But I'm getting parse error in loop. Where am I going wrong?
Also is there a better way to do this?
First of all - you miss spaces! It is significant.
Second, you forget in from let ... in. We could not use in in do-notation:
sumsq (x:xs) =
let total = 0 in
loop length(x:xs) (x:xs) total
Third, you do not use x and xs form (x:xs) :
sumsq xs =
let total = 0 in
loop (length xs) xs total
And we unite our length xsin one block. It is fourth.
Fifth, we have 3, not 2 arguments for loop:
loop 0 xs total = return total
Sixth, (!!) work from 0, but you use it from 1, so (xs !! (n -1)) is right
Seventh, you don't need to use monad, just recursion. So, get rid from return and do
Eighth. you have infinite recursive total = total + smth
Ninth, we can't use arguments as tuple, so, you final working result is :
sumsq xs =
let total = 0 in
loop (length xs) xs total
loop 0 xs total = total
loop n xs total = loop (n-1) xs total1
where
sq = (xs !! (n -1)) ^2
total1 = total + sq
UPDATED
If we are talking about complexity, it is not good - O(n^2) as it is mentioned in comments : for each element we seek this element.
We could simplify our loop function and get rid of n argument:
loop [] total = total
loop (x:xs) total = loop xs total1
where
sq = x ^ 2
total1 = total + sq
and our sumsq function we write:
sumsq xs = loop xs 0
P.S.
This is an implementation much easier function sumsq = sum. map (^ 2)
If I understood you correctly, you could simply do this with map and sum:
Prelude> let myFun = sum . map (^2)
Prelude> myFun [1, 2, 3]
14
Or with foldl1 and lambda:
Prelude> let myFun' = foldl1 (\s x -> s + x^2)
Prelude> myFun' [1, 2, 3, 4]
30
Surely something like this would be the usual approach?
sumSquared :: [Integer] -> Integer
sumSquared [] = 0
sumSquared (x:xs) = (x * x) + sumSquared xs
Or you could do this even more succinctly with foldr, or sum and map (like #soon's answer)
The do must be more indented than the word loop.
Apart from that, you don't need do (or return) at all here, unless you can answer the question which monad this is for?
There are more problems with your code. One of the most severe is this:
You don't seem to know what "pattern matching" is, nor what it is good for. You really want to learn about it, otherwise you can't write any good programs.
I'm really new to F#, and I need a bit of help with an F# problem.
I need to implement a cut function that splits a list in half so that the output would be...
cut [1;2;3;4;5;6];;
val it : int list * int list = ([1; 2; 3], [4; 5; 6])
I can assume that the length of the list is even.
I'm also expected to define an auxiliary function gencut(n, xs) that cuts xs into two pieces, where n gives the size of the first piece:
gencut(2, [1;3;4;2;7;0;9]);;
val it : int list * int list = ([1; 3], [4; 2; 7; 0; 9])
I wouldn't normally ask for exercise help here, but I'm really at a loss as to where to even start. Any help, even if it's just a nudge in the right direction, would help.
Thanks!
Since your list has an even length, and you're cutting it cleanly in half, I recommend the following (psuedocode first):
Start with two pointers: slow and fast.
slow steps through the list one element at a time, fast steps two elements at a time.
slow adds each element to an accumulator variable, while fast moves foward.
When the fast pointer reaches the end of the list, the slow pointer will have only stepped half the number of elements, so its in the middle of the array.
Return the elements slow stepped over + the elements remaining. This should be two lists cut neatly in half.
The process above requires one traversal over the list and runs in O(n) time.
Since this is homework, I won't give a complete answer, but just to get you partway started, here's what it takes to cut the list cleanly in half:
let cut l =
let rec cut = function
| xs, ([] | [_]) -> xs
| [], _ -> []
| x::xs, y::y'::ys -> cut (xs, ys)
cut (l, l)
Note x::xs steps 1 element, y::y'::ys steps two.
This function returns the second half of the list. It is very easy to modify it so it returns the first half of the list as well.
You are looking for list slicing in F#. There was a great answer by #Juliet in this SO Thread: Slice like functionality from a List in F#
Basically it comes down to - this is not built in since there is no constant time index access in F# lists, but you can work around this as detailed. Her approach applied to your problem would yield a (not so efficient but working) solution:
let gencut(n, list) =
let firstList = list |> Seq.take n |> Seq.toList
let secondList = list |> Seq.skip n |> Seq.toList
(firstList, secondList)
(I didn't like my previous answer so I deleted it)
The first place to start when attacking list problems is to look at the List module which is filled with higher order functions which generalize many common problems and can give you succinct solutions. If you can't find anything suitable there, then you can look at the Seq module for solutions like #BrokenGlass demonstrated (but you can run into performance issues there). Next you'll want to consider recursion and pattern matching. There are two kinds of recursion you'll have to consider when processing lists: tail and non-tail. There are trade-offs. Tail-recursive solutions involve using an accumulator to pass state around, allowing you to place the recursive call in the tail position and avoid stack-overflows with large lists. But then you'll typically end up with a reversed list! For example,
Tail-recursive gencut solution:
let gencutTailRecursive n input =
let rec gencut cur acc = function
| hd::tl when cur < n ->
gencut (cur+1) (hd::acc) tl
| rest -> (List.rev acc), rest //need to reverse accumulator!
gencut 0 [] input
Non-tail-recursive gencut solution:
let gencutNonTailRecursive n input =
let rec gencut cur = function
| hd::tl when cur < n ->
let x, y = gencut (cur+1) tl //stackoverflow with big lists!
hd::x, y
| rest -> [], rest
gencut 0 input
Once you have your gencut solution, it's really easy to define cut:
let cut input = gencut ((List.length input)/2) input
Here's yet another way to do it using inbuilt library functions, which may or may not be easier to understand than some of the other answers. This solution also only requires one traversal across the input. My first thought after I looked at your problem was that you want something along the lines of List.partition, which splits a list into two lists based on a given predicate. However, in your case this predicate would be based on the index of the current element, which partition cannot handle, short of looking up the index for each element.
We can accomplish creating our own equivalent of this behavior using a fold or foldBack. I will use foldBack here as it means you won't have to reverse the lists afterward (see Stephens excellent answer). What we are going to do here is use the fold to provide our own index, along with the two output lists, all as the accumulator. Here is the generic function that will split your list into two lists based on n index:
let gencut n input =
//calculate the length of the list first so we can work out the index
let inputLength = input |> List.length
let results =
List.foldBack( fun elem acc->
let a,b,index = acc //decompose accumulator
if (inputLength - index) <= n then (elem::a,b,index+1)
else (a,elem::b,index+1) ) input ([],[],0)
let a,b,c = results
(a,b) //dump the index, leaving the two lists as output.
So here you see we start the foldBack with an initial accumulator value of ([],[],0). However, because we are starting at the end of the list, the 0 representing the current index needs to be subtracted from the total length of the list to get the actual index of the current element.
Then we simply check if the current index falls within the range of n. If it does, we update the accumulator by adding the current element to list a, leave list b alone, and increase the index by 1 : (elem::a,b,index+1). In all other cases, we do exactly the same but add the element to list b instead: (a,elem::b,index+1).
Now you can easily create your function that splits a list in half by creating another function over this one like so:
let cut input =
let half = (input |> List.length) / 2
input |> gencut half
I hope that can help you somewhat!
> cut data;;
val it : int list * int list = ([1; 2; 3], [4; 5; 6])
> gencut 5 data;;
val it : int list * int list = ([1; 2; 3; 4; 5], [6])
EDIT: you could avoid the index negation by supplying the length as the initial accumulator value and negating it on each cycle instead of increasing it - probably simpler that way :)
let gencut n input =
let results =
List.foldBack( fun elem acc->
let a,b,index = acc //decompose accumulator
if index <= n then (elem::a,b,index-1)
else (a,elem::b,index-1) ) input ([],[],List.length input)
let a,b,c = results
(a,b) //dump the index, leaving the two lists as output.
I have the same Homework, this was my solution. I'm just a student and new in F#
let rec gencut(n, listb) =
let rec cut n (lista : int list) (listb : int list) =
match (n , listb ) with
| 0, _ -> lista, listb
| _, [] -> lista, listb
| _, b :: listb -> cut (n - 1) (List.rev (b :: lista )) listb
cut n [] listb
let cut xs = gencut((List.length xs) / 2, xs)
Probably is not the best recursive solution, but it works. I think
You can use List.nth for random access and list comprehensions to generate a helper function:
let Sublist x y data = [ for z in x..(y - 1) -> List.nth data z ]
This will return items [x..y] from data. Using this you can easily generate gencut and cut functions (remember to check bounds on x and y) :)
check this one out:
let gencut s xs =
([for i in 0 .. s - 1 -> List.nth xs i], [for i in s .. (List.length xs) - 1 -> List.nth xs i])
the you just call
let cut xs =
gencut ((List.length xs) / 2) xs
with n durationn only one iteration split in two