Haskell. Assigning name to a threshold of values - function

I'm trying to figure out how to write in Haskell:
There is a list made of 4 variables: [w,x,y,z]
After completing the following through ghci:
collection :: Int -> Int -> Int -> Int -> [Int]
collection w x y z = [w,x,y,z]
I want to assign a "meaning" to each threshold value for w,x,y,z. Example: when 0 < x < 60, then x = "Low", when 59 < x < 80, then x = "Medium", when 79 < x < 100, then x = "High"
How do you put that in Haskell code?

If I understand correctly what you want, you can define a function that assigns what you call "meaning" to a single integer, and then map the collection list over it:
bin :: Int -> String
bin x
| x <= 0 = error "nonpositive value"
| x < 60 = "Low"
| x < 80 = "Medium"
| x < 100 = "High"
| otherwise = error "value greater than or equal to 100"
binnedCollection :: Int -> Int -> Int -> Int -> [String]
binnedCollection w x y z = map bin $ collection w x y z
For example,
Prelude> binnedCollection 0 20 60 80
["Low","Low","Medium","High"]
I have added error cases for the ranges not included in your definition; change them to whatever is appropriate for your logic.

Related

Why "Parse error in pattern: x >= y" when defining a function by guarded equation?

I try to use guarded equation to define a function. Why does it not work in GHCi? Thanks.
Prelude> :{
Prelude| maxThree :: Integer -> Integer -> Integer -> Integer
Prelude| maxThree x y z
Prelude| x >= y && x >= z = x
Prelude| y >= z = y
Prelude| otherwise = z
Prelude| :}
<interactive>:77:1: error: Parse error in pattern: x >= y
Your syntax is wrong. Don’t be confused by the fact that the prompt already contains |! What you’ve written is the following:
maxThree :: Integer -> Integer -> Integer -> Integer
maxThree x y z
x >= y && x >= z = x
y >= z = y
otherwise = z
As you can see, this is clearly wrong. Guards always start with a vertical bar |, but you’ve left it out. I assume you got confused by the fact that the Prelude| prompt already contains |; that is part of the UI of GHCi, and is not considered to be part of the code you type in. If you want to type a guard into GHCi, do it like this:
Prelude> :{
Prelude| maxThree :: Integer -> Integer -> Integer -> Integer
Prelude| maxThree x y z
Prelude| | x >= y && x >= z = x
Prelude| | y >= z = y
Prelude| | otherwise = z
Prelude| :}
Note how I have typed the code into GHCi exactly the same as I would type it into a file, including the fact that the guards need to be indented relative to the start of the definition.

Function to return a part of a list

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.

haskell add anything to a existing function

hey there using this script:
smallestDifference3 :: Int -> Int -> Int -> Int
smallestDifference3 a b c
| ((differenceAB < differenceBC) && (differenceBC < differenceAC)) = differenceAB
| ((differenceAB < differenceAC) && (differenceAC < differenceBC)) = differenceAB
| ((differenceBC < differenceAB) && (differenceAB < differenceAC)) = differenceBC
| ((differenceBC < differenceAC) && (differenceAC < differenceAB)) = differenceBC
| ((differenceAC < differenceBC) && (differenceBC < differenceAB)) = differenceAC
| ((differenceAC < differenceAB) && (differenceBC < differenceBC)) = differenceAC
where differenceAB
| a < b = -(a - b)
| otherwise = a - b
differenceBC
| b < c = -(b - c)
| otherwise = b - c
differenceAC
| a < c = -(a - c)
| otherwise = a - c
i can type three Integers and get the smallest result of two of these Integer´s.
but what can i do if i add one more INT, so i have:
smallestDifference4 :: Int -> Int -> Int -> Int -> Int
smallestDifference4 a b c d
// etc..
Should i use the "smallestDifference3"-function to get this or what do i need to do? greetings!
Introduce a generic function which takes a list, i.e.
smallestDifference :: [Int] -> Int
and then use that from your other functions, e.g.
smallestDifference4 :: Int -> Int -> Int -> Int -> Int
smallestDifference4 a b c d = smallestDifference [a,b,c,d]
...of course, at that point you might want to just drop those tiny functions altogether since they don't "pull their own weight".
That being said, you could implement this function more in terms of existing functions. The idea is that you need a way to get all possible pairs for the given list, then compute the difference of the pair members, and then pick the minimum of that.
You would need an 'all pairs' function like
pairs :: [a] -> [(a, a)]
pairs = concat . go
where go [] = []
go [x] = []
go (x:xs) = map (\a -> (x,a)) xs : go xs
and then you could do it like
smallestDifference = minimum
. map abs
. map (uncurry (-))
. pairs

Compute next prime number in Haskell

I am trying to compute the next closest prime number after a number is entered with Haskell,
I have coded 2 functions isPrime and nextPrime
Here is my code:
isPrime :: Int -> Bool
isPrime x | x < 2 = False
| otherwise = prime (2:[3,4..(x-1)])
where
prime (y:z)
| x < y ^ 2 = True
| x `mod` y == 0 = False
| otherwise = prime z
nextPrime :: Int -> Int
nextPrime n | isPrime n == True = n
| otherwise = nextPrime n
where
n = n + 1
The problem I have is that I get this error when I run it : * Exception: "<<"loop">>"
I don't know what's wrong, is it an infinite loop?
You cannot change the value of variables in Haskell. This means that you cannot execute
n = n + 1
since that would change the value of n. In Haskell, n is a name that always refers to the same value inside the function it is used. If n starts out as 3, n will always be 3. You could do,
next = n + 1
and then also change
| otherwise = nextPrime n
into
| otherwise = nextPrime next
This will not change the value of any variable, but instead create a new variable with the new value – something you often do in Haskell!
Just change the definition of nextPrime to
nextPrime :: Int -> Int
nextPrime n | isPrime n = n -- don't need to compare to True here
| otherwise = nextPrime (n+1)
You generate an infinite regress when you try to define n = n + 1, as the runtime would attempt to expand this as
n = n + 1
= (n + 1) + 1
= ((n + 1) + 1) + 1
= ...
Fortunately, the compiler is able to detect this kind of infinite regress and warn you about it!

How to create a Prouhet–Thue–Morse sequence in Haskell?

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))