Im trying to write a little program that can check whether a given number appears in a Tree. This is my code:
import Prelude
data Tree = Node Int [Tree]
Tree happytree = Node 5 [Node 1 [Node 6 []],Node 8 [],Node 2 [Node 1 [],Node 4 []]]
contains1 :: [Tree] -> Int -> Bool
contains1 [] x = False
contains1 (a:as) x = contains a x || contains1 as x
contains :: Tree -> Int -> Bool
contains (Node x []) y = x==y
contains (Node x as) y = x==y || contains1 as y
Im getting the error message
Not in scope: data constructor ‘Tree’
Perhaps you meant ‘True’ (imported from Prelude)
What is this supposed to mean?
I was wondering if somebody could give me an advice how to write my contains function without writing the help function contains1.
Thanks in advance
You get the error from the declaration Tree happytree = .... It seems a C-style habit snuck into your code and you tried to declare the constant with a type in the wrong way.
It's just happytree = ... and the compiler deduces the type. If you want to specify it explicitly, you do it like with the functions and write happytree :: Tree on a separate line.
As for getting rid of contains1, it's testing whether any of the trees in the list contains the value, so you can get rid of it this way:
contains :: Tree -> Int -> Bool
contains (Node x []) y = x==y
contains (Node x as) y = x==y || any (`contains` y) as
I'm using section syntax here for the partially applied contains; you could instead write a lambda \a -> contains a y.
While Sebastian's answer tells you the problem (type declarations belong in their own lines), note that the error message stems from the following:
data Id Int = Id Int
Id x = Id 5
This is perfectly valid, since you're binding with a pattern Id x. It's similar to
(x:_) = [5..]
However, in order to do this, you need a data constructor, e.g. something that can create a value, like Node, whereas Tree is a type constructor, it creates (or in this case is) types. That's why you end up with that rather cryptic error message:
Not in scope: data constructor ‘Tree’
Perhaps you meant ‘True’ (imported from Prelude)
Either way, you can fix this by removing Tree from Tree happytree.
For your other question, use any:
contains :: Tree -> Int -> Bool
contains (Node x as) y = x == y || any (`contains` y) as
Note that elem-like functions (on lists elem :: Eq a => a -> [a] -> Bool) usually take the predicate first and the container last, which makes the application of contains easier:
contains :: Int -> Tree -> Bool
contains y (Node x as) = x == y || any (contains y) as
Related
There's a series of examples I'm trying to do to practice Haskell. I'm currently learning about continuation passing, but I'm a bit confused as to how to implement a function like find index of element in list that works like this:
index 3 [1,2,3] id = 2
Examples like factorial made sense since there wasn't really any processing of the data other than multiplication, but in the case of the index function, I need to compare the element I'm looking at with the element I'm looking for, and I just can't seem to figure out how to do that with the function parameter.
Any help would be great.
first let me show you a possible implementation:
index :: Eq a => a -> [a] -> (Int -> Int) -> Int
index _ [] _ = error "not found"
index x (x':xs) cont
| x == x' = cont 0
| otherwise = index x xs (\ind -> cont $ ind + 1)
if you prefer point-free style:
index :: Eq a => a -> [a] -> (Int -> Int) -> Int
index _ [] _ = error "not found"
index x (x':xs) cont
| x == x' = cont 0
| otherwise = index x xs (cont . (+1))
how it works
The trick is to use the continuations to count up the indices - those continuations will get the index to the right and just increment it.
As you see this will cause an error if it cannot find the element.
examples:
λ> index 1 [1,2,3] id
0
λ> index 2 [1,2,3] id
1
λ> index 3 [1,2,3] id
2
λ> index 4 [1,2,3] id
*** Exception: not found
how I figured it out
A good way to figure out stuff like this is by first writing down the recursive call with the continuation:
useCont a (x:xs) cont = useCont a xs (\valFromXs -> cont $ ??)
And now you have to think about what you want valFromXs to be (as a type and as a value) - but remember your typical start (as here) will be to make the first continuation id, so the type can only be Int -> Int. So it should be clear that we are talking about of index-transformation here. As useCont will only know about the tail xs in the next call it seems natural to see this index as relative to xs and from here the rest should follow rather quickly.
IMO this is just another instance of
Let the types guide you Luke
;)
remarks
I don't think that this is a typical use of continuations in Haskell.
For once you can use an accumulator argument for this as well (which is conceptional simpler):
index :: Eq a => a -> [a] -> Int -> Int
index _ [] _ = error "not found"
index x (x':xs) ind
| x == x' = ind
| otherwise = index x xs (ind+1)
or (see List.elemIndex) you can use Haskells laziness/list-comprehensions to make it look even nicer:
index :: Eq a => a -> [a] -> Int
index x xs = head [ i | (x',i) <- zip xs [0..], x'== x ]
If you have a value a then to convert it to CPS style you replace it with something like (a -> r) -> r for some unspecified r. In your case, the base function is index :: Eq a => a -> [a] -> Maybe Int and so the CPS form is
index :: Eq a => a -> [a] -> (Maybe Int -> r) -> r
or even
index :: Eq a => a -> [a] -> (Int -> r) -> r -> r
Let's implement the latter.
index x as success failure =
Notably, there are two continuations, one for the successful result and one for a failing one. We'll apply them as necessary and induct on the structure of the list just like usual. First, clearly, if the as list is empty then this is a failure
case as of
[] -> failure
(a:as') -> ...
In the success case, we're, as normal, interested in whether x == a. When it is true we pass the success continuation the index 0, since, after all, we found a match at the 0th index of our input list.
case as of
...
(a:as') | x == a -> success 0
| otherwise -> ...
So what happens when we don't yet have a match? If we were to pass the success continuation in unchanged then it would, assuming a match is found, eventually be called with 0 as an argument. This loses information about the fact that we've attempted to call it once already, though. We can rectify that by modifying the continuation
case as of
...
(a:as') ...
| otherwise -> index x as' (fun idx -> success (idx + 1)) failure
Another way to think about it is that we have the collect "post" actions in the continuation since ultimately the result of the computation will pass through that code
-- looking for the value 5, we begin by recursing
1 :
2 :
3 :
4 :
5 : _ -- match at index 0; push it through the continuation
0 -- lines from here down live in the continuation
+1
+1
+1
+1
This might be even more clear if we write the recursive branch in pointfree style
| otherwise -> index x as' (success . (+1)) failure
which shows how we're modifying the continuation to include one more increment for each recursive call. All together the code is
index :: Eq a => a -> [a] -> (Int -> r) -> r -> r
index x as success failure
case as of
[] -> failure
(a:as') | x == a -> success 0
| otherwise -> index x as' (success . (+1)) failure
I'm a having a type error on my Haskell Code. termEnVoc is expected to return True if the Term given is part of the Vocabulario (vocabulary), I'm not completely sure if it works but anyway I can't understand why do I get a type error.
Here it's the code:
type Cte = Simbolo
type Funcion = (Simbolo,Aridad)
type Predicado = (Simbolo, Aridad)
type Vocabulario = ([Cte], [Funcion], [Predicado])
data Term = C Simbolo | L Var | F Simbolo [Term]
deriving (Show, Eq)
termEnVoc :: Term -> Vocabulario -> Bool --This is line 38, the one with the error
termEnVoc = \t -> \(cs,fs,ps)-> (or(map (\x ->(x==t))cs) || or(map (\x ->(x==t))f) || or(map (\x ->(x==t))p));
And here the error:
ERROR file:.\tarea3.hs:38 - Type error in explicitly typed binding
*** Term : termEnVoc
*** Type : [Char] -> ([[Char]],[([Char],Int)],[([Char],Int)]) -> Bool
*** Does not match : Term -> Vocabulario -> Bool
As chi suggests, the main problem appears to be that you are trying to compare Terms with values of other types. It's hard to see just what you're trying to do (specifically, what different types are supposed to represent), but here's the general way you probably want to structure the function definition:
termEnVoc (C simbolo) (cs, fs, ps) = cte `elem` cs
termEnVoc (F simbolo termList) (cs, fs, ps) = head $ filter ((== f) . fst) fs
termEnVoc (L var) (cs, fs, ps) = head $ filter ((== var) . fst) ps
As I indicated, some (or even most) of the details may be wrong, but this should give you a sense of how to structure the definition. The code above makes use of the following:
(== x) = (\y -> y == x)
You can actually do this with operators in general:
(/ 3) = (\x -> x/3)
and
(3 /) = (\x -> 3/x)
The only one that's wonky is subtraction, and I always have to look up the rules for that.
elem a as = or $ map (== a) as
a `elem` b = elem a b
filter p [] = []
filter p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
Note that the real definitions of the above are likely different, for efficiency reasons.
I finally decided that the problem was as dfeuer said that I was comparing terms with values of other types.
I end up with this method:
esTerm :: Vocabulario -> Term -> Bool
esTerm = \(c,f,p)-> \t -> case t of {
C x -> elem x c;
L x -> True;
F n ts -> case (lookup n f) of {
Nothing -> False;
Just x -> x==(length ts)&& and(map (esTerm (c,f,p)) ts);
}
}
Thanks for the help, it was really useful for fixing other mistakes I was making on my project.
I want to overload any operator . i want to do such a simple function that for instance think about overloading of == operator .Overload == such that
x==y
returns x .
Or x==y return x+y. It doesn't matter what . Can you show me any simple operator overloading example? I cannot find any example on the web unfortunately.
For example;when i call Tree a == Tree a
return 5 (it always return 5. I select it ,it is not related to any thing)
or when i call 3==4
return : 7
I tried the below codes(i find it from haskell.org) but it cannot compile.
class Eq a where
(==) ::a -> a -> Int
instance Eq Integer where
x == y = 5
instance Eq Float where
x == y = 5
Neither the below code works:
data Tree a = Node a | Empty
class Tree a where
(==) :: Tree a -> Tree a -> Int
instance Tree Integer where
x == y = 1
I take the error :
Ambiguous occurrence `Eq'
It could refer to either `Main.Eq', defined at Operations.hs:4:7
or `Prelude.Eq',
imported from `Prelude' at Operations.hs:1:1
(and originally defined in `GHC.Classes')
You can't hide instances from an imported module. See for example: Explicitly import instances
It looks like the "overloading" you're trying to do is to allow (==) for other types, like trees. This is easy! Just simply create a new instance:
data Tree a = Leaf a | Branch [Tree a]
instance (Eq a) => Eq (Tree a) where
(Leaf a) == (Leaf b) = a == b
(Branch a) == (Branch b) = a == b
_ == _ = False
(You could also just derive the Eq instance)
Try hiding the == from the Prelude first. You only need a type class if you want it to work differently for different types.
import Prelude hiding ((==))
x == y = x
Here's a +++ operator that acts like the (++) operator used to append lists:
(+++) :: [a]->[a]->[a]
x +++ [] = x
[] +++ x = x
x +++ y = (init x) +++ ((last x) : y)
When I compile the following code with GHC (using the -Wall flag):
module Main where
data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show)
insert :: (Ord a) => a -> Tree a -> Tree a
insert x EmptyTree = Node x EmptyTree EmptyTree
insert x (Node a left right)
| x == a = Node a left right
| x < a = Node a (insert x left) right
| x > a = Node a left (insert x right)
main :: IO()
main = do
let nums = [1..10]::[Int]
print . foldr insert EmptyTree $ nums
GHC complains that pattern matching in insert is non-exhaustive:
test.hs|6| 1:
|| Warning: Pattern match(es) are non-exhaustive
|| In an equation for `insert': Patterns not matched: _ (Node _ _ _)
Why is GHC issuing this warning? It is pretty obvious that the pattern GHC complains about is handled in insert x (Node a left right).
It's because the pattern matching is incomplete. There's no guarantee that one of x==a, x<a, or x>a holds. For instance, if the type is Double and x is NaN then none of them are True.
Riccardo is correct, GHC doesn't infer that your guards can't possibly all be false. So accept his answer please.
I'm going to digress and talk about coding style.
Your motivation for not using otherwise may have been that it looks unsightly:
insert :: (Ord a) => a -> Tree a -> Tree a
insert x EmptyTree = Node x EmptyTree EmptyTree
insert x (Node a left right)
| x == a = Node a left right
| x < a = Node a (insert x left) right
| otherwise = Node a left (insert x right)
Looking at this code, a human reader must confirm to themselves that the final guard accepts precisely those cases where x > a.
We could instead write it like this:
insert :: (Ord a) => a -> Tree a -> Tree a
insert x EmptyTree = Node x EmptyTree EmptyTree
insert x (Node a left right) = case x `compare` a of
EQ -> Node a left right
LT -> Node a (insert x left) right
GT -> Node a left (insert x right)
The Ordering type returned by compare has only the three values EQ, LT, and GT, so GHC can confirm that you've covered all possibilities, and a human reader can easily see that you've covered them correctly.
This is also more efficient code: we call compare once, instead of calling == and then probably calling < as well.
Now I'm going to digress some more and talk about laziness.
You've probably also written a function similar to this:
contains :: (Ord a) => a -> Tree a -> Bool
contains _ EmptyTree = False
contains x (Node a left right) = case x `compare` a of
EQ -> True
...
When x == a, you need to know that the tree uses the Node constructor, and that its first argument is equal to x. You don't need to know what either of the subtrees are.
But now look back at my definition of insert above. When the tree it's given is a Node, it always returns a Node whose first argument is always a. But it doesn't state that up front: instead it evaluates x `compare` a.
We can rewrite insert to perform the comparison as late as possible:
insert :: (Ord a) => a -> Tree a -> Tree a
insert x EmptyTree = Node x EmptyTree EmptyTree
insert x (Node a left right) = Node a newLeft newRight
where comparison = x `compare` a
newLeft = if comparison == LT then insert x left else left
newRight = if comparison == GT then insert x right else right
Now we return the Node a bit as soon as possible --- even if the comparison throws an error! --- and we still perform the comparison once at most.
GHC is not able to infer whether your three guards in the insert x (Node a left right) cover all possible cases, and consequently there will be no body to be associated with insert x (Node a left right). Try replacing the last condition x > a with otherwise (a synonim for True).
In this specific case however, it's true that the guards do not cover all cases, see augustss' example about double numbers.
Ok so we have not learned polymorphic functions yet, but we still have to write this code.
Given:
nameEQ (a,_) (b,_) = a == b
numberEQ (_,a) (_,b) = a == b
intEQ a b = a == b
member :: (a -> a -> Bool) -> a -> [a] -> Bool
I added:
member eq x ys | length ys < 1 = False
| head(ys) == x = True
| otherwise = member(x,tail(ys))
but i get errors about not being the correct type as well as some other stuff. We have to see if an element exists in from some type. So we have those 2 types above. Some examples given:
phoneDB = [("Jenny","867-5309"), ("Alice","555-1212"), ("Bob","621-6613")]
> member nameEQ ("Alice","") phoneDB
True
> member nameEQ ("Jenny","") phoneDB
True
> member nameEQ ("Erica","") phoneDB
False
> member numberEQ ("","867-5309") phoneDB
True
> member numberEQ ("","111-2222") phoneDB
False
> member intEQ 4 [1,2,3,4]
True
> member intEQ 4 [1,2,3,5]
False
not exactly sure what i need to do here. Any help or documentation on this would be great. Thanks!
Various things (I'm not going to write out the full answer as this is homework):
length ys < 1 can be more simply expressed as null ys
You don't need brackets around function arguments. head(ys) is more commonly written as head ys
You can, if you want, turn the top case and the other two into pattern matches rather than guards. member eq x [] = ... will match the empty case, member eq x (y:ys) = ... will match the non-empty case.
You are using == for comparison. But you're meant to use the eq function you're given instead.
You are bracketing the arguments to member as if this was Java or similar. In Haskell, arguments are separated by spaces, so member(x,(tail(ys)) should be member x (tail ys).
Those errors you gloss over "about not being the correct type as well as some other stuff" are important. They tell you what's wrong.
For example, the first time I threw your code into ghc I got:
Couldn't match expected type `a -> a -> Bool'
against inferred type `(a1, [a1])'
In the first argument of `member', namely `(x, tail (ys))'
In the expression: member (x, tail (ys))
In the definition of `member':
member eq x ys
| length ys < 1 = False
| head (ys) == x = True
| otherwise = member (x, tail (ys))
Well, when I look at it that's straightforward - you've typed
member(x,tail(ys))
When you clearly meant:
member x (tail ys)
Commas mean something in Haskell you didn't intend there.
Once I made that change it complained again that you'd left off the eq argument to member.
The error after that is tougher if you haven't learned about Haskell typeclasses yet, but suffice it to say that you need to use the passed-in eq function for comparing, not ==.
Since the parameters a in member :: (a -> a -> Bool) -> a -> [a] -> Bool
don't derive Eq, you can't use == to compare them,
but instead have to use the given function eq.
Therefore your code might look like this:
member :: (a -> a -> Bool) -> a -> [a] -> Bool
member eq x ys
| length ys < 1 = False
| eq x (head ys) = True
| otherwise = member eq x (tail ys)
Only problem with this is, that length still requires to evaluate the entire List,
so you could reach a a better performance writing:
member' :: (a -> a -> Bool) -> a -> [a] -> Bool
member' eq x (y:ys)
| eq x y = True
| otherwise = member' eq x ys
member' _ _ [] = False
With the use of any you can simplify it even more:
member'' :: (a -> a -> Bool) -> a -> [a] -> Bool
member'' f a = any (f a)