Using Either correctly - haskell

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.

Related

How to implement the function find with the filter function?

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.

Defining new function as a composition of functions while adding additional behaviours

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."

How can I replace generators if I need only one result?

I'm playing with Haskell for first time.
I've created function that returns first precise enough result. It works as expected, but I'm using generator for this. How can I replace generator in this task?
integrateWithPrecision precision =
(take 1 $ preciseIntegrals precision) !! 0
preciseIntegrals :: Double -> [Double]
preciseIntegrals precision =
[
integrate (2 ^ power) pi | power <- [0..],
enoughPowerForPrecision power precision
]
You can use the beautiful until function. Here it is:
-- | #'until' p f# yields the result of applying #f# until #p# holds.
until :: (a -> Bool) -> (a -> a) -> a -> a
until p f x | p x = x
| otherwise = until p f (f x)
So, you can write your function like this:
integrateWithPrecision precision = integrate (2 ^ pow) pi
where
pow = until done succ 0
done pow = enoughPowerForPrecision pow precision
In your case, you do all the iteration and then compute a result just once. But until is useful even when you need to compute a result at each step - just use an (iter, result) tuple and then just extract the result at the end with snd.
It seems like you want to check higher and higher powers until you get one that satisfies a requirement. This is what you could do: First you define a function to get enough power, and then you integrate using that.
find gets the first element of a list that satisfies a condition – like being enough of a power! Then we need a fromJust to get the actual value from that. Please note that almost always, fromJust is a terrible idea to have in your code. However, in this case the list is infinite, so we will have troubles with infinite loops long before fromJust is able to crash the program.
enoughPower :: Double -> Int
enoughPower precision =
fromJust $ find (flip enoughPowerForPrecision precision) [0..]
preciseIntegrals :: Double -> Double
preciseIntegrals precision = integrate (2^(enoughPower precision)) pi
The function
\xs -> take 1 xs !! 0
is called head
head [] = error "Cannot take head of empty list"
head (x:xs) = x
Its use is somewhat unsafe, as shown it can throw an error if you pass it an empty list, but in this case since you can be certain your list is non-empty it's fine.
Also, we tend not to call these "generators" in Haskell as they're not a special form but are instead a simple consequence of lazy evaluation. In this case, preciseIntegrals is called a "list comprehension" and [0..] is nothing more than a lazily generated list.

No instance for (Num[t0]) arising from the literal '2' (Haskell)

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

When destructuring tuples in Haskell, where can the elements be used?

I am reading a tutorial that uses the following example (that I'll generalize somewhat):
f :: Foo -> (Int, Foo)
...
fList :: Foo -> [Int]
fList foo = x : fList bar
where
(x, bar) = f foo
My question lies in the fact that it seems you can refer to x and bar, by name, outside of the tuple where they are obtained. This would seem to act like destructuring parameter lists in other languages, if my guess is correct. (In other words, I didn't have to do the following:)
fList foo = (fst tuple) : fList (snd tuple)
where
tuple = f foo
Am I right about this behavior? I've never seen it mentioned yet in the tutorials/books I've been reading. Can someone point me to more info on the subject?
Edit: Can anything (lists, arrays, etc.) be destructured in a similar way, or can you only do this with tuples?
Seeing your edit, I think what your asking about is Pattern matching.
And to answer your question: Yes, anything you can construct, you can also 'deconstruct' using the constructors. For example, you're probably familiar with this form of pattern matching:
head :: [a] -> a
head (x:xs) = x
head [] = error "Can't take head of empty list"
However, there are more places where you can use pattern matching, other valid notations are:
head xs = case xs of
(y:ys) -> y
[] -> error "Can't take head of empty list"
head xs = let (y:ys) = xs
in y
head xs = y
where
(y:ys) = xs
Note that the last two examples are a bit different from the first to because they give different error messages when you call them with an empty list.
Although these examples are specific to lists, you can do the same with other data types, like so:
first :: (a, b) -> a
first tuple = x
where
(x, y) = tuple
second :: (a, b) -> b
second tuple = let (x, y) = tuple
in y
fromJust :: Maybe a -> a
fromJust ma = x
where
(Just x) = ma
Again, the last function will also crash if you call it with Nothing.
To sum up; if you can create something using constructors (like (:) and [] for lists, or (,) for tuples, or Nothing and Just for Maybe), you can use those same constructors to do pattern matching in a variety of ways.
Am I right about this behavior?
Yes. The names exist only in the block where you have defined them, though. In your case, this means the logical unit that your where clause is applied to, i.e. the expression inside fList.
Another way to look at it is that code like this
x where x = 3
is roughly equivalent to
let x = 3 in x
Yes, you're right. Names bound in a where clause are visible to the full declaration preceding the where clause. In your case those names are f and bar.
(One of the hard things about learning Haskell is that it is not just permitted but common to use variables in the source code in locations that precede the locations where those variables are defined.)
The place to read more about where clauses is in the Haskell 98 Report or in one of the many fine tutorials to be found at haskell.org.

Resources