I have a data object for trees like this:
data Tree = Empty | Node Int [Tree] deriving (Show, Eq)
Here is my searching function:
searchValueTree :: Tree -> Int -> Bool
searchValueTree Empty _ = False
searchValueTree (Node a list) valueSearch
| a == valueSearch = True
| otherwise = helperTree list valueSearch
--help function
helperTree :: [Tree] -> Int -> Bool
helperTree [] _ = False
helperTree (x:xs) value = searchValueTree x value || helperTree xs value
test::Bool
test = searchValueTree (Node 5 [Node 4 [Node 3 [Empty]], Node 7 [Empty], Leer]) 3
The question is, when I'm in the helper function and I call searchValueTree x value and I haven't found my value, which is called first: helperTree list valueSearch in searchValueTree, or helperTree xs value in helperTree?
I can't figure out the order of execution.
It goes something like this:
searchValueTree x value || helperTree xs value
-> {- definition of || -}
case searchValueTree x value of
True -> True
False -> helperTree xs value
-> {- pattern match forces evaluation of the call to searchValueTree -}
case (case x of
Empty -> False
Node a list | a == value -> True
| otherwise -> helperTree list value
) of
True -> True
False -> helperTree xs value
-> {- assuming x matches Node a list and a /= value -}
case let Node _ list = x in helperTree list value of
True -> True
False -> helperTree xs value
I believe in your parlance this means that helperTree list valueSearch is called in searchValueTree before helperTree xs value is called in helperTree. From here, because the first argument to (||) has not yet reached a form that lets the pattern match choose between its branches, evaluation continues in the scrutinee of the case, namely in let Node _ list = x in helperTree list value.
Related
I am currently a newbie just starting out.
My code :
atIndex :: [a] -> Int -> a
atIndex [] _ = error "error"
atIndex (xs) n = head (drop n xs)
The first argument is my array and the second my index (ex: atIndex [1,2,3] 1; I will get 2).
I want to know how can I send an error or message if my index is out of range of the array ?
example: atIndex [1,2,3] -1 or atIndex [1,2,3] 3 and get "error, your index is out of range".
You can work with a guard so:
atIndex :: [a] -> Int -> a
atIndex [] _ = error "error"
atIndex (x:_) 0 = …
atIndex (_:xs) n
| n < 0 = …
| otherwise = atIndex … …
In Haskell, one howeve usually does not work with errors, but encodes it in the output, by using a Maybe a or Either String a type for example where Nothing/Left "error message" is used if the input is invalid, and Just x/Right x in case the input is valid with x the result wrapped in a Just or Right, so:
atIndex :: [a] -> Int -> Maybe a
atIndex [] _ = Nothing
atIndex (x:_) 0 = Just …
atIndex (_:xs) n
| n < 0 = Nothing
| otherwise = atIndex … …
For variety, this is what the code looks like when using if / else and Either.
Note 1. When using guards you don't have = in the declaration, whereas you do with if / else.
Note 2. As with Maybe, where the return type is Just value or Nothing, with Either the return type is Left error or Right value. Unlike Maybe, Either includes an error message.
atIndex :: [a] -> Int -> Either String a
atIndex [] _ = Left "Error"
atIndex xs n =
if n >=0 && n < length(xs) then
Right $ head (drop n xs)
else
Left "Error"
If you just want an error on invalid index, the built-in indexing function (!!) already does this. Its definition, found on page 118 of the Haskell 2010 Language Report, is as follows:
(!!) :: [a] -> Int -> a
xs !! n | n < 0 = error "Prelude.!!: negative index"
[] !! _ = error "Prelude.!!: index too large"
(x:_) !! 0 = x
(_:xs) !! n = xs !! (n-1)
Other options are to use a Maybe or Either to represent the result. The implementation would be similar to the above, but returning Nothing/Left on errors and returning Just/Right otherwise.
Note that head is a partial function, and listToMaybe should be used instead when the list could be empty. Here are some implementations using drop like your function:
atIndexMaybe :: [a] -> Int -> Maybe a
atIndexMaybe xs n
| n < 0 = Nothing
| otherwise = listToMaybe (drop n xs)
atIndexEither :: [a] -> Int -> Either String a
atIndexEither xs n
| n < 0 = Left "Negative index"
| otherwise = case drop n xs of
[] -> Left "Index out of range"
(x:_) -> Right x
I am trying to create function setEqual.. This is what I have so far:
setEqual :: Eq a => [a] -> [a] -> Bool
setEqual [] _ = True
setEqual _ [] = False
setEqual a#(x:a') (y:b) | x == y = setEqual a' b
| otherwise = setEqual a b
setEqualTest = [ not ("ABCD" `setEqual` "ABC"),
not ("ABC" `setEqual` "ABCD"),
[0,2,1,3] `setEqual` [0,1,2,3] ]
When I run the test I get [True, False, False]. Am I doing this correctly?
I think you just need to get two things right for writing your recursive function (to check set equality here): the base case and the recursive case.
You base case is incorrect. You don't know that an empty set [] is equal to an arbitrary set _ unless it's also empty. So it should be:
setEqual [] [] = True
plus that empty set is not equal to anything else:
setEqual [] _ = False
setEqual _ [] = False
(Note that the setEqual [] [] ... line takes precedence as it is written before the others.
Your recursive case has a typo, and the last line should be:
| otherwise = setEqual a' b
I'm trying to find out en element at a particular position in a list using recursive function. The function takes 2 parameter, an int & list. int is the position of the item in the list. I have specified 2 cases, 1st case for empty list provided and 2nd case for non- empty list.
.hs code
findKthElem :: Ord a => Int -> [a] -> a
findKthElem x [] = error "empty list provided"
findKthElem x (y:ys) = if x==1 then y else findKthElem (x-1) ys
Input
*Main> findKthElem 0 [1..99]
Output
** Exception: empty list provided
Expected Output
1
Since I'm a newbie in Haskell I can't understand where I'm going wrong. Please Help.
An approach using guards to match against different index values:
findKthElem :: Ord a => Int -> [a] -> a
findKthElem _ [] = error "empty list provided"
findKthElem i (x:xs) | i < 0 = error "invalid index"
| i == 0 = x
| otherwise = findKthElem (i - 1) xs
You can also use the Maybe monad to remain error free:
findKthElem :: Ord a => Int -> [a] -> Maybe a
findKthElem _ [] = Nothing
findKthElem i (x:xs) | i < 0 = Nothing
| i == 0 = Just x
| otherwise = findKthElem (i - 1) xs
So I'm trying to define a function in Haskell that if given an integer and a list of integers will give a 'true' or 'false' whether the integer occurs only once or not.
So far I've got:
let once :: Eq a => a -> [a] -> Bool; once x l =
But I haven't finished writing the code yet. I'm very new to Haskell as you may be able to tell.
Start off by using pattern matching:
once x [] =
once x (y:ys) =
This won't give you a good program immediately, but it will lead you in the right direction.
Here's a solution that doesn't use pattern matching explicitly. Instead, it keeps track of a Bool which represents if a occurance has already been found.
As others have pointed out, this is probably a homework problem, so I've intentionally left the then and else branches blank. I encourage user3482534 to experiment with this code and fill them in themselves.
once :: Eq a => a -> [a] -> Bool
once a = foldr f False
where f x b = if x == a then ??? else ???
Edit: The naive implementation I was originally thinking of was:
once :: Eq a => a -> [a] -> Bool
once a = foldr f False
where f x b = if x == a then b /= True else b
but this is incorrect as,
λ. once 'x' "xxx"
True
which should, of course, be False as 'x' occurs more than exactly once.
However, to show that it is possible to write once using a fold, here's a revised version that uses a custom monoid to keep track of how many times the element has occured:
import Data.List
import Data.Foldable
import Data.Monoid
data Occur = Zero | Once | Many
deriving Eq
instance Monoid Occur where
mempty = Zero
Zero `mappend` x = x
x `mappend` Zero = x
_ `mappend` _ = Many
once :: Eq a => a -> [a] -> Bool
once a = (==) Once . foldMap f
where f x = if x == a then Once else Zero
main = do
let xss = inits "xxxxx"
print $ map (once 'x') xss
which prints
[False,True,False,False,False]
as expected.
The structure of once is similar, but not identical, to the original.
I'll answer this as if it were a homework question since it looks like one.
Read about pattern matching in function declarations, especially when they give an example of processing a list. You'll use tools from Data.List later, but probably your professor is teaching about pattern matching.
Think about a function that maps values to a 1 or 0 depending on whethere there is a match ...
match :: a -> [a] -> [Int]
match x xs = map -- fill in the thing here such that
-- match 3 [1,2,3,4,5] == [0,0,1,0,0]
Note that there is the sum function that takes a list of numbers and returns the sum of the numbers in the list. So to count the matches a function can take the match function and return the counts.
countN :: a -> [a] -> Int
countN x xs = ? $ match x xs
And finally a function that exploits the countN function to check for a count of only 1. (==1).
Hope you can figure out the rest ...
You can filter the list and then check the length of the resulting list. If length == 1, you have only one occurrence of the given Integer:
once :: Eq a => a -> [a] -> Bool
once x = (== 1) . length . filter (== x)
For counting generally, with import Data.List (foldl'), pointfree
count pred = foldl' (\ n x -> if pred x then n + 1 else n) 0
applicable like
count (< 10) [1 .. 10] == 9
count (== 'l') "Hello" == 2
gives
once pred xs = count pred xs == 1
Efficient O(n) short-circuit predicated form, testing whether the predicate is satisfied exactly once:
once :: (a -> Bool) -> [a] -> Bool
once pred list = one list 0
where
one [] 1 = True
one [] _ = False
one _ 2 = False
one (x : xs) n | pred x = one xs (n + 1)
| otherwise = one xs n
Or, using any:
none pred = not . any pred
once :: (a -> Bool) -> [a] -> Bool
once _ [] = False
once pred (x : xs) | pred x = none pred xs
| otherwise = one pred xs
gives
elemOnce y = once (== y)
which
elemOnce 47 [1,1,2] == False
elemOnce 2 [1,1,2] == True
elemOnce 81 [81,81,2] == False
I have a data called "Sample", defined as
data Sample = Test1 (String,[[String]])
| Test2 (String,[[String]])
Then I create a list[Sample] called "Samples", say
[Test1 ("Sample1",[["works","running"]]), Test2 ("Sample2", []),
Test1 ("Sample3", [["aborts"]] ]
Now, I need to check whether "aborts" is present under "Sample3". I have a basic
idea of how to do it but I am not sure how to implement it in Haskell.
My idea is
check:: String -> [String] -> [Sample] -> Bool
check samplename result samples =
I can call it by:
check "Sample3" ["aborts"] Samples
But how do I implement this function.
I have solved like this but I am looking for a better version.
My version is:
check:: String -> [String] -> [Sample] -> Bool
check samplename result samples =
if( "True" `elem` final )
then True
else False
where
final = [x | sample <- samples,
x <- [ case sample of
Test1 (name,res) =
if name == samplename && (result `elem` res)
then "True"
else "False"
Test2 (name, res) = "False"]]
Here is my version of the solution. But I dont think your data represent any real problem , you can easily use Map if you want to store something like [Sample] which is basically a list of key value pairs. Well the idea behind my solution is also inspired from Map . I have written a lookup' function similar to lookup which given a key returns the value . writing the rest function is trivial then. Similar to your approach but less messy .
data Sample = Test1 (String,[[String]])
| Test2 (String,[[String]])
deriving Show
samples = [ Test1 ("Sample1",[["works","running"]]), Test2 ("Sample2", []), Test1 ("Sample3", [["aborts"]]) ]
fromSample :: Sample -> (String,[[String]])
fromSample (Test1 x) = x
fromSample (Test2 x) = x
lookup' :: String -> [Sample] -> Maybe [[String]]
lookup' str [] = Nothing
lookup' str (x:xs) | fst pair == str = Just $ snd pair
| otherwise = lookup' str xs
where pair = fromSample x
check :: String -> [String] -> [Sample] -> Bool
check sample str xs = case lookup' sample xs of
Nothing -> False
Just list -> str `elem` list
If we think about what check must do at a high level, we know it must check for every element of samples to see if the test "Sample3" contains any (or all, i'm unclear which you mean) of the strings result are present.
So we know we need recursion and we can start by making the general outline of the function:
check :: String -> [String] -> [Sample] -> Bool
check samplename result [] = False
check samplename result (x:xs) = ...
So when the list is empty, no matches can occur so we can immediately return false. In the recursive case we know we need to check x and if no match is found, continue checking xs. One possible way to do this is with a helper function check' (you can also just inline the check').
check samplename result (x:xs) = check' x || check samplename result xs
where check' ...
ok, so what does check' do? It checks the datatype Sample to see if any matches occur. We know Sample has two constructors, Test1 and Test2 so check' should look like
check' :: Sample -> Bool
check' (Test1 (name, values)) = ...
check' (Test2 (name, values)) = ...
The first thing we have to do is test the value of name to see if it matches samplename. We can do this easily using guards
check' :: Sample -> Bool
check' (Test1 (name, values)) | name == samplename = ...
check' (Test2 (name, values)) | name == samplename = ...
check' _ = False
Since check' is a child function of check, the variables defined in check are in scope, so we can just refer to them. A new case is added to handle the event that the names do not match.
Ok, so now the idea is to check if any (or all) of the values in result occur in values. Luckily the prelude has a function we can use for this.
elem :: Eq a => a -> [a] -> Bool
The function now becomes
check' :: Sample -> Bool
check' (Test1 (name, values)) | name == samplename = result `elem` values
check' (Test2 (name, values)) | name == samplename = result `elem` values
check' _ = False
The full function is thus:
check :: String -> [String] -> [Sample] -> Bool
check samplename result [] = False
check samplename result (x:xs) = check' x || check samplename result xs
where check' :: Sample -> Bool
check' (Test1 (name, values)) | name == samplename = result `elem` values
check' (Test2 (name, values)) | name == samplename = result `elem` values
check' _ = False
Checking every element of a list with a predicate is so common that the prelude has standard functions for this. one possible way to define check is using the functions or and map.
This will generally result in a less efficient function though:
check :: String -> [String] -> [Sample] -> Bool
check samplename result samples = or (map check' samples)
where check' :: Sample -> Bool
check' (Test1 (name, values)) | name == samplename = result `elem` values
check' (Test2 (name, values)) | name == samplename = result `elem` values
check' _ = False
The function can further be simplified by adapting an alternative structure for the datatype, such as
type ID = Int
type Name = String
type Values = [[String]]
data Sample = Test ID Name Values
The function then becomes
check :: String -> [String] -> [Sample] -> Bool
check samplename result samples = or (map check' samples)
where check' :: Sample -> Bool
check' (Test _ name values) | name == samplename = result `elem` values
check' _ = False
Lastly since the result of check' is a Bool, and guards are Bool as well, we can refactor check' to a simpler form which doesn't need the fallthrough case
check :: String -> [String] -> [Sample] -> Bool
check samplename result samples = or (map check' samples)
where check' :: Sample -> Bool
check' (Test _ name values) = name == samplename && result `elem` values
This ** or (map .. ..)** pattern is so common that again there's a prelude function any which does this. check can then be further simplified to
check :: String -> [String] -> [Sample] -> Bool
check samplename result samples = any check' samples
where check' :: Sample -> Bool
check' (Test _ name values) = name == samplename && result `elem` values
This should do the trick:
data Sample = Test1 String [[String]]
| Test2 String [[String]]
sampleName :: Sample -> String
sampleName (Test1 name _) = name
sampleName (Test2 name _) = name
getData :: Sample -> [[String]]
getData (Test1 _ samples) = samples
getData (Test2 _ samples) = samples
check :: String -> [String] -> [Sample] -> Bool
check name needle samples = any doCheck samples
where
doCheck s = if sampleName s == name
then needle `elem` getData s
else False
If all names are supposed to be distinct, you can abort the search faster:
check2 :: String -> [String] -> [Sample] -> Bool
check2 name needle samples = go samples
where
go [] = False
go (s:ss) = if sampleName s == name
then needle `elem` getData s
else go ss
Testing:
*Main> check "Sample3" ["aborts"] tst
True
Comments on your version:
data Sample = Test1 (String,[[String]])
| Test2 (String,[[String]])
You don't need tuples here (see my code).
if( "True" `elem` final ) then True else False
In general, if expr then True else False can be always replaced with expr. And why do you use strings as booleans?
final = [x | sample <- samples,
x <- [ case sample of
Test1 (name,res) -> if name == samplename
&& (result `elem` res)
then "True" else "False"
Test2 (name, res) -> "False"]]
This can be rewritten without list comprehensions by using any:
check:: String -> [String] -> [Sample] -> Bool
check samplename result samples = any doCheck samples
where
doCheck (Test1 n s) = n == samplename && result `elem` s
doCheck _ = False