Trying to iterate over a forest Haskell compilation error - haskell

I try to assign to each node of a forest a number, such that there will be no 2 nodes with the same number. I try to use 2 functions which call eachother recursive but I get some compilation errors.
Here is the code :
numberTree :: Int -> Tree a -> (Tree Int,Int)
numberTree n (Node c []) = (Node n [], n+1)
numberTree n (Node _ (x:xs)) = (Node n fst.numberForest (n+1) xs, snd.numberForest (n+1) xs)
numberForest :: Int -> [Tree a] -> ([Tree Int],Int)
numberForest n (x:xs) = ((fst(numberTree n x )):(fst(numberForest (n+1) xs)), snd(numberForest (n+1) xs)+1)
numberForest n (x:xs) = ((fst(numberTree n x )):(fst(numberForest (n+1) xs)), snd(numberForest (n+1) xs)+1)
The errors I get are :
.hs:27:34:
Couldn't match expected type b0 -> c0' with actual typeTree Int
Possible cause: Node' is applied to too many arguments
In the first argument of(.)', namely `Node n fst'
In the expression: Node n fst . numberForest (n + 1) xs
.hs:27:34:
Couldn't match expected type `Tree Int' with actual type `a0 -> c0
In the expression: Node n fst . numberForest (n + 1) xs
In the expression:
(Node n fst . numberForest (n + 1) xs,
snd . numberForest (n + 1) xs)
In an equation for `numberTree':
numberTree n (Node _ (x : xs))
= (Node n fst . numberForest (n + 1) xs,
snd . numberForest (n + 1) xs)
.hs:27:42:
Couldn't match type `(a1, b1) -> a1' with `[Tree Int]'
Expected type: Forest Int
Actual type: (a1, b1) -> a1
Probable cause: `fst' is applied to too few arguments
In the second argument of `Node', namely `fst'
In the first argument of `(.)', namely `Node n fst'
.hs:27:46:
Couldn't match expected type `a0 -> b0'
with actual type `([Tree Int], Int)'
Possible cause: `numberForest' is applied to too many arguments
In the second argument of `(.)', namely `numberForest (n + 1) xs'
In the expression: Node n fst . numberForest (n + 1) xs
.hs:27:70:
Couldn't match expected type `Int' with actual type `a2 -> c1'
In the expression: snd . numberForest (n + 1) xs
In the expression:
(Node n fst . numberForest (n + 1) xs,
snd . numberForest (n + 1) xs)
In an equation for `numberTree':
numberTree n (Node _ (x : xs))
= (Node n fst . numberForest (n + 1) xs,
snd . numberForest (n + 1) xs)
.hs:27:74:
Couldn't match expected type `a2 -> (a3, c1)'
with actual type `([Tree Int], Int)'
Possible cause: `numberForest' is applied to too many arguments
In the second argument of `(.)', namely `numberForest (n + 1) xs'
In the expression: snd . numberForest (n + 1) xs
What is wrong and how should I solve this ?

This line
numberTree n (Node _ (x:xs)) = (Node n fst.numberForest (n+1) xs, snd.numberForest (n+1) xs)
actually means
numberTree n (Node _ (x:xs)) = ( (Node n fst) . (numberForest (n+1) xs)
, snd . (numberForest (n+1) xs))
which tries to compose trees instead of functions, causing the compiler to complain. You probably want something like this:
numberTree n (Node _ (x:xs)) = ( Node n (fst (numberForest (n+1) xs))
, snd (numberForest (n+1) xs))
However, be careful that the code above is computing numberForest (n+1) xs twice, causing an exponential blowup. You can avoid that e.g. using a let ... in ... as follows
numberTree n (Node _ (x:xs)) = let result = numberForest (n+1) xs
in (Node n (fst result), snd result)
You can further improve on this using pattern matching inside the let:
numberTree n (Node _ (x:xs)) = let (forest, n') = numberForest (n+1) xs
in (Node n forest, n')

The state monad is your friend.
import Control.Monad.Trans.State
data Tree a = Node a (Forest a)
type Forest a = [Tree a]
numberTreeS :: Tree a -> State Int (Tree Int)
numberTreeS (Node _ xs) = do
n <- get
put (n + 1)
xs' <- numberForestS xs
return $ Node n xs'
numberForestS :: Forest a -> State Int (Forest Int)
numberForestS = mapM numberTreeS
numberForest :: Forest a -> Forest Int
numberForest xs = evalState (numberForestS xs) 0
This is more readable, than explicit state passing.

Related

reconstruct the binary tree with two lists after preorder and inorder

--Two lists are given, one sorted by preorder, the other sorted by inorder. And the two lists are from the same binary tree. With the two lists the binary tree is --reconstructed.
-- I haven't found the function "rank" online. My professor told us that the function "rank" can output the position of one element in a list.
The error occured in the following line where the function "rank" were used.
So I have two questions.
How ist the function "rank"?
Is the expression "reconstruct :: [Int]->IntTree" correct ? I am not sure.
main :: IO () -- This says that main is an IO action.
main = return () -- This tells main to do nothing
data IntTree = Empty | Branch IntTree Int IntTree deriving (Show, Eq)
reconstruct :: [Int]->IntTree
-- Pattern matching
reconstruct (x:xs) y = Branch (reconstruct take((rank x y) xs) take ((rank x y) y)) x x (reconstruct drop ((rank x y)+1 xs) drop ((rank x y)+1 y))
after correction
import Data.List
main :: IO () -- This says that main is an IO action.
main = return () -- This tells main to do nothing
data IntTree = Empty | Branch IntTree Int IntTree deriving (Show, Eq)
--Two lists are given, one sorted by preorder, the other sorted by inorder.
-- And the two lists are from the same binary tree. With the two lists the binary tree is reconstructed.
reconstruct :: [Int]->[Int]->IntTree
-- Pattern matching
reconstruct [] [] = Empty
reconstruct (x:xs) y = Branch (reconstruct take (length (fst p) xs) (fst p)) x (reconstruct drop (length (fst p) xs) (snd p))
where p = span (x/=) y
reconstruct _ _ = error "incomplete pattern"
the error
E:\Haskell\Uebungsblatt_2_Aufgabe_1.hs:15:32: error:
* Couldn't match expected type `[Int] -> IntTree'
with actual type `IntTree'
* The function `reconstruct' is applied to three arguments,
but its type `[Int] -> [Int] -> IntTree' has only two
In the first argument of `Branch', namely
`(reconstruct take (length (fst p) xs) (fst p))'
In the expression:
Branch
(reconstruct take (length (fst p) xs) (fst p))
x
(reconstruct drop (length (fst p) xs) (snd p))
|
15 | reconstruct (x:xs) y = Branch (reconstruct take (length (fst p) xs) (fst p)) x (reconstruct drop (length (fst p) xs) (snd p))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E:\Haskell\Uebungsblatt_2_Aufgabe_1.hs:15:44: error:
* Couldn't match expected type `[Int]'
with actual type `Int -> [a0] -> [a0]'
* Probable cause: `take' is applied to too few arguments
In the first argument of `reconstruct', namely `take'
In the first argument of `Branch', namely
`(reconstruct take (length (fst p) xs) (fst p))'
In the expression:
Branch
(reconstruct take (length (fst p) xs) (fst p))
x
(reconstruct drop (length (fst p) xs) (snd p))
|
15 | reconstruct (x:xs) y = Branch (reconstruct take (length (fst p) xs) (fst p)) x (reconstruct drop (length (fst p) xs) (snd p))
| ^^^^
E:\Haskell\Uebungsblatt_2_Aufgabe_1.hs:15:50: error:
* Couldn't match expected type `[Int] -> [Int]'
with actual type `Int'
* The function `length' is applied to two arguments,
but its type `[Int] -> Int' has only one
In the second argument of `reconstruct', namely
`(length (fst p) xs)'
In the first argument of `Branch', namely
`(reconstruct take (length (fst p) xs) (fst p))'
|
15 | reconstruct (x:xs) y = Branch (reconstruct take (length (fst p) xs) (fst p)) x (reconstruct drop (length (fst p) xs) (snd p))
| ^^^^^^^^^^^^^^^^^
E:\Haskell\Uebungsblatt_2_Aufgabe_1.hs:15:81: error:
* Couldn't match expected type `[Int] -> IntTree'
with actual type `IntTree'
* The function `reconstruct' is applied to three arguments,
but its type `[Int] -> [Int] -> IntTree' has only two
In the third argument of `Branch', namely
`(reconstruct drop (length (fst p) xs) (snd p))'
In the expression:
Branch
(reconstruct take (length (fst p) xs) (fst p))
x
(reconstruct drop (length (fst p) xs) (snd p))
|
15 | reconstruct (x:xs) y = Branch (reconstruct take (length (fst p) xs) (fst p)) x (reconstruct drop (length (fst p) xs) (snd p))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E:\Haskell\Uebungsblatt_2_Aufgabe_1.hs:15:93: error:
* Couldn't match expected type `[Int]'
with actual type `Int -> [a1] -> [a1]'
* Probable cause: `drop' is applied to too few arguments
In the first argument of `reconstruct', namely `drop'
In the third argument of `Branch', namely
`(reconstruct drop (length (fst p) xs) (snd p))'
In the expression:
Branch
(reconstruct take (length (fst p) xs) (fst p))
x
(reconstruct drop (length (fst p) xs) (snd p))
|
15 | reconstruct (x:xs) y = Branch (reconstruct take (length (fst p) xs) (fst p)) x (reconstruct drop (length (fst p) xs) (snd p))
| ^^^^
E:\Haskell\Uebungsblatt_2_Aufgabe_1.hs:15:99: error:
* Couldn't match expected type `[Int] -> [Int]'
with actual type `Int'
* The function `length' is applied to two arguments,
but its type `[Int] -> Int' has only one
In the second argument of `reconstruct', namely
`(length (fst p) xs)'
In the third argument of `Branch', namely
`(reconstruct drop (length (fst p) xs) (snd p))'
|
15 | reconstruct (x:xs) y = Branch (reconstruct take (length (fst p) xs) (fst p)) x (reconstruct drop (length (fst p) xs) (snd p))
| ^^^^^^^^^^^^^^^^^
[Finished in 0.5s]
reconstruct :: [Int] -> [Int] -> IntTree
reconstruct [] [] = Empty
reconstruct (x:xs) y = let (l,_:r) = span (x /=) y
(l',r') = splitAt (length l) xs
in Branch (reconstruct l' l) x (reconstruct r' r)
reconstruct _ _ = error "incomplete pattern"
This seemed to work on the single testcase I tried, and is pretty much what you intended to write (I think). It runs into issues if nodes can have left-descendants with equal contents to themselves (?). I think it might traverse l twice (due to length), you could solve this with a zipand some extra logic if desired.
The function `reconstruct' is applied to three arguments, but its type `[Int] -> [Int] -> IntTree' has only two
(reconstruct take (length (fst p) xs) (fst p))
You apply the reconstruct functions to 3 arguments, as stated in the error message: take, (length (fst p) xs) and (fst p).
Similar error is with length application: you pass 2 arguments to it.
Maybe you meant to pass FUNCTION(ARGUMENT) as single argumetn to next function. It does not work like this, it would be considered as 2 arguments: FUNCTION and (ARGUMENT). Instead you should use (FUNCTION ARGUMENT), or (FUNCTION (ARGUMENT)) if the ARGUMENT is complex.
Also, you should not group arguments to functions separately from the function: take (length ... LIST). This is considered as single argument (length ... LIST). They should be on same bracket level with the function.
So your first reconstruct call would rather look like:
(reconstruct (take (length (fst p)) xs) (fst p))
And probably the rest of the expression have similar issues

Getting the error "Non type-variable argument in the constraint: Integral [a2]"

I'm trying to implement the luhn algorithm using the following code:
luhn :: Int -> Bool
luhn x = (tail $ show (foldl (\acc x -> acc + (read x :: Int)) 0 (foldr doEncrypt [] $ zip [0..] (show x)))) == "0"
where
doEncrypt (i,y) acc = if not(even i)
then head(((uncurry (+) . (`divMod` 10) . (*2)) y)) : acc
else (head y) : acc
I now got stuck with the following error:
• Non type-variable argument in the constraint: Integral [a2]
(Use FlexibleContexts to permit this)
• When checking the inferred type
doEncrypt :: forall a1 a2.
(Integral a1, Integral [a2]) =>
(a1, [a2]) -> [a2] -> [a2]
In an equation for ‘luhn’:
luhn x
= (tail
$ show
(foldl
(\ acc x -> acc + (read x :: Int))
0
(foldr doEncrypt [] $ zip [0 .. ] (show x))))
== "0"
where
doEncrypt (i, y) acc
= if not (even i) then
head (((uncurry (+) . (`divMod` 10) . (* 2)) y)) : acc
else
(head y) : acc
I see that the error suggests that the second part of the tuple (a2) is a "Non type-variable argument". However, Haskell seems to identify this a2 argument as an Integral while in fact it is a Char. How can I tell Haskell that this is a Char and that Haskell shouldn't worry any further about this variable's type? Or is there something else I'm not understanding which causes this error?
Edit:
When I remove the (head y) and replace it by y I get instead the following error:
• Couldn't match type ‘Char’ with ‘[Char]’
Expected type: [String]
Actual type: [Char]
• In the third argument of ‘foldl’, namely
‘(foldr doEncrypt [] $ zip [0 .. ] (show x))’
In the first argument of ‘show’, namely
‘(foldl
(\ acc x -> acc + (read x :: Int))
0
(foldr doEncrypt [] $ zip [0 .. ] (show x)))’
In the second argument of ‘($)’, namely
‘show
(foldl
(\ acc x -> acc + (read x :: Int))
0
(foldr doEncrypt [] $ zip [0 .. ] (show x)))’
There where multiple things wrong with my solution, but finally the following code works!
luhn :: Int -> Bool
luhn x = (tail $ show (foldl (\acc x -> acc + (digitToInt x)) 0 (foldr doEncrypt [] $ zip [0..] (show x)))) == "0"
where
doEncrypt (i,y) acc = if not(even i)
then (head $ show(((uncurry (+) . (`divMod` 10) . (*2)) (digitToInt y)))) : acc
else y : acc
Thanks a lot to #WillemVanOnsem for your pointers, without I probably wouldn't have solved this!

binary tree in generalized statement

I have to implement a Code which accepts a binary tree and shows a generalised Statement: this is my Code
mkBTree xs
| (m == 0) = Leaf (unwrap xs)
| otherwise = Fork (mkBTree ys) (mkBTree zs)
where m = (length xs) `div` 2
(ys, zs) = splitAt m xs
unwrap [x] = x
but the only thing i get is something like:
Data constructor not in scope: Leaf :: a -> t
Data constructor not in scope: Fork :: t -> t -> t
Failed, modules loaded: none.
What is wrong here?
I have to implement a Code which accepts a binary tree and shows a generalised Statement: this is my Code import Data.Char
import Data.List
data mkBTree xs = Leaf xs | Fork (mkBTree xs) xs (mkBTree xs)
deriving(Eq,Show)
data mkBTree xs = Leaf xs | Fork xs [mkBTree xs]
deriving(Eq,Show)
entferneBlaetter :: NBaum a -> NBaum a
entferneBlaetter xs
| (m == 0) = BBlatt (unwrap xs)
| otherwise = BKnoten (NBaum ys) (NBaum zs)
where m = (length xs) `div` 2
(ys, zs) = splitAt m xs
unwrap [x] = x

Difference list head function time complexity

I'm playing with Difference list data type in Haskell: http://hackage.haskell.org/package/dlist-0.8.0.2/docs/Data-DList.html
And I see from package description that head function runs in O(n) time.
I wonder, why it happens? From first glance it looks like head should work O(1) time in most reasonable cases. But to argue about time-complexity we should define what this n stands for? Is it number of elements or number of lists?
Let's expand some definitions to figure out how head works.
First I have x = [1,2] and y = [3,4]. Then I convert them to DList and obtain x' = DList (x++) and y' = DList (y++). After that I append them:
z = x' <> y' = DList $ \zs -> x ++ (y ++ zs)
Now to the head function. It is defined as
-- | /O(n)/. Return the head of the dlist
head :: DList a -> a
head = list (error "Data.DList.head: empty dlist") const
Where list is:
-- | /O(n)/. List elimination for dlists
list :: b -> (a -> DList a -> b) -> DList a -> b
list nill consit dl =
case toList dl of
[] -> nill
(x : xs) -> consit x (fromList xs)
So you can say it is obvious why head runs O(n) time: is uses list function which runs O(n) time. But let's do some equational reasoning:
head z
= list (error "Data.DList.head: empty dlist") const z
= case toList z of
[] -> error "Data.DList.head: empty dlist"
(x : xs) -> const x (fromList xs)
= case (toList $ DList $ \zs -> x ++ (y ++ zs)) of
[] -> error "Data.DList.head: empty dlist"
(x : xs) -> const x (fromList xs)
= case (x ++ (y ++ [])) of
[] -> error "Data.DList.head: empty dlist"
(x : xs) -> const x (fromList xs)
= case ((1:2:[]) ++ (y ++ [])) of
[] -> error "Data.DList.head: empty dlist"
(x : xs) -> const x (fromList xs)
= case (1:((2:[]) ++ (y ++ []))) of
[] -> error "Data.DList.head: empty dlist"
(x : xs) -> const x (fromList xs)
= (1 : ((2:[]) ++ (y ++ []))) -> const 1 (fromList (2:[]) ++ (y ++ []))
= 1
So it looks like head won't evaluate whole list to take just first element and will work in O(1) unless there no empty lists. Is this really true and description of function just tells about worst possible case?

I do not understand this error haskell

My code receives a list of values ​​in hexadecimal and i have to pass them to binary and put each result in a list but I have these two errors and i dont know how to fix them
Pixels.hs:121:29:
Occurs check: cannot construct the infinite type:
t0 = Bool -> [a1] -> t0
In the return type of a call of `modA'
Probable cause: `modA' is applied to too many arguments
In the expression:
modA (o ++ [(k `mod` 2)]) (l + 1) (k `div` 2) otherwise o
In an equation for `modA':
modA o l k
| l < 8 = modA (o ++ [(k `mod` 2)]) (l + 1) (k `div` 2) otherwise o
Pixels.hs:126:89:
Couldn't match expected type `[a0]'
with actual type `Bool -> t1 -> [[a1]] -> [a0] -> t0'
In the first argument of `(++)', namely `f'
In the fourth argument of `f', namely
`(f
++
[(psr (head (e1)))
++
(psr (head (e2)))
++ (psr (head (e3))) ++ (psr (head (e4))) ++ (psr (head (e5)))])'
In the expression:
f otherwise
convertir
[tail (e1), tail (e2), tail (e3), tail (e4), ....]
(f
++
[(psr (head (e1)))
++
(psr (head (e2)))
++ (psr (head (e3))) ++ (psr (head (e4))) ++ (psr (head (e5)))])
Failed, modules loaded: none.
here is the code
rInt :: String -> Int
rInt = read
font:: Char -> Pixels
font a = let x= ord a in
if x>=0 || x<=31 || x>=126 then ["*****","*****","*****","*****","*****","*****","*****"]
else
auxfont (fontBitmap!!(x-32))
where
auxfont b = let y = map trns (map rInt (map show b)) in
convertir y []
trns z = modA [] 1 z
modA o l k
| l < 8 = modA (o++[(k `mod` 2)]) (l+1) (k `div` 2)
otherwise o
convertir (e1:e2:e3:e4:e5) f
| null e1 = f
otherwise convertir [tail(e1),tail(e2),tail(e3),tail(e4),tail(e5)] (f++[(psr(head(e1)))++(psr(head(e2)))++(psr(head(e3)))++(psr(head(e4)))++(psr(head(e5)))])
psr 0 = " "
psr 1 = "*"
Your syntax is wrong, you need a | before otherwise:
foo x y z | x > y = ...
| otherwise = ...

Resources