I'm a beginner of Haskell and I'm trying to divide a list into two sublists with approximate equal size. The module can be loaded but when I tried to run ghci, it does not work.
For example:
divideList [1,2,3,4] = [1,2] [3,4] divideList [1,2,3,4,5] = [1,2,3] [4,5]
divideList [] = ([],[])
divideList [x] = ([x],[])
divideList ((x:xs):ys) = if a < b
then splitAt (a+1) ((x:xs):ys)
else divideList (xs:ys)
where a = length xs
b = length ys
It said that "No instance for (Num[t0]) arising from the literal '2'". I don't know how to fix it. Can anyone help me??? Thanks!
Here's the error indicated when I typed divideList [2,3,5] in ghci.
<interactive>:2:13:
No instance for (Num[a0]) arising from literal '2'
Possible fix: add an instance declaration for (Num[a0])
In the expression: 2
In the first argument of 'divideList', namely "[2,3,5]
In the expression: divideList [2,3,5]
First off: Dude, where's my {formatting, type signatures}?
Second: The error you are talking about indicates you have used a numeric literal (ex: 1) in a place where the types say the value should be a list. Because interpreting literals is flexible (polymorphic), the type checker complains that you need to tell it how to interpret a number as list.
Third: The posted code (reformatted and provided a type signature below) does not produce the error you claim.
Fourth: The posted code does not perform the task you describe - the type signature alone is a strong hint - the function you described should take lists to pairs of lists ([a] -> ([a],[a]) but you defined a function that consumes lists of lists ([[a]] -> ([[a]],[[a]]))...
divideList :: [[a]] -> ([[a]], [[a]])
divideList [] = ([],[])
divideList [x] = ([x],[])
divideList ((x:xs):ys) =
if a < b
then splitAt (a+1) ((x:xs):ys)
else divideList (xs:ys)
where a = length xs
b = length ys
As Thomas says, if you write out the type signature before you write the implementation, it should generally give you a greater feel for what you want your code to be doing.
If I'm correct in understanding your code, you were intending on starting from the left of the provided list, and advancing through until the left-hand side of the list is greater than or equal to in size as the right hand side, at which point you split it.
If this is the case, then there are a couple of bugs in your code:
Your current logic is if a < b then split, where a = length xs (supposed left-hand side) and b = length ys (supposed right-hand side). Assuming you start from the left, the left-hand side will be smaller than the right hand side to begin with! So in this case, you should probably have a > b instead.
Your use of pattern matching is incorrect - (x:xs):ys means "take the first element of the list as (x:xs), which is a single element x plus the rest of the list xs, then the rest as ys". So this pattern matching is trying to turn the first element of the list (2) into a list so it can extract (x:xs) from it, which is where your error is coming from.
If you wish to split the list roughly in half, I would simply do something more like
mySplit list = splitAt ((length list) `div` 2) list
which is much simpler :)
Related
I'm making some exercise to practice my Haskell skills. My task is to implement the Haskell function find by myself with the filter function.
I already implemented the find function without the filter function (see codeblock below) but now my problem is to implement it with filter function.
-- This is the `find` function without `filter` and it's working for me.
find1 e (x:xs)= if e x then x
else find1 e xs
-- This is the find function with the filter function
find2 e xs = filter e xs
The result of find1 is right
*Main> find1(>4)[1..10]
Output : [5].
But my actual task to write the function with filter gives me the
*Main> find2(>4)[1..10]
Output : [5,6,7,8,9,10].
My wanted result for find2 is the result of find1.
To "cut a list" to only have one, head element in it, use take 1:
> take 1 [1..]
[1]
> take 1 []
[]
> take 1 $ find2 (> 4) [1..10]
[5]
> take 1 $ find2 (> 14) [1..10]
[]
If you need to implement your own take 1 function, just write down its equations according to every possible input case:
take1 [] = []
take1 (x:xs) = [x]
Or with filter,
findWithFilter p xs = take1 $ filter p xs
Your find1 definition doesn't correspond to the output you show. Rather, the following definition would:
find1 e (x:xs) = if e x then [x] -- you had `x`
else find1 e xs
find1 _ [] = [] -- the missing clause
It is customary to call your predicate p, not e, as a mnemonic device. It is highly advisable to add type signatures to all your top-level definitions.
If you have difficulty in writing it yourself you can start without the signature, then ask GHCi which type did it infer, than use that signature if it indeed expresses your intent -- otherwise it means you've coded something different:
> :t find1
find1 :: (t -> Bool) -> [t] -> [t]
This seems alright as a first attempt.
Except, you actually intended that there would never be more than 1 element in the output list: it's either [] or [x] for some x, never more than one.
The list [] type is too permissive here, so it is not a perfect fit.
Such a type does exist though. It is called Maybe: values of type Maybe t can be either Nothing or Just x for some x :: t (read: x has type t):
import Data.Maybe (listToMaybe)
find22 p xs = listToMaybe $ filter p xs
We didn't even have to take 1 here: the function listToMaybe :: [a] -> Maybe a (read: has a type of function with input in [a] and output in Maybe a) already takes at most one element from its input list, as the result type doesn't allow for more than one element -- it simply has no more room in it. Thus it expresses our intent correctly: at most one element is produced, if any:
> find22 (> 4) [1..10]
Just 5
> find22 (> 14) [1..10]
Nothing
Do add full signature above its definition, when you're sure it is what you need:
find22 :: (a -> Bool) -> [a] -> Maybe a
Next, implement listToMaybe yourself. To do this, just follow the types, and write equations enumerating the cases of possible input, producing an appropriate value of the output type in each case, just as we did with take1 above.
I have started to solve the 99 problems in Haskell, and for the second question, it is given the following solution:
myButLast' :: [a] -> a
myButLast' = last . init
and if we give the empty list to this function, we get and error, however, I would like to print a specific error as
myButLast' [] = error "The list has to have at least 2 elements!"
myButLast' [x] = error "The list has to have at least 2 elements!"
but when I add these line to the code, I get
Equations for ‘myButLast'’ have different numbers of arguments
, so is there a way to use the composition type of defining my new function while also adding some specific behaviour ?
The best you can do is probably something like the following, where the error checking is moved into an auxiliary function (which I've named go for lack of a better name) defined in a where clause:
myButLast :: [a] -> a
myButLast = go (last . init)
where
go _ [] = bad
go _ [x] = bad
go f xs = f xs
bad = error "The list has to have at least 2 elements!"
It might help make it clearer what's going on if we define go separately with a type signature. Also, in case you find the underscores confusing, I've replaced them with f:
myButLast :: [a] -> a
myButLast = go (last . init)
go :: ([a] -> a) -> [a] -> a
go f [] = bad
go f [x] = bad
go f xs = f xs
bad = error "The list has to have at least 2 elements!"
Here, you can see that go is a function that takes two arguments, the first being itself a function of type [a] -> a and the second being a list of type [a].
The above definition of go pattern matches on the second argument (the list). If the list is empty or a singleton, then the result of go is just bad (the error message), regardless of the function f. Otherwise (if the list is at least two elements), the result of go f xs is simply to apply the first argument (that function f) to the list xs.
How does this work? Well, let's see what happens if we apply myButLast to a list. I've used the symbol "≡" here to show equivalence of Haskell expressions with comments explaining why they are equivalent:
myButLast [1,2,3]
-- by the definition of "myButLast"
≡ go (last . init) [1,2,3]
-- by the definition of "go", third pattern w/
-- f ≡ last . init
-- xs = [1,2,3]
≡ (last . init) [1,2,3] -- this is just f xs w/ the pattern substitutions
-- because of your original, correct answer
≡ 2
If we apply it to a "bad" list, the only difference is the pattern matched from the definition of go:
myButLast [1]
-- by the definition of "myButLast"
≡ go (last . init) [1]
-- by the definition of "go", second pattern w/
-- f ≡ last . init
-- x = 1
≡ bad
-- gives an error message by definition of "bad"
As an interesting aside, another way to look at go is that it's a function:
go :: ([a] -> a) -> ([a] -> a)
Because the function application arrow -> is right associative, this type signature is exactly the same as ([a] -> a) -> [a] -> a. The neat thing about this is that now it's clear that go takes a function of type [a] -> a (such as last . init) and returns another function of type [a] -> a (such as myButLast). That is, go is a transformer that adds additional behavior to an existing function to create a new function, which is exactly what you were asking for in your original question.
In fact, if you slightly generalize the type signature so that go can operate on a function taking a list, regardless of what it returns:
go :: ([a] -> b) -> [a] -> b
go _ [] = bad
go _ [x] = bad
go f xs = f xs
this still works. Then, you could use this same go on anything that needed a list of length two, whatever it returned. For example, if you had an original implementation to return the last two elements of a list:
lastTwoElements :: [a] -> [a]
lastTwoElements = (!! 2) . reverse . tails -- tails from Data.List
you could re-write it as:
lastTwoElements :: [a] -> [a]
lastTwoElements = go ((!! 2) . reverse . tails)
to add error handling for the empty and singleton list cases.
In this case, you'd probably want to rename go to usingTwoElements or withList2 or something...
Use an explicit argument in the solution:
myButLast' x = last (init x)
Now you can add your special cases just above that line.
The original solution used a pointfree style last . init to avoid mentioning the x argument. However, if you have to add further equations, you need to make the argument explicit.
Moving from
fun :: A -> B
fun = something
to
fun :: A -> B
fun a = something a
is called eta-expansion, and is a common transformation of Haskell code. The first style is usually called point-free (or, jokingly, point-less), while the second one is called pointful. Here "point" refers to the variable a.
Somewhat sidestepping the original question, but you may be interested in the safe package for tasks like this. In general, you should strive to use total functions that don't raise errors. In this case, that means using something like lastMay :: [a] -> Maybe a and initMay :: [a] -> Maybe a, which simply return Nothing if given an empty list. They can be composed using <=<, found in Control.Monad.
import Safe
myButLast :: [a] -> Maybe a
myButLast = lastMay <=< initMay
Then
> myButLast []
Nothing
> myButLast [1]
Nothing
> myButLast [1,2]
Just 1
If you really want an error message, Safe provides lastNote and initNote as well.
myButLast = let msg = "Need at least 2 elements" in (lastNote msg . initNote msg)
You could often simply compose an additional function that has the additional behaviour:
myButLast' :: [a] -> a
myButLast' = last . init . assertAtLeastTwo
where assertAtLeastTwo xs#(_:_:_) = xs
assertAtLeastTwo _ = error "The list has to have at least 2 elements!"
Here we've added a function that checks for the conditions we want to raise an error, and otherwise simply returns its input so that the other functions can act on it exactly as if assertAtLeastTwo wasn't there.
Another alternative that allows you to clearly highlight the error conditions is:
myButLast' :: [a] -> a
myButLast' [] = error "The list has to have at least 2 elements!"
myButLast' [x] = error "The list has to have at least 2 elements!"
myButLast' xs = go xs
where go = last . init
Where you do the error checking as you originally wrote, but have the main definition simply defer to an implementation function go, which can then be defined point-free using composition.
Or you can of course inline go from above, and have:
myButLast' xs = (last . init) xs
Sine a composition of functions is itself an expression, and can simply be used in a larger expression directly as the function. In fact a fairly common style is in fact to write code of the form "compose a bunch of functions then apply to this argument" this way, using the $ operator:
myButLast' xs = last . init $ xs
If you would use wrappers you can have the best of both worlds and a clear separation between the two. Robust error checking and reporting and a vanilla function to use however you wish, with or without the wrapper.
Interesting, the vanilla function reports 'last' cannot process an empty list given a one element list and 'init' cannot process an empty list when given an empty list.
mbl2 = last . init
mbl xs = if length xs < 2 then error errmsg else mbl2 xs
where errmsg = "Input list must contain at least two members."
I just started learning Haskell and I'm trying to define the "Get n'th element of list" (with the !! operator) in a function which uses foldl. I now defined it without foldl, just making use of recursion. I wondered if anybody could tell me how to change the code I have to a function with foldl, and could describe what is happening. Thanks in advance!
get 1 (x:_) = x
get i (_:xs) = elementAt'' (i - 1) xs
A couple of notes:
First note that you want get 1 to return the first element in your list, that's not the common choice in many languages including Haskell ([2, 3, 5] !! 1 = 3).
Second, although elementAt is a recursive function over lists, it can be defined more efficiently in the old fashion recursive way. fold functions are not good choices here, because fold goes through every element of the list. But we want elementAt recursion to stop the moment that we find the element.
Given this, here is how you can implement elementAt recursively:
elementAt :: Int -> [a] -> a
elementAt i (x:xs) = if i == 1 then x else elementAt (i-1) xs
And here's the implementation using foldl:
elementAt' :: Int -> [a] -> a
elementAt' i (x:xs) =
snd $
foldl
(\(j, a) b ->
if j < 1 then (j-1, a) else (j-1, b))
(i-1, x)
xs
The seed value of foldl is a tuple: (i-1, x) where x is the head of the list.
Note that the return result of fold functions must be of the same type of their seed. Hence here foldl returns a tuple: (j-1, a) where a is the final result, if the index is found; otherwise (j-1, b) where b is the current element of the list.
You can see how foldl goes through every element of the list even after it found the element at index that we were looking for (it keeps returning the previous result a that will be the final result).
PS. These elementAt functions are not handling the case for empty lists or when i is greater than the length of the list; hence they're not exhaustive.
I can see the following, a bit cryptic way of using foldl for your purpose (it is using zero-based indexing, but can be changed easily to 1-based):
get i lst=
snd $
foldl (\p (j, y) -> if j == i then (j,y) else p ) (0, 0) (zip [0,1..] lst)
The foldl part is working with tuples (index, element), whose list is generated by zipping the given list with indices list. The function passed to foldl as first argument is comparing the index of the desired element with the index with currently passed, and returning the current element if the index is matching, or the previous element otherwise. Then, in the end by using snd only the element part of the tuple is returned.
First time poster, but this site has helped me alot.
I am trying to learn Haskell.
This is the question i'm asked to answer.
Write a function that takes a list (length >=2) of pairs of length and returns the first component of the second element in the list. So, when provided with [(5,’b’), (1,’c’), (6,’a’)], it will return 1.
I have done this myself.
listtwo :: [([a],b)] -> [a]
listtwo [] = []
listtwo [(a,b)] = fst (head (tail [(a,b)]))
I am trying to take a list of lists tuples I believe and return the 1st element from the 2nd item in the list. I know if you take out the [(a,b)]'s and replace the second [(a,b)] with a list like the one in the question it works fine. But when I try to make this function work for ANY list of tuples. I get errors.
Error I recieve
<interactive>:1:27:
No instance for (Num [a0])
arising from the literal `6'
Possible fix: add an instance declaration for (Num [a0])
In the expression: 6
In the expression: (6, 'a')
In the first argument of `listtwo', namely
`[(5, 'b'), (1, 'c'), (6, 'a')]'
So i'm asking if anyone can help me deciver the errors and mabye explain what I am doing wrong (don't give me the answer, cant learn that way).
Appriciate the help, might have more questions if this gets answered. Thank you very much in advance!
You say that you want a function that returns the first component of the second element of the list. The best way to write this function will be by pattern matching. But first, let's think about its type.
Say you want a list of tuples of (Int,Char). This is written as [(Int,Char)]. If you want a list of 2-tuples of arbitrary type, you replace the types Int and Char with type variables, so you end up with the type [(a,b)].
Your function needs to take something of this type, and return the first component of the second element of the list. All of the first components of the tuples have type a, so your return type must be a as well. So your function's type signature is
f :: [(a,b)] -> a
Now, how do we write this function? The best way is to use pattern matching. This is a neat way to extract the components of a data structure without having to use accessors (aka getters, if you come from an object-oriented background). Let's say we have a function g :: [a] -> a which returns the third component of a list. You could write
g :: [a] -> a
g xs = head (tail (tail xs))
but that looks pretty nasty. Another way is to pattern match. A list with three elements [x,y,z] can be constructed by doing x : y : z : [] where x, y and z are all of type a (remember that the operator : adds items to the front of a list). So we can write:
g :: [a] -> a
g (x : y : z : []) = z
But there's a problem with this - it only works on lists of length three, because our pattern says "Match a list of three elements with the empty list tacked on the end." Instead, we could use the pattern x : y : z : rest, where now rest matches the rest of the list:
g :: [a] -> a
g (x : y : z : rest) = z
where our pattern now says "Match a list of three elements followed by anything else at all." In fact, we can make it simpler. We aren't going to use the values x, y or rest so we can replace them with the Haskell pattern _ (underscore). This matches anything, and makes us promise that we aren't going to use that value:
g :: [a] -> a
g (_ : _ : z : _) = z
How can we use this to solve your problem? Well, if you had a list matching the pattern (w,x) : (y,z) : rest you would want to return y. So you can write:
f :: [(a,b)] -> a
f ( (w,x) : (y,z) : rest ) = y
which will work fine. However, you don't care about the first pair at all, so you can replace (w,x) with _. You also don't care about the second element of the second tuple or the rest of the list, so you can replace them with _ as well, getting:
f :: [(a,b)] -> a
f ( _ : (y,_) : _) = y
Checking it in ghci:
ghci> f [(5,'b'),(1,'c'),(6,'a')]
1
So it behaves as you expected it to.
So I have the following function:
chk2 :: [(Integer,Integer)] -> Either [(Integer,Integer)] (Integer,Integer)
chk2 i#((n,_):_)
| chkp (prod $ lgst i)==True = Right $ lgst i
| lgst i==i!!0 = Left $ chk2 $ (4-2,4-2):next i
| otherwise = Left $ chk2 $ next i
where prod (a,b) = a*b
lgst = foldl1 (\(a,b) (c,d) -> if prod (a,b) > prod (c,d) then (a,b) else (c,d))
next t = map (\(a,b) -> if (a,b)==lgst t then (a-1,b+1) else (a,b)) t
along with this error:
runhugs: Error occurred
ERROR "4/4.hs":14 - Type error in explicitly typed binding
*** Term : chk2
*** Type : [(Integer,Integer)] -> Either (Either [(Integer,Integer (Integer,Integer)) (Integer,Integer)
*** Does not match : [(Integer,Integer)] -> Either [(Integer,Integer)] (Integer,Integer)
I'm trying to get this function to either end up with an (a,b) i.e. first guard or [(a,b)] i.e. the latter two guards. The basic problem is in the latter two guards.. if I take out the recursion, everything works fine, but I'm not sure how to define the type signature when returning the function itself.
The problem is with how you recurse.
According to the type of chk2, chk2 $ next i is of type Either [(Integer,Integer)] (Integer,Integer). Left is of type b -> Either b a, so Left $ chk2 $ next i is of type Either (Either [(Integer,Integer)] (Integer,Integer)) a for some unspecified type a.
Left $ chk2 $ (4-2,4-2):next i has a similar problem.
To fix, you need to decide how you want to handle the recursive value.
Easy fix:
| lgst i==i!!0 = chk2 $ (4-2,4-2):next i
| otherwise = chk2 $ next i
However, I doubt this is what you want, since it means all your results will be Right.
I'm not sure how to do what you want, because I'm not sure what you want.
What does a list result mean? What does a non-list result mean?
What you probably want to do is pattern match the result of the recursion, transforming Right pair -> Left [pair], perhaps appending some other result to the front.
As an example, I'll construct a recursive function with a similar type signature. Let foo be a function that takes a list of integers, and:
if the first element of the list is the maximum of the whole list, returns that element
otherwise, return a subsequence of the list, where each is the maximum of all the elements between it and the next element in the subsequence (or the end)
To do this:
foo :: [Integer] -> Either [Integer] Integer
foo [] = Left []
foo (x:xs) = case foo xs of
Left ys -> if all (<=x) ys
then Right x
else let (_,ys') = break (>x) ys in Left (x:ys')
Right y -> if x >= y
then Right x
else Left [x,y]
Note how I use case to pattern match on the result of the recursive call to foo.
To solve Euler #4, yours seems to be a very awkward style for Haskell. It's usually a bad idea to try and "port" code from other languages into Haskell, since the paradigm for Haskell is so very different.
You'll find a very clean, sensible solution to Euler #4 that uses list comprehensions at the Haskell Wiki. Certainly not the only solution, but it is at least 20x as readable as your current code. No offense.
I (and tons of other Haskellers) highly recommend Learn You a Haskell and Real World Haskell for learning how to approach problems the Haskell way, which in my experience is usually to create small, simple helper methods and compose them into a solution.