Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Statements In Haskell

Tags:

syntax

haskell

How do you have multiple statements in haskell?

Here's what I'm trying to do: given a list such as [a,b,c,d], return every other element, so you get [a,c]. I can see the solution, and here's what I have so far:

fact (xs)   | length( xs ) `mod` 2  == 1 = head( xs )
    | otherwise = fact(tail( xs ))

This works fine the first time around, but then it quits. What I want to be able to say is return the head, and then call fact(tail(xs)) How do I do that?

like image 428
confused Avatar asked Oct 17 '09 01:10

confused


People also ask

How do you do multiple If statements in Haskell?

In Haskell, multiple lines of if will be used by separating each of the if statement with its corresponding else statement. In the above example, we have introduced multiple conditions in one function. Depending on the function inputs, it will provide us different outputs.

How do you divide in Haskell?

The (/) function requires arguments whose type is in the class Fractional, and performs standard division. The div function requires arguments whose type is in the class Integral, and performs integer division. More precisely, div and mod round toward negative infinity.

What are guards in Haskell?

Haskell guards are used to test the properties of an expression; it might look like an if-else statement from a beginner's view, but they function very differently. Haskell guards can be simpler and easier to read than pattern matching .


1 Answers

The function you specified returns only a single element. You'd need to change it to something like:

fact [] = [] -- can't call tail on a list of length 0!
fact (xs)   | length( xs ) `mod` 2  == 1 = head( xs ) : fact(tail(xs))
            | otherwise = fact(tail( xs ))

You may find it helpful to write out type signatures to help figure out thinkos like this:

fact :: [a] -> [a] -- convert a list of anything to another (shorter) list

However note that this is very slow - O(n^2) in fact, since it's taking length at each step. A much more haskelly solution would use pattern matching to process two elements at a time:

fact :: [a] -> [a]
-- Take the first element of each two-element pair...
fact (x:_:xs) = x:fact xs
-- If we have only one element left, we had an odd-length list.
-- So grab the last element too.
fact [x]      = [x]
-- Return nothing if we have an empty list
fact _        = []
like image 121
bdonlan Avatar answered Oct 04 '22 01:10

bdonlan