I'm a noob in Haskell, but some experience with ActionScript 3.0 Object Orientated. Thus working on a major programming transition. I've read the basic knowledge about Haskel, like arithmetics. And I can write simple functions.
As a practical assignment I have to generate the Thue-Morse sequence called tms1 by computer in Haskell. So it should be like this:
>tms1 0
0
>tms1 1
1
>tms1 2
10
>tms1 3
1001
>tms1 4
10010110
and so on... According to wikipedia I should use the formula.
t0 = 0
t2n = tn
t2n + 1 = 1 − tn
I have no idea how I can implement this formula in Haskell. Can you guide me to create one?
This is what I got so far:
module ThueMorse where
tms1 :: Int -> Int
tms1 0 = 0
tms1 1 = 1
tms1 2 = 10
tms1 3 = 1001
tms1 x = tms1 ((x-1)) --if x = 4 the output will be 1001, i don't know how to make this in a recursion function
I did some research on the internet and found this code.
Source:
http://pastebin.com/Humyf6Kp
Code:
module ThueMorse where
tms1 :: [Int]
tms1 = buildtms1 [0] 1
where buildtms1 x n
|(n `rem` 2 == 0) = buildtms1 (x++[(x !! (n `div` 2))]) (n+1)
|(n `rem` 2 == 1) = buildtms1 (x++[1- (x !! ((n-1) `div` 2))]) (n+1)
custinv [] = []
custinv x = (1-head x):(custinv (tail x))
tms3 :: [Int]
tms3 = buildtms3 [0] 1
where buildtms3 x n = buildtms3 (x++(custinv x)) (n*2)
intToBinary :: Int -> [Bool]
intToBinary n | (n==0) = []
| (n `rem` 2 ==0) = intToBinary (n `div` 2) ++ [False]
| (n `rem` 2 ==1) = intToBinary (n `div` 2) ++ [True]
amountTrue :: [Bool] -> Int
amountTrue [] = 0
amountTrue (x:xs) | (x==True) = 1+amountTrue(xs)
| (x==False) = amountTrue(xs)
tms4 :: [Int]
tms4= buildtms4 0
where buildtms4 n
|(amountTrue (intToBinary n) `rem` 2 ==0) = 0:(buildtms4 (n+1))
|(amountTrue (intToBinary n) `rem` 2 ==1) = 1:(buildtms4 (n+1))
But this code doesn't give the desired result. Any help is well appreciated.
I would suggest using a list of booleans for your code; then you don't need to explicitly convert the numbers. I use the sequence defined like this:
0
01
0110
01101001
0110100110010110
01101001100101101001011001101001
...
Notice that the leading zeros are quite important!
A recursive definition is now easy:
morse = [False] : map step morse where step a = a ++ map not a
This works because we never access an element that is not yet defined. Printing the list is left as an excercise to the reader.
Here is another definition, using the fact that one can get the next step by replacing 1 with 10 and 0 with 01:
morse = [False] : map (concatMap step) morse where step x = [x,not x]
Edit
Here are easier definitions by sdcvvc using the function iterate. iterate f x returns a list of repeated applications of f to x, starting with no application:
iterate f x = [x,f x,f (f x),f (f (f x)),...]
And here are the definitions:
morse = iterate (\a -> a ++ map not a) [False]
morse = iterate (>>= \x -> [x,not x]) [False]
Your definition of the sequence seems to be as a sequence of bit sequences:
0 1 10 1001 10010110 ... etc.
t0 t1 t2 t3 t4
but the wikipedia page defines it as a single bit sequence:
0 1 1 0 1 ... etc
t0 t1 t2 t3 t4
This is the formulation that the definitions in Wikipedia refer to. With this knowledge, the definition of the recurrence relation that you mentioned is easier to understand:
t0 = 0
t2n = tn
t2n + 1 = 1 − tn
In English, this can be stated as:
The zeroth bit is zero.
For an even, non-zero index, the bit is the same as the bit at half the index.
For an odd index, the bit is 1 minus the bit at half the (index minus one).
The tricky part is going from subscripts 2n and 2n+1 to odd and even, and understanding what n means in each case. Once that is done, it is straightforward to write a function that computes the *n*th bit of the sequence:
lookupMorse :: Int -> Int
lookupMorse 0 = 0;
lookupMorse n | even n = lookupMorse (div n 2)
| otherwise = 1 - lookupMorse (div (n-1) 2)
If you want the whole sequence, map lookupMorse over the non-negative integers:
morse :: [Int]
morse = map lookupMorse [0..]
This is the infinite Thue-Morse sequence. To show it, take a few of them, turn them into strings, and concatenate the resulting sequence:
>concatMap show $ take 10 morse
"0110100110"
Finally, if you want to use the "sequence of bit sequences" definition, you need to first drop some bits from the sequence, and then take some. The number to drop is the same as the number to take, except for the zero-index case:
lookupMorseAlternate :: Int -> [Int]
lookupMorseAlternate 0 = take 1 morse
lookupMorseAlternate n = take len $ drop len morse
where
len = 2 ^ (n-1)
This gives rise to the alternative sequence definition:
morseAlternate :: [[Int]]
morseAlternate = map lookupMorseAlternate [0..]
which you can use like this:
>concatMap show $ lookupMorseAlternate 4
"10010110"
>map (concatMap show) $ take 5 morseAlternate
["0", "1", "10", "1001", "10010110"]
Easy like this:
invertList :: [Integer] -> [Integer]
invertList [] = []
invertList (h:t)
|h == 1 = 0:invertList t
|h == 0 = 1:invertList t
|otherwise = error "Wrong Parameters: Should be 0 or 1"
thueMorse :: Integer -> [Integer]
thueMorse 1 = [0]
thueMorse n = thueMorse (n - 1) ++ invertList (thueMorse (n - 1))
Related
I am working on the following exercise:
Define a function libDiv which computes the list of natural divisors of some positive integer.
First define libDivInf, such that libDivInf n i is the list of divisors of n which are lesser than or equal to i
libDivInf : int -> int -> int list
For example:
(liDivInf 20 4) = [4;2;1]
(liDivInf 7 5) = [1]
(liDivInf 4 4) = [4;2;1]
Here's is my attempt:
let liDivInf : int -> int -> int list = function
(n,i) -> if i = 0 then [] (*ERROR LINE*)
else
if (n mod i) = 0 (* if n is dividable by i *)
then
i::liDivInf n(i-1)
else
liDivInf n(i-1);;
let liDiv : int -> int list = function
n -> liDivInf n n;;
I get:
ERROR: this pattern matches values of type 'a * 'b ,but a pattern
was expected which matches values of type int
What does this error mean? How can I fix it?
You've stated that the signature of liDivInf needs to be int -> int -> int list. This is a function which takes two curried arguments and returns a list, but then bound that to a function which accepts a single tuple with two ints. And then you've recursively called it in the curried fashion. This is leading to your type error.
The function keyword can only introduce a function which takes a single argument. It is primarily useful when you need to pattern-match on that single argument. The fun keyboard can have multiple arguments specified, but does not allow for pattern-matching the same way.
It is possible to write a function without using either.
let foo = function x -> x + 1
Can just be:
let foo x = x + 1
Similarly:
let foo = function x -> function y -> x + y
Can be written:
let foo x y = x + y
You've also defined a recursive function, but not included the rec keyword. It seems you're looking for something much more like the following slightly modified version of your attempt.
let rec liDivInf n i =
if i = 0 then
[]
else if (n mod i) = 0 then
i::liDivInf n (i-1)
else
liDivInf n (i-1)
I'm very new to Haskell and am trying to write a simple function that will take an array of integers as input, then return either the product of all the elements or the average, depending on whether the array is of odd or even length, respectively.
I understand how to set a base case for recursion, and how to set up boolean guards for different cases, but I don't understand how to do these in concert.
arrayFunc :: [Integer] -> Integer
arrayFunc [] = 1
arrayFunc array
| (length array) % 2 == 1 = arrayFunc (x:xs) = x * arrayFunc xs
| (length array) % 2 == 0 = ((arrayFunc (x:xs) = x + arrayFunc xs) - 1) `div` length xs
Currently I'm getting an error
"parse error on input '='
Perhaps you need a 'let' in a 'do' block?"
But I don't understand how I would use a let here.
The reason you have guards is because you are trying to determine the length of the list before you actually look at the values in the list.
Rather than make multiple passes (one to compute the length, another to compute the sum or product), just compute all of the values you might need, as you walk the list, and then at the end make the decision and return the appropriate value:
arrayFunc = go (0, 1, 0, True)
where go (s, p, len, parity) [] =
if parity then (if len /= 0 then s `div` len else 0)
else p
go (s, p, len, parity) (x:xs) =
go (s + x, p * x, len + 1, not parity) xs
There are various things you can do to reduce memory usage, and the recursion is just reimplementing a fold, but this gives you an idea of how to compute the answer in one pass.
Define an auxiliary inner function like that:
arrayFunc :: [Integer] -> Integer
arrayFunc [] = 1
arrayFunc array
| (length array) % 2 == 1 = go1 array
| (length array) % 2 == 0 = go2 array
where
go1 (x:xs) = x * go1 xs
go2 (x:xs) = ((x + go2 xs) - 1) `div` length xs
This deals only with the syntactical issues in your question. In particular, [Integer] is not an array -- it is a list of integers.
But of course the name of a variable doesn't influence a code's correctness.
Without focus on recursion this should be an acceptable solution:
arrayFunc :: (Integral a) => [a] -> a
arrayFunc ls
| n == 0 = 1
| even n = (sum ls) `div` (fromIntegral n)
| otherwise = product ls
where
n = length xs
I want to take the user input of a list of numbers and find the average. However, after looking for examples I have not found any that seems to match what I am doing because I can have from 2 - 100 numbers in a list. Any help/advice is appreciated.
Below is my working code as is.
main = do
putStrLn "Enter how many numbers:"
listlen <- getLine
if ((read listlen) <= 100) -- read converts a string to a number
then do
putStrLn "Enter a String of numbers:"
--numberString <- getLine
numberString<- getLine
let ints = map read (words numberString) :: [Int]
putStrLn("The List: " ++(numberString))
putStrLn("The average: ")
putStrLn("Number of values greater than average: ")
else do
putStrLn " Error: listlen must be less than or = to 100"
main
Ok, this is homework, but homework can be really tough when you have to do it in Haskell. I'll try to explain step by step how you can do.
Good to know
First, Haskell is functional. You can find different defintions of "functional", but basically you can think of it as a property of the language: everything is constant (no side effect).
Second, you can start a REPL by typing ghci in a terminal:
jferard#jferard-Z170XP-SLI:~$ ghci
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help
Prelude> :set +m -- enable parsing of multiline commands
Prelude> -- type the expression you want to evaluate here
Recursion
How do you compute the sum of the elements of a list? In an imperative language, you will do something like that (Python like):
s = 0
for every x in xs:
s <- s + x
But s is not constant. It's updated on every iteration until we get the sum. Can we reformulate the algorithm to avoid this mutation? Fortunately yes. Here's the key idea:
sum [x] = x
sum [x1, ..., xn] = x1 + sum [x2, ..., xn]
With a little imagination, you can say that sum [] = 0. So we can write it in Haskell:
sum [] = 0
sum (x:xs) = x + sum xs
-- sum [1, 2, 3, 5] == 11
(x:xs) means: x (the head) followed by the list xs (the tail). If you have understood that, you know how we can avoid side effects in many situations: just call another function to do the rest of the job. (Note: if you know about the stack, you can imagine what happens under the hood.)
Now, how do you compute the length of a list? In a Python-like language, you'd do something like (forget len(..)):
l = 0
for every x in xs:
l <- l + 1
Again, with a recursive definition, you have:
length [] = 0
length (x:xs) = 1 + length xs
-- len [1, 2, 3, 5] == 4
Folds
Computing sum and length is so common that they are built-in functions in Haskell. But there is something more important: if you examine the two functions carefully, you'll notice this pattern:
f [] = <initial value>
f (x:xs) = g(f xs, x)
For sum, initial value is 0 and g(f xs, x) = x + f xs. For length, initial value is 0 and g(f xs, x) = 1 + f xs. This pattern is so common that Haskell has a built-in function (actually several built-in functions) for it: foldl. foldl takes a function, an initial value and a list and returns the function repeatedly applied to the previous result and the current element, until the list is consumed. You can think of the function as the the body of the loop:
sum xs = foldl (+) 0 xs
(Note on curryfication: 1. You will maybe learn some day that Haskell functions always take one argument, but that's not the point here. 2. You can remove xs on both sides: sum = foldl (+) 0)
Prelude> foldl (+) 0 [1,2,3,5]
11 -- (((0+1)+2)+3)+5
With scanl, you can in some way "debug" the foldl:
Prelude> scanl (+) 0 [1,2,3,5]
[0,1,3,6,11]
length is more tricky, since you don't have a built-in function g(f xs, x) = 1 + f xs. You can use a lambda function: \acc x -> 1 + acc where acc is the current value:
length xs = foldl (\acc x -> 1 + acc) 0 xs
Your question
Average
Let's try to write average with the built-in sum and length functions:
Prelude> average xs = sum xs / length xs
<interactive>:1:14: error:
• Could not deduce (Fractional Int) arising from a use of ‘/’
...
What does that mean? I won't get into details, but you have to know that Haskell is very strict with numbers. You can't divide two integers and expect a float result without a little work.
Prelude> :t (/)
(/) :: Fractional a => a -> a -> a
This means that / will take Fractionals. Thus, the work is: cast integers into Fractionals.
average xs = fromIntegral (sum xs) / fromIntegral (length xs)
-- average [1, 2, 3, 5] == 2.75
Number of values greater than average
Now, the number of values greater than the mean. In a Python-like langage, you'll write:
c = 0
for every x in xs:
if x > avg:
c <- c + 1
Let's try the recursive method:
gtAvg [] = 0
gtAvg (x:xs) = (if x>avg then 1) + sum xs -- WRONG
You see that there is something missing. In the imperative version, if x <= avg, we simply do nothing (and thus do not update the value). Here, we must return something:
gtAvg [] = 0
gtAvg (x:xs) = (if x>avg then 1 else 0) + gtAvg xs
But where does the avg value come from? We need to precompute it. Let's define a function that takes avg as an argument:
gtAvg' [] _ = 0
gtAvg' (x:xs) avg = (if fromIntegral x>avg then 1 else 0) + gtAvg' xs avg
-- gtAvg' [1, 2, 3, 5] (average [1, 2, 3, 5]) == 2
And then:
gtAvg xs = gtAvg' xs (average xs)
-- gtAvg [1, 2, 3, 5] == 2
Obviously, this is more simple with a foldl:
gtAvg xs = foldl (\acc x -> if fromIntegral x>average xs then acc+1 else acc) 0 xs
More (map, filter and list comprehension)
When we are on the basics of Haskell, you may need three more constructs.
Filter
First, a filter:
Prelude> filter (>2.75) [1, 2, 3, 5]
[3.0,5.0]
If you take the length of that list, you get the number of elements greater than the average:
gtAvg xs = length $ filter (\x -> fromIntegral x >average xs) xs
(Or with a composition of functions: length $ filter ((> average xs).fromIntegral) xs) Don't be disturbed by the $ sign: it means that the right side of the expression (filter...) is one block, like if it were in parenthesis.
Map
Second, map applies a function to every element of a list and returns the list of mapped elements. For instance, if you want to some squares of elements of a list:
Prelude> sum $ map (**2) [1, 2, 3, 5]
39.0
You can use it like that:
gtAvg xs = length $ filter (>average xs) $ map fromIntegral xs
It converts elements to Fractional, then it applies the filter.
List comprehension
Third, you can have filter and a map with a list comprehension:
gtAvg xs = length [x | x<-xs, fromIntegral x>average xs]
I left a lot of things aside and made probably approximations, but now you should have the basic knowledge to answer your question.
listlen :: [a] -> Int
listlen xs = go 0 xs -- 0 = initial value of accumulator
where go s [] = s -- return accumulator
go s (a:as) = go (s+1) as -- compute the next value of the accumulator
sumx :: [a] -> Int
sumx xs = go 0 xs
where go s [] = s
go s (a:as) = go ... as -- flll in the blank ... -- and recurse
lenAndSum :: [a] -> (Int,Int)
lenAndSum xs = go (0,0) xs -- (0,0) = initial values of both accumulators
where go (s1,s2) [] = (s1,s2) -- return both accumulators at the end
go (s1,s2) (a:as) = go ... as -- left as an exercise
main = do
putStrLn "Enter how many numbers:"
listlen <- getLine
if ((read listlen) <= 100) -- read converts a string to a number
then do
putStrLn "Enter a String of numbers:"
--numberString <- getLine
numberString<- getLine
let ints = map read (words numberString) :: [Int]
putStrLn("The List: " ++(numberString))
putStrLn("The average: ")
putStrLn("Number of values greater than average: ")
else do
putStrLn " Error: listlen must be less than or = to 100"
main`enter code here`
I am new to Haskell and have an assignment. I have to write a
Int->Int->[u]->[u]
Function that is given input two Ints i and j and a list and returns the elements that are in possitions greater than i and smaller than j. What I have thought so far is:
fromTo :: Int->Int->[u]->[u]
fromTo i j (h:t)
|i == 1 && j == length(h:t)
= (h:t)
|i /= 1
fromTo (i-1) j t
|j /= length(h:t)
fromTo i j init(h:t)
However I get a syntax error for the second |. Also im unsure if my train of thought is correct here.
(init returns the list without its last element)
EDIT: Corrected
|i /= 1
fromTo (i-1) j (h:t)
to
|i /= 1
fromTo (i-1) j t
Fixed indentation, parenthesization, and missing =s. This reformation compiles, and works for ordinals and finite non-empty lists:
fromTo :: Int -> Int -> [u] -> [u]
fromTo i j (h : t)
| i == 1 && j == length (h : t) = h : t
| i /= 1 = fromTo (i - 1) j t
| j /= length (h : t) = fromTo i j (init (h : t))
I think you're looking for something like this pointfree, naturally indexing span:
take :: Int -> [a] -> [a]
take _ [] = []
take 0 _ = []
take n (x : xs) = x : take (n - 1) xs
drop :: Int -> [a] -> [a]
drop _ [] = []
drop 0 xs = xs
drop n (_ : xs) = drop (n - 1) xs
span :: Int -> Int -> [a] -> [a]
span i j = drop i . take (j + 1)
which
span 0 3 [0 .. 10] == [0,1,2,3]
Or, to fit the specification:
between :: Int -> Int -> [a] -> [a]
between i j = drop (i + 1) . take j
which
between 0 3 [0 .. 10] == [1,2]
You're missing = between the | guard clause and the body. The Haskell compiler thinks the whole thing is the guard, and gets confused when it runs into the next | guard because it expects a body first. This will compile (although it is still buggy):
fromTo :: Int -> Int -> [u] -> [u]
fromTo i j (h:t)
| i == 1 && j == length (h:t) =
(h:t)
| i /= 1 =
fromTo (i-1) j t
| j /= length (h:t) =
fromTo i j (init (h:t))
but I would say there are better ways of writing this function. For example, in principle a function like this should work on infinite lists, but your use of length makes that impossible.
Here is complete solution that use recursion:
fromTo :: Int -> Int -> [u] -> [u]
fromTo i j xs = go i j xs []
where go i j (x:xs) rs
| i < 0 || j < 0 = []
| i > length (x:xs) || j > length (x:xs) = []
| i /= 0 = go (i - 1) j t
| j /= 1 = goo i (j -1) (rs ++ [x])
| otherwise = rs
Notes:
go is standard Haskell idiom for recursive function that need extra parameters compared to main level function.
First clause make sure that negative indexes result in empty list. Second does the same for any index that exceed size of a list. Lists must be finite. Third "forgets" head of the array i times. Fourth will accumulate "next" (j - 1) heads into rs. Fifth clause will be triggered when all indexes are "spent" and rs contain result.
You could make it work on infinite lists. Drop second clause. Return rs if xs is empty before "exhausting" indexes. Then function will take "up to" (j-1) elements from i.
I'm exploring "advanced" uses of OCaml functions and I'm wondering how I can write a function with variable number of arguments.
For example, a function like:
let sum x1,x2,x3,.....,xn = x1+x2,+x3....+xn
With a bit of type hackery, sure:
let sum f = f 0
let arg x acc g = g (acc + x)
let z a = a
And the (ab)usage:
# sum z;;
- : int = 0
# sum (arg 1) z;;
- : int = 1
# sum (arg 1) (arg 2) (arg 3) z;;
- : int = 6
Neat, huh? But don't use this - it's a hack.
For an explanation, see this page (in terms of SML, but the idea is the same).
OCaml is strongly typed, and many techniques used in other (untyped) languages are inapplicable. In my opinion (after 50 years of programming) this is a very good thing, not a problem.
The clearest way to handle a variable number of arguments of the same type is to pass a list:
# let sum l = List.fold_left (+) 0 l;;
val sum : int list -> int = <fun>
# sum [1;2;3;4;5;6];;
- : int = 21