I am new in Haskell, could guys help me how to generating list from 1 to 10.
I tried to make like this:
seqList :: Integer -> [Integer]
seqList 1 = [1]
seqList n = n : seqList(n-1)
The result 10 to 1, not 1 to 10
And second question
can we make function as value.
numList :: [Integer]
numList = [1,2..10]
totJum :: Int
totJum = length numList
takeNum :: Int->[Integer]
takeNum totJum
| totJum >= 10 = take 5 numList
| totJum == 10 = numList
With this code, i want to call output if the length from numlist matches the condition.
For the first one you can work with an accumulator: a variable you use to yield a value and each time increment in the recursive call, so:
seqList :: Integer -> [Integer]
seqList n = go 1
where go i
| i <= … = …
| otherwise = …
where I leave filling in the … parts as an exercise.
with this code, I want to call output if the length from numlist matches the condition.
You should not use totJum as a parameter, but just use it in the body of the function, so:
takeNum :: [Integer]
takeNum
| totJum >= 10 = take 5 numList
| totJum == 10 = numList
Note however that here you do not cover the case where totJum is less than or 10. In that case the function will thus error. You thus might want to add an otherwise clause.
Related
like consider the following python code,
n = 4
if n>3 :
n = 5
if n>2 :
n = 6
if n>1 :
n = 4
How to achieve this in haskell??
let n = 4
main :: IO()
main = do
if n>3 then let n = 5
if n>2 then let n = 6
if n>1 then let n = 4
Tried this but gives an error, looking for some modifications
As I commented there are some points of your program you should checkout
else must be used after if
You don't use let for top level declarations (as in let n = 4).
When you write if n>3 then let n=5 you are not changing the value of n because values are inmutables in Haskell
There are a few "idiomatic" ways you can rewrite your program
Use a chained if then else with prints. This is the closest to your code
n = 4 -- no let in top level binding
main :: IO()
main = do
if n>3 then print 5 -- do not use let n=5 because n can't be mutated
else if n>2 then print 6
else if n>1 then print 4
else print ()
Use an external function and guards. This is the most idiomatic
f :: Int -> Int
f x | x > 3 = 5
| x > 2 = 6
| x > 1 = 4
n = 4
main = do
print (f n)
As #davidflecher commented, you can use guards within a let binding
n = 4
main :: IO()
main = do
let x | n > 3 = 5
| n > 2 = 6
| n > 1 = 4
print x
Use MultyWayIf extension (This is more advance as it needs extensions to the language)
{-# LANGUAGE MultiWayIf #-}
n = 4
main :: IO()
main = do
let x = if | n > 3 -> 5
| n > 2 -> 6
| n > 1 -> 4
print x
While the example is a bit contrived, the usual way to encode an if with multiple branches is to use a case-of with () as the scrutinee as follows:
main :: IO()
main = do
case () of
_ | n > 3 -> ...
| n > 2 -> ...
| otherwise -> ...
or when part of a binding, by use of a guarded let
let x | n > 3 = ...
| n > 2 = ...
| otherwise = ...
Alternatively, this may also be encoded as guards of a helper function
f :: Int -> Int
f n | n > 3 = 5
| n > 2 = 6
| otherwise = 4
Updated to include #Iceland_jack's comment
I'm a newbie in haskell!
I need to write a function that process an ID number. I need to check the first digit of the integer number. If the number is 1 or 3 then the client is male, if the number is 2 or 4 then female. I think I need a helper function which splitting the long integer number to an integer list.
The fuction called szemelyinem, it has one parameter/argument which is a 11 long integer number.
This is the spliting function:
split :: Integral x => x -> [x]
split 0 = []
split x = split (x `div` 10) ++ [x `mod` 10]
In my head the notion is Split the long number then load it to the function, then check the first element in the list and return with one string. But I don't know how to start this :/
I have an example like this:
szemelyinem 40504291247
Result: "female"
This is the first step.
split :: Integral x => x -> [x]
split 0 = []
split x = split (x `div` 10) ++ [x `mod` 10]
This is the second.
rev:: [Integer] -> [Integer]
rev [] = []
rev (h:t) = rev t ++ [h]
This is the third step
nemdel :: [Integer] -> [Integer]
nemdel [] = []
nemdel (h:t) = drop 10 (h:t)
This is the fourth.
listtonumb:: [Integer] -> Integer
listtonumb = foldl addDigit 0
where addDigit num d = 10*num + d
And the last one.
szemelyinem :: Integer -> [Char]
szemelyinem szam =
if listtonumb(nemdel(rev(split szam))) == 1 || listtonumb(nemdel(rev(split szam))) == 3
then "male"
else if listtonumb(nemdel(rev(split szam))) == 2 || listtonumb(nemdel(rev(split szam))) == 4
then "Female"
else error "Bad ID"
I'm sure about that is a complex way to do this shit.
I´m new to Haskell.
Let´s say I want to sum up the first n elements of a list with a generated function on my own. I don´t know how to do this with Haskell. I just know how to sum up a whole given list, e.g.
sumList :: [Int] -> Int
sumList [] = 0
sumList (x:xs) = x + sumList xs
In order to sum up the first n elements of a list, for example
take the first 5 numbers from [1..10], which is 1+2+3+4+5 = 15
I thought I could do something like this:
sumList :: Int -> [Int] -> Int
sumList take [] = 0
sumList take (x:xs) = x + take $ sumList xs
But it doesn´t work... What´s wrong?
So you know how to sum up the numbers in a list,
sumList :: [Int] -> Int
sumList [] = 0
sumList (x:xs) = x + sumList xs
and if that list has no more than 5 elements in it, this function will even return the correct result if you indeed intended to sum no more than 5 elements in an argument list. Let's make our expectations explicit by renaming this function,
sumUpToFiveElements :: [Int] -> Int
sumUpToFiveElements [] = 0
sumUpToFiveElements (x:xs) = x + sumUpToFiveElements xs
it won't return the correct result for lists longer than five, but at least the name is right.
Can we fix that? Can we count up to 5? Can we count up to 5 while also advancing along the input list as we do?
sumUpToFiveElements :: Int -> [Int] -> Int
sumUpToFiveElements counter [] = 0
sumUpToFiveElements counter (x:xs) = x + sumUpToFiveElements (counter + 1) xs
This still isn't right of course. We do now count, but for some reason we ignore the counter. What is the right time to react to the counter, if we want no more than 5 elements? Let's try counter == 5:
sumUpToFiveElements :: Int -> [Int] -> Int
sumUpToFiveElements 5 [] = 0
sumUpToFiveElements counter [] = 0
sumUpToFiveElements counter (x:xs) = x + sumUpToFiveElements (counter + 1) xs
But why do we demand the list to also be empty when 5 is reached? Let's not do that:
sumUpToFiveElements :: Int -> [Int] -> Int
sumUpToFiveElements 5 _ = 0 -- the wildcard `_` matches *anything*
sumUpToFiveElements counter [] = 0
sumUpToFiveElements counter (x:xs) = x + sumUpToFiveElements (counter + 1) xs
Success! We now stop counting when 5 is reached! More, we also stop the summation!!
Wait, but what was the initial value of counter? We didn't specify it, so it's easy for a user of our function (that would be ourselves) to err and use an incorrect initial value. And by the way, what is the correct initial value?
Okay, so let's do this:
sumUpToFiveElements :: [Int] -> Int
sumUpToFiveElements xs = go 1 xs -- is 1 the correct value here?
where
go counter _ | counter == 5 = 0
go counter [] = 0
go counter (x:xs) = x + go (counter + 1) xs
Now we don't have that extraneous argument that made our definition so brittle, so prone to a user error.
And now for the punchline:
Generalize! (by replacing an example value with a symbolic one; changing 5 to n).
sumUpToNElements :: Int -> [Int] -> Int
sumUpToNElements n xs = .......
........
Done.
One more word of advice: don't use $ while at the very beginning of your learning Haskell. Use explicit parens.
sumList take (x:xs) = x + take $ sumList xs
is parsed as
sumList take (x:xs) = (x + take) (sumList xs)
This adds together two unrelated numbers, and then uses the result as a function to be called with (sumList xs) as an argument (in other words it's an error).
You probably wouldn't write it that way if you were using explicit parens.
Well you should limit the number of values with a parameter (preferably not take, since
that is a function from the Prelude), and thus limit the numbers.
This limiting in your code is apparently take $ sumList xs which is very strange: in your function take is an Int, and $ will basically write your statement to (x + take) (sumList xs). You thus apparently want to perform a function application with (x + take) (an Int) as function, and sumList xs as argument. But an Int is not a function, so it does not typecheck, nor does it include any logic to limit the numbers.
So basically we should consider three cases:
the empty list in which case the sum is 0;
the number of elements to take is less than or equal to zero, in that case the sum is 0; and
the number of elements to take is greater than 0, in that case we add the head to the sum of taking one element less from the tail.
So a straightforward mapping is:
sumTakeList :: (Integral i, Num n) => i -> [n] -> n
sumTakeList _ [] = 0
sumTakeList t (x:xs) | t <= 0 = 0
| otherwise = x + sumTakeList (t-1) xs
But you do not need to write such logic yourself, you can combine the take :: Int -> [a] -> [a] builtin with the sum :: Num a => [a] -> a functions:
sumTakeList :: Num n => Int -> [n] -> n
sumTakeList t = sum . take t
Now if you need to sum the first five elements, we can make that a special case:
subList5 :: Num n => [n] -> n
sumList5 = sumTakeList 5
A great resource to see what functions are available and how they work is Hoogle. Here is its page on take and the documentation for the function you want.
As you can see, the name take is taken, but it is a function you can use to implement this.
Note that your sumList needs another argument, the number of elements to sum. the syntax you want is something like:
sumList :: Int -> [Int] -> Int
sumList n xs = _ $ take n xs
Where the _ are blanks you can fill in yourself. It's a function in the Prelude, but the type signature is a little too complicated to get into right now.
Or you could write it recursively, with two base cases and a third accumulating parameter (by means of a helper function):
sumList :: Int -> [Int] -> Int
sumList n xs = sumList' n xs 0 where
sumList' :: Int -> [Int] -> Int -> Int
sumList' 0 _ a = _ -- A base case.
sumList' _ [] a = _ -- The other base case.
sumList' m (y:ys) a = sumList' _ _ _ -- The recursive case.
Here, the _ symbols on the left of the equals signs should stay there, and mean that the pattern guard ignores that parameter, but the _ symbols on the right are blanks for you to fill in yourself. Again, GHC will tell you the type you need to fill the holes with.
This kind of tail-recursive function is a very common pattern in Haskell; you want to make sure that each recursive call brings you one step closer to the base case. Often, that will mean calling itself with 1 subtracted from a count parameter, or calling itself with the tail of the list parameter as the new list parameter. here, you want to do both. Don't forget to update your running sum, a, when you have the function call itself recursively.
Here's a short-but-sweet answer. You're really close. Consider the following:
The take parameter tells you how many elements you need to sum up, so if you do sumList 0 anything you should always get 0 since you take no elements.
If you want the first n elements, you add the first element to your total and compute the sum of the next n-1 elements.
sumList 0 anything = 0
sumList n [] = 0
sumList n (e:es) = e + sumList (n-1) e
I have the following problem: given a max(max) apacity, and given a list of values(listOfValues) i need to return a list with values from the listOfValues. The sum of the elements must be <= max and i need to prioritize the higher values.
Example: typing solvingProblem 103 [15, 20, 5, 45, 34] i must get: [45, 45, 5, 5]
To solve the problem i create the following code:
solvingProblem max [] = 0
solvingProblem max listOfValues | max == 0 = 0
| otherwise = createList max listOfValues []
createList max [] result = -1
createList max listOfValues result | smaller listOfValues > max = -1
| higher listOfValues > max = createList max (remove (higher listOfValues) listOfValues) result
| otherwise = createList (max - higher listOfValues) listOfValues (insert (higher listOfValues) result)
higher [a] = a
higher (a:b:x) | a > b = higher (a:x)
| otherwise = higher (b:x)
smaller [a] = a
smaller (a:b:x) | a < b = smaller (a:x)
| otherwise = smaller (b:x)
remove x [] = []
remove x (h:t) | x == h = remove x t
| otherwise = h : remove x t
insert x (h:t) = x : h : t
In the two lines where i'll returning "-1" should be the parameter "result", but if i change "-1" to "result" the code don't load on ghci.
Can someone help me?
Thank you and sorry for my bad english.
If I may begin with a bit of a side note, some of your functions already exist in Haskell (now that I come to think of it you might have written them for an exercise, but just in case it wouldn't be the case, let's discuss that): your higher is maximum, your smaller is minimum and your insert is just (:), beacause like you write it yourself insert x list = x:list. Note that your version will fail if you give it the empty list because the pattern matching is non-exhaustive. Also you could write remove in terms of filter: remove x list = filter (== x) list.
Now why doesn't your code load properly? ghci tells you:
• Non type-variable argument in the constraint: Num [a]
(Use FlexibleContexts to permit this)
• When checking the inferred type
solvingProblem :: forall a.
(Ord a, Num [a], Num a) =>
a -> [a] -> [a]
Which I agree is pretty cryptic, but what it's saying is that the return type of solvingProblem is a list of a and for some reason it is also an instance of the Num type class. The reason why it says it's an instance of Num is because one of the return value of solvingProblem is 0 which is a number, which is a bit odd because it is also a list. Changing the 0 with [] makes the code compile and work (if you change insert with (:) otherwise you get the non-exhaustive pattern matching I was talking about earlier).
λ> solvingProblem 103 [15,20, 5, 45, 34]
[5,5,45,45]
it :: (Ord t, Num t) => [t]
The problem is with the last guard clause in createList.
The type you intended for createList seems to be:
createList :: Int -> [Int] -> Int -> Int
but if you look at the last guard clause you have:
| otherwise = createList (max - ...) listOfValues (insert ...)
^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^
Int [Int] [Int]
Even though GHC is very good at inferring types, always adding
type signatures to your code is a good way of catching these kinds
of errors early.
I'm learning ocaml and I'm trying to write easy function which prints out firsts given as argument int's.
What I have wrote:
let rec take(number, lista)=
let rec take_acc(number, lista, acc)=
match number with
| 0 -> []
| number < 0 -> []
| number > lista.length -> lista
| number < lista.length -> take_acc(number-1, lista.tl, acc#lista.head);;
take_acc(number, lista, [])
let listas = 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: [];;
take(2,listas);;
The point is, that given code above gives me error:
Error: Unbound value take
What I'm doing wrong?
The point is that this code works:
let xxl = 11 :: 33 :: 54 :: 74 :: [];;
let rec take2 (ile,xxx) =
if ile=0 || ile<0 then []
else
if ile>(List.length xxl) then take2(ile-1,xxx)
else
List.hd xxx :: take2(ile-1,List.tl xxx);;
Where is difference beetwen these two programs?
EDIT:
Due to Jeffrey Scofield's suggestion I have written something like this:
let rec take2(ilosc, lista) =
let rec take_acc(ilosc, lista, acc) =
if ilosc = 0 || ilosc < 0 then []
else
if ilosc > List.length lista
then lista
else
take_acc(ilosc-1, lista.tl, acc#lista.hd);;
let listas = 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: [];;
take2(2,listas);;
Still the same.
Your code is not syntactically well formed. So it couldn't ever reach the point of saying that take isn't defined.
The first thing to fix is your use of patterns. The construct number < 0 isn't a pattern, it's a boolean expression. You can have a boolean as part of a pattern using when:
| _ when number < 0
However, this isn't particulary good style for what you want to test. It might be better just to use if for your tests.
The next thing to fix might be your use of lista.length. The way to get the length of a list in OCaml is List.length lista.