Compiler cannot decide the type of the return value of `take` function - haskell

I'm trying to solve the 99 problems in Haskell, and for the 4th question, I have first tried such a solution
myLength :: [a] -> Int
myLength [] = 0
myLength ys = go 1 ys
where
go :: Int -> [a] -> Int
go n xs
| ( (take n xs) == (take (n+1) xs) ) = n
| otherwise = go (n+1) xs
However, the compiler gives the error:
Problem4.hs:10:8: error:
• No instance for (Eq a1) arising from a use of ‘==’
Possible fix:
add (Eq a1) to the context of
the type signature for:
go :: forall a1. Int -> [a1] -> Int
• In the expression: ((take n xs) == (take (n + 1) xs))
In a stmt of a pattern guard for
an equation for ‘go’:
((take n xs) == (take (n + 1) xs))
In an equation for ‘go’:
go n xs
| ((take n xs) == (take (n + 1) xs)) = n
| otherwise = go (n + 1) xs
|
10 | | ( (take n xs) == (take (n+1) xs) ) = n
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
As far as I understood, the reason for the error it that when we try to compare the lists returned from (take n xs) and (take (n+1) xs), the compiler does not know the types of lists in advance, so it cannot compare them, and this is why it complains, so before this line, I need to tell the compiler that both return values are the same type, and the type is [a], but how can we do that ?
A confusion: when we specify the type signature of go, we are explicitly fixing the what is the type of xs, i.e so shouldn't the list that is return by the function take have the same type, namely [a], hence shouldn't the compiler be able to compare them ?
Edit:
Note that, I have another function in the definition of a function, and there are lots of things that are different from the question that is marked as duplicate, and as you can observe, the given answer to that question does not fully solves this question.

What you need is instance contexts (here Eq a), which is indicated by =>:
myLength :: Eq a => [a] -> Int
myLength [] = 0
myLength ys = go 1 ys
where
go :: Eq a => Int -> [a] -> Int
go n xs
| ( (take n xs) == (take (n+1) xs) ) = n
| otherwise = go (n+1) xs
But this is not a proper answer to the question #4, because it adds an additional constraint to the function.
EDIT: For the question "Shouldn't every list be equality comparable?":
Lists are comparable iff their elements are comparable. For example, functions, Kleisli arrows, WrappedArrows are not equality comparable, so aren't lists of them.

{-# Language ScopedTypeVariables #-}
myLength :: forall a. Eq a => [a] -> Int
myLength [] = 0
myLength ys = go 1 ys
where
go :: Int -> [a] -> Int
go n xs
| take n xs == take (n+1) xs = n
| otherwise = go (n+1) xs

Related

create a function ved that will only remove the last occurrence of the largest item in the list using recursion

You must use recursion to define rmax2 and you must do so from “scratch”. That is, other than the cons operator, head, tail, and comparisons, you should not use any functions from the Haskell library.
I created a function that removes all instances of the largest item, using list comprehension. How do I remove the last instance of the largest number using recursion?
ved :: Ord a => [a] -> [a]
ved [] =[]
ved as = [ a | a <- as, m /= a ]
where m= maximum as
An easy way to split the problem into two easier subproblems consists in:
get the position index of the rightmost maximum value
write a general purpose function del that eliminates the element of a list at a given position. This does not require an Ord constraint.
If we were permitted to use regular library functions, ved could be written like this:
ved0 :: Ord a => [a] -> [a]
ved0 [] = []
ved0 (x:xs) =
let
(maxVal,maxPos) = maximum (zip (x:xs) [0..])
del k ys = let (ys0,ys1) = splitAt k ys in (ys0 ++ tail ys1)
in
del maxPos (x:xs)
where the pairs produced by zip are lexicographically ordered, thus ensuring the rightmost maximum gets picked.
We need to replace the library functions by manual recursion.
Regarding step 1, that is finding the position of the rightmost maximum, as is commonly done, we can use a recursive stepping function and a wrapper above it.
The recursive step function takes as arguments the whole context of the computation, that is:
current candidate for maximum value, mxv
current rightmost position of maximum value, mxp
current depth into the original list, d
rest of original list, xs
and it returns a pair: (currentMaxValue, currentMaxPos)
-- recursive stepping function:
findMax :: Ord a => a -> Int -> Int -> [a] -> (a, Int)
findMax mxv mxp d [] = (mxv,mxp)
findMax mxv mxp d (x:xs) = if (x >= mxv) then (findMax x d (d+1) xs)
else (findMax mxv mxp (d+1) xs)
-- top wrapper:
lastMaxPos :: Ord a => [a] -> Int
lastMaxPos [] = (-1)
lastMaxPos (x:xs) = snd (findMax x 0 1 xs)
Step 2, eliminating the list element at position k, can be handled in very similar fashion:
-- recursive stepping function:
del1 :: Int -> Int -> [a] -> [a]
del1 k d [] = []
del1 k d (x:xs) = if (d==k) then xs else x : del1 k (d+1) xs
-- top wrapper:
del :: Int -> [a] -> [a]
del k xs = del1 k 0 xs
Putting it all together:
We are now able to write our final recursion-based version of ved. For simplicity, we inline the content of wrapper functions instead of calling them.
-- ensure we're only using authorized functionality:
{-# LANGUAGE NoImplicitPrelude #-}
import Prelude (Ord, Eq, (==), (>=), (+), ($), head, tail,
IO, putStrLn, show, (++)) -- for testing only
ved :: Ord a => [a] -> [a]
ved [] = []
ved (x:xs) =
let
findMax mxv mxp d [] = (mxv,mxp)
findMax mxv mxp d (y:ys) = if (y >= mxv) then (findMax y d (d+1) ys)
else (findMax mxv mxp (d+1) ys)
(maxVal,maxPos) = findMax x 0 1 xs
del1 k d (y:ys) = if (d==k) then ys else y : del1 k (d+1) ys
del1 k d [] = []
in
del1 maxPos 0 (x:xs)
main :: IO ()
main = do
let xs = [1,2,3,7,3,2,1,7,3,5,7,5,4,3]
res = ved xs
putStrLn $ "input=" ++ (show xs) ++ "\n" ++ " res=" ++ (show res)
If you are strictly required to use recursion, you can use 2 helper functions: One to reverse the list and the second to remove the first largest while reversing the reversed list.
This result in a list where the last occurrence of the largest element is removed.
We also use a boolean flag to make sure we don't remove more than one element.
This is ugly code and I really don't like it. A way to make things cleaner would be to move the reversal of the list to a helper function outside of the current function so that there is only one helper function to the main function. Another way is to use the built-in reverse function and use recursion only for the removal.
removeLastLargest :: Ord a => [a] -> [a]
removeLastLargest xs = go (maximum xs) [] xs where
go n xs [] = go' n True [] xs
go n xs (y:ys) = go n (y:xs) ys
go' n f xs [] = xs
go' n f xs (y:ys)
| f && y == n = go' n False xs ys
| otherwise = go' n f (y:xs) ys
Borrowing the implementation of dropWhileEnd from Hackage, we can implement a helper function splitWhileEnd:
splitWhileEnd :: (a -> Bool) -> [a] -> ([a], [a])
splitWhileEnd p = foldr (\x (xs, ys) -> if p x && null xs then ([], x:ys) else (x:xs, ys)) ([],[])
splitWhileEnd splits a list according to a predictor from the end. For example:
ghci> xs = [1,2,3,4,3,2,4,3,2]
ghci> splitWhileEnd (< maximum xs) xs
([1,2,3,4,3,2,4],[3,2])
With this helper function, you can write ven as:
ven :: Ord a => [a] -> [a]
ven xs =
let (x, y) = splitWhileEnd (< maximum xs) xs
in init x ++ y
ghci> ven xs
[1,2,3,4,3,2,3,2]
For your case, you can refactor splitWhileEnd as:
fun p = \x (xs, ys) -> if p x && null xs then ([], x:ys) else (x:xs, ys)
splitWhileEnd' p [] = ([], [])
splitWhileEnd' p (x : xs) = fun p x (splitWhileEnd' p xs)
ven' xs = let (x, y) = splitWhileEnd' (< maximum xs) xs in init x ++ y
If init and ++ are not allowed, you can implement them manually. It's easy!
BTW, I guess this may be your homework for Haskell course. I think it's ridiculous if your teacher gives the limitations. Who is programming from scratch nowadays?
Anyway, you can always work around this kind of limitations by reimplementing the built-in function manually. Good luck!

Creating a safe version of Haskell 'init' function

I'm working my way through "Real World Haskell," and the assignment is to make safe versions of head, tail, last, and init. I've succeeded on the first three, but the Maybe typeclass is killing me on init.
Here is my code:
-- safeInit
safeInit :: [a] -> Maybe [a]
safeInit [] = Nothing
safeInit (x:xs) = if null xs
then Just [x]
else x : (safeInit xs)
And here are the resultant errors on loading into GHCI (the function starts on line 23 of the original file:
[1 of 1] Compiling Main ( ch04.exercises.hs, interpreted )
> ch04.exercises.hs:27:26: error:
> • Couldn't match expected type ‘Maybe [a]’ with actual type ‘[a]’
> • In the expression: x : (safeInit xs)
> In the expression: if null xs then Just [x] else x : (safeInit xs)
> In an equation for ‘safeInit’:
> safeInit (x : xs) = if null xs then Just [x] else x : (safeInit xs)
> • Relevant bindings include
> xs :: [a] (bound at ch04.exercises.hs:25:13)
> x :: a (bound at ch04.exercises.hs:25:11)
> safeInit :: [a] -> Maybe [a] (bound at ch04.exercises.hs:24:1) | 27 | else x : (safeInit xs) |
> ^^^^^^^^^^^^^^^^^
>
> ch04.exercises.hs:27:31: error:
> • Couldn't match expected type ‘[a]’ with actual type ‘Maybe [a]’
> • In the second argument of ‘(:)’, namely ‘(safeInit xs)’
> In the expression: x : (safeInit xs)
> In the expression: if null xs then Just [x] else x : (safeInit xs)
> • Relevant bindings include
> xs :: [a] (bound at ch04.exercises.hs:25:13)
> x :: a (bound at ch04.exercises.hs:25:11)
> safeInit :: [a] -> Maybe [a] (bound at ch04.exercises.hs:24:1) | 27 | else x : (safeInit xs) |
> ^^^^^^^^^^^ Failed, no modules loaded.
Any way I mark or don't mark either the x or xs on the last two lines with Just, I get different, but very much related, typing errors. What subtlety on using the Maybe type with lists am I missing?
The main reason why this does not work is because your expression x : safeInit xs will not typecheck. Indeed, safeInit xs is a Maybe [a], but (:) has type (:) :: a -> [a] -> [a], so the types do not match.
There is also a semantical error. If null xs is True, then you should return Just [] instead of Just [x], since then x is the last element in the list.
You can make use of fmap :: Functor f => (a -> b) -> f a -> f b (so for f ~ Maybe, fmap is fmap :: (a -> b) -> Maybe a -> Maybe b), to alter a value that is wrapped in a Just:
safeInit :: [a] -> Maybe [a]
safeInit [] = Nothing
safeInit [_] = Just []
safeInit (x:xs) = fmap (x:) (safeInit xs)
but this will result in a lot of wrapping and unwrapping of values in a Just. It also means that for an infinite list, it will get stuck in an infinite loop. We can simply check if the list contains at least on element, and then perform the init logic as the result of a function we wrap in a Just:
safeInit :: [a] -> Maybe [a]
safeInit [] = Nothing
safeInit (x:xs) = Just (go xs x)
where go [] _ = []
go (x2:xs) x = x : go xs x2
One interesting problem is how to write safeInit in terms of foldr. Aside from the fun of the puzzle, this allows it to participate in the list fusion optimization in GHC as a "good consumer", which can improve performance in some cases. We start with the first (naive) version in Willem Van Onsem's answer:
safeInit0 :: [a] -> Maybe [a]
safeInit0 [] = Nothing
safeInit0 [_] = Just []
safeInit0 (x:xs) = fmap (x:) (safeInit0 xs)
The first problem with this is that it's not shaped quite like a fold: it has separate cases for [p] and for p:q:rs. A classic trick for patching this up is to pass a Maybe carrying the previous value in the list.
safeInit1 :: [a] -> Maybe [a]
safeInit1 xs0 = go xs0 Nothing
where
-- This first case only happens when
-- the whole list is empty.
go [] Nothing = Nothing
go [] (Just x) = Just [x]
go (x:xs) Nothing = go xs (Just x)
go (x:xs) (Just prev) = (prev:) <$> go xs (Just x)
The next problem is semantic: it doesn't work right with infinite or partially defined arguments. We want
safeInit [1..] = Just [1..]
but safeInit1 will diverge in this case, because fmap is necessarily strict in its Maybe argument. But it turns out there's a bit of information we can use: fmap will only be applied to a Just value in this case. Exercise: prove that.
We'll take advantage of that by representing Maybe [a] in a weird way as (Bool, [a]), where Nothing is represented as (False, []) and Just xs is represented as (True, xs). Now we can be lazier:
safeInit2 :: [a] -> Maybe [a]
safeInit2 xs = case helper2 xs of
(False, _) -> Nothing
(True, xs) -> Just xs
helper2 :: [a] -> (Bool, [a])
helper2 xs0 = go xs0 Nothing
where
go [] Nothing = (False, [])
go [] _ = (True, [])
go (x:xs) mb = case mb of
Nothing -> (True, rest)
Just p -> (True, p:rest)
where
rest = snd (go xs (Just x))
Now this has precisely the shape of a fold:
safeInit3 :: [a] -> Maybe [a]
safeInit3 xs = case helper3 xs of
(False, _) -> Nothing
(True, xs) -> Just xs
helper3 :: [a] -> (Bool, [a])
helper3 xs0 = foldr go stop x0 Nothing
where
stop Nothing = (False, [])
stop _ = (True, [])
go x r mb = case mb of
Nothing -> (True, rest)
Just p -> (True, p:rest)
where
rest = snd (r (Just x))
You might worry that all these intermediate Maybes and pairs will cause performance problems, but in fact GHC is able to optimize them all away, producing something very much like Willem Van Onsem's optimized implementation.

Couldn't match expected type `Int' with actual type `a'

import Data.List
data Tree a = Leaf a | Node (Tree a) a (Tree a) deriving Show
toTree :: Ord a => [a] -> Tree a
toTree xs = Node (balancedTree (take n xs')) (xs'!!n) (balancedTree (drop n xs'))
where
xs' = sort xs
n = middle xs
middle :: Num a => [a] -> a
middle xs = fromIntegral ((length xs `div` 2) + 1)
balancedTree :: Ord a => [a] -> Tree a
balancedTree (x:[]) = Leaf x
balancedTree xs = Node (balancedTree (take n xs')) (xs'!!n) (balancedTree (drop n xs'))
where
xs' = sort xs
n = middle xs
This is my code for converting from a list to a binary tree. I know there are many mistakes but I just want to get the types errors sorted before I start debugging. I get the following errors in both the "toTree" method and the "balancedTree" method as they are both really the same and will be condensed into one when the errors are sorted out.
ex7.hs:6:38: error:
* Couldn't match expected type `Int' with actual type `a'
`a' is a rigid type variable bound by
the type signature for:
toTree :: forall a. Ord a => [a] -> Tree a
at ex7.hs:5:1-32
* In the first argument of `take', namely `n'
In the first argument of `balancedTree', namely `(take n xs')'
In the first argument of `Node', namely
`(balancedTree (take n xs'))'
* Relevant bindings include
xs' :: [a] (bound at ex7.hs:8:9)
n :: a (bound at ex7.hs:9:9)
xs :: [a] (bound at ex7.hs:6:8)
toTree :: [a] -> Tree a (bound at ex7.hs:6:1)
|
6 | toTree xs = Node (balancedTree (take n xs')) (xs'!!n) (balancedTree (drop n xs'))
| ^
I have tried for hours to fix it by searching stackOverflow but I can't figure it out. The type declaration of "toTree" must stay the same. Also the definition of Tree should stay the same.
My understanding is that "take" required an "Int" and I am giving it an "a". I do not know how I can fix this.
The problem is that middle returns an a, not an Int. Indeed:
middle :: Num a => [a] -> a
middle xs = fromIntegral ((length xs `div` 2) + 1)
But in your balancedTree, you use it as if it is an index, and take n, drop n, and !! n require n to be an Int, indeed:
balancedTree :: Ord a => [a] -> Tree a
balancedTree (x:[]) = Leaf x
balancedTree xs = Node (balancedTree (take n xs')) (xs'!!n) (balancedTree (drop n xs'))
where
xs' = sort xs
n = middle xs
The type signature does not make much sense either. You can calculate the length over any list, not only from lists that consist out of numbers. You thus should construct a function that returns the index in the middle of the list and use that. For example:
middle :: [a] -> Int
middle = (length xs `div` 2) + 1
That being said, using length, etc. is usually not a good idea in Haskell. length requires O(n) time, and furthermore for infinite lists, it will get stuck in an infinite loop. Often if you use functions like length, there is a more elegant solution.
Instead of using a "top-down" approach, it might be better to look at a "bottom-up" approach, where you iterate over the items, and on the fly construct Leafs, and group these together in Nodes until you reach the top.

Implement the take function with list comprehension

How would you implement take with a list comprehension?
My approach so far:
take2 :: (Num i, Ord i) => i -> [a] -> [a]
take2 n xs = [x | x <- xs, [x..n]]
The fundamental reason why list comprehensions are not a good fit for the take function is this:
The take function stops the evaluation of the argument list after n elements.
But lists comprehensions always evaluate all elements of the list in the generator. There is no break-statement in Haskell.
You can use some trick to truncate the list before or after using it in the list comprehension, but there is no real point of doing so. That would be similar to first using normal take to truncate the list, then using a list comprehension just to return the result.
We can use a zip approach here, and enumerate over both the elements, and indices, like:
take2 :: (Num i, Enum i) => i -> [a] -> [a]
take2 n xs = [x | (x, _) <- zip xs [1..n]]
Or with the ParallelListComp extension:
{-# LANGUAGE ParallelListComp #-}
take2 :: (Num i, Enum i) => i -> [a] -> [a]
take2 n xs = [x | x <- xs | _ <- [1..n]]
But actually take is probably not a function that is a good fit for list comprehension in the first place.
Without List Comprehension
take' :: Int -> [Int] -> [Int]
take' _ [] = []
take' _ [x] = [x]
take' n all#(x : xs)
| (n > length all) = error "Index too large"
| (n == length all) = all
| (n == 0) = []
| (n < length all) = x : [] ++ (take' (n-1) xs)
take' :: Int -> [a] -> [a]
take' n xs = [xs !! i | i <- [0..n-1]]

Using few functions in Haskell together

I made this code where I need to find elements in a list that appears only once
for example: for input [1,2,2,3,4,4], the output will be: [1,3]
unique :: =[a]->[a]
unique xs =[x|x<-xs, elemNum x xs ==1]
elemNum :: Int -> [Int]->[Int]
elemNum x (y:ys)
| x==y =1+ elemNum x ys
| otherwise =elemNum x ys
However I am getting an error :
Not in scope: `unique'
Is this the correct way to use 2 function in Haskell? (define them at the same file), What'a wrong with the code?
There are a few problems in your code:
type signature of unique is wrong, it should be
unique :: (Eq a) => [a] -> [a]
that type constraint (Eq a) comes from elemNum
type signature of elemNum also wrong, it should be
elemNum :: (Eq a) => a -> [a] -> Int
that type constraint comes from ==, and the type of its first parameter no need to be Int, but its return type should be Int because you want to find out how many x in xs.
Also, you forgot to deal with empty list in that definition.
Here is a fixed version of your code:
unique :: (Eq a) => [a] -> [a]
unique xs =[x| x<-xs, elemNum x xs == 1]
elemNum :: (Eq a) => a -> [a] -> Int
elemNum x [] = 0
elemNum x (y:ys)
| x==y = 1 + elemNum x ys
| otherwise = elemNum x ys
Here is another implementation:
onlyOnce [] = []
onlyOnce (x:xs)
| x `elem` xs = onlyOnce $ filter (/=x) xs
| otherwise = x : onlyOnce xs
If x occurs in xs, then the result of onlyOnce (x:xs) should be the same as the result of applying onlyOnce to the result of removing all occurrences of x from xs; otherwise, x occurs in (x:xs) only once, so x should be part of the final result.
You have an equals sign in the Type declaration for unique:
unique :: =[a]->[a]
should be
unique :: [a] -> [a]
In my opinion it is much easier to implement this function using functions from Data.List module:
import Data.List
unique :: (Ord a) => [a] -> [a]
unique = map (\(y,_) -> y) . filter (\(x,l) -> l == 1) . map (\l#(x:xs) -> (x,length l)) . group . sort

Resources