Creating higher order functions using Haskell - function

I have recently been teaching myself Haskell, and one of my exercises was to implement a function that takes two arguments: a list and a single value. The function would check if the value is in the list twice or more. I cannot use the function element or member.
I tried removing the values that are not equal to the value. Then checking for the size of the new list if its more than 1 then it outputs True if not it outputs False. I having problem trying to use a function inside a function.
remove2 val [] = []
remove2 val (x:xs) = if ( not (x == val))
then remove2 val xs
else x:remove2 val xs
isMemberTwice :: (Eq val) => val -> [val] -> Bool
isMemberTwice val [] = False
isMemberTwice val (x:xs)
| ( >= (length (remove2 val [val])) 2) = True
| otherwise = a `isMemberTwice’` xs

A higher order function is a function that takes another function as argument or returns another function.
Your problem at hand is easily solvable using a short recursive function:
memtwice :: (Eq a) => a -> [a] -> Bool
memtwice value list = scan value list False
where scan _ [] _ = False
scan v (x:xs) True =
if v == x then True
else scan v xs True
scan v (x:xs) False =
scan v xs (v == x)
The scan is a function that carries state information (whether there has already been found one instance) as additional parameter.
One could rewrite this using higher order functions such as fold though I'm not sure how one could implement the short circuit behaviour (stopping as soon as two instances have been found) then.

Every function on a list can be written in this form:
f [] = ... -- also called the "base case"
f (a:as) = ... -- also called the recursive case
Let's apply this idea to writing a function which determine the number 3 appears in a list at least once:
hasA3 :: [Int] -> Bool
hasA3 [] = ...
hasA3 (a:as) = ...
Clearly hasA3 [] = False. I'll leave you to figure out how to write the recursive case. Hint: the function might have to check if a == 3.
Now let's write a function which determines if a list contains two or more threes. Again we start with the two cases:
hasTwo3s :: [Int] -> Bool
hasTwo3s [] = ...
hasTwo3s (a:as) = ...
Again, the base case is easy. Hints for the recursive case: you might have to check if a == 3 and then you might want to use the hasA3 function.

I will add to Daniel Jour's answer starting from its final note:
One could rewrite this using higher order functions such as fold
though I'm not sure how one could implement the short circuit
behaviour (stopping as soon as two instances have been found) then.
Let's transform the original code:
memtwice value list = scan value list False
where scan _ [] _ = False
scan v (x:xs) True =
if v == x then True
else scan v xs True
scan v (x:xs) False =
scan v xs (v == x)
Moving to boolean operators we get:
memtwice value list = scan value list False
where scan _ [] _ = False
scan v (x:xs) True = v == x || scan v xs True
scan v (x:xs) False = scan v xs (v == x)
Now, the parameter v is always value, so let's remove the parameter.
memtwice value list = scan list False
where scan [] _ = False
scan (x:xs) True = value == x || scan xs True
scan (x:xs) False = scan xs (value == x)
Introducing an explicit lambda for the last argument (not really needed, but helps readability):
memtwice value list = scan list False
where scan [] = (\_ -> False)
scan (x:xs) = \found -> if found
then value == x || scan xs True
else scan xs (value == x)
We now see that the last recursion pattern is a foldr: indeed we have a base-case definition for scan [], and the recursive case scan (x:xs) is defined only in terms of scan xs.
memtwice value list = foldr go (\_ -> False) list False
where go x next = \found -> if found
then value == x || next True
else next (value == x)
Note that foldr seems to be called with four parameters. This is because go x next produces a function, hence foldr go (\_ -> False) list does as well. We can now revert the explicit lambda.
memtwice value list = foldr go (\_ -> False) list False
where go x next True = value == x || next True
go x next False = next (value == x)
Finally, note that since || has short-circuiting behaviour, we did achieve an equivalent foldr to the original code.

There's an easier way really:
isMemberTwice needle haystack = n >= 2
where n = length $ filter (== needle) haystack
However, the downside with this approach is that, if you pass it a really long list, it'll evaluate the entire list, which is unnecessary: you only need to see if there are at least 2 occurrences of needle.
So a better solution is to avoid using length on the filtered list and instead just use pattern match: if it matches (_:_:_), there must be at least 2 occurrences:
isMemberTwice needle haystack = case occurrences of (_:_:_) -> True
_ -> False
where occurrences = filter (== needle) haystack

Related

Case insensitive without importing modules. I need the original output and not the lower ones

this is my code:
x = ["Hello","Nice","WELCOME"]
y = "HELLO"
app x y = filter (isInfixOf (map to Lower y)) (map (map toLower) x)
Output:
app x y -> ["hello"]
I need the original output ("HELLO") and not the lower one without importing modules.--
thank you
You should only map toLower in the filter condition, not perform a mapping on the elements itself:
app :: [String] -> String -> [String]
app xs y = filter (isInfixOf (map toLower y) . map toLower) xs
Note that using toLower x == toLower y is however not a good way to do case insensitive matching: certain characters do not have an uppercase/lowercase variant, and the rules of matching two strings in a caseinsensitive manner are more complicated. Usually one uses toCaseFold :: Text -> Text to normalize text to do case-insensitive matching. For example:
ghci> map toLower "straße" == map toLower "strasse"
False
ghci> toCaseFold "straße" == toCaseFold "strasse"
True

How do I find the index of a particular element within a List in DAML?

Say I have a List that looks like this:
let identifiers = ["ABC123", "DEF456", "GHI789"]
I want to know the index if the element "DEF456". What's the recommended way to accomplish this?
In daml 1.2 you can use the elemIndex : Eq a => a -> [a] -> Optional Int function in the DA.List standard library module like so:
daml 1.2 module MyModule where
import DA.List
indexOfElement = scenario do
let identifiers = ["ABC123", "DEF456", "GHI789"]
index : Optional Int = elemIndex "DEF456" identifiers
assert $ index == Some 1
return index
The findIndex function in the Base.List module in the standard library, does what you want.
daml 1.0 module FindIndex where
import Base.List
import Base.Maybe
test foo : Scenario {} = scenario
let
identifiers = ["ABC123", "DEF456", "GHI789"]
index: Maybe Integer = findIndex ((==) "DEF456") identifiers
assert $ index == Just 1
Under the hood most list manipulation in DAML, including findIndex is implemented using foldr and foldl.
-- Returns the index of the first element in the list satisfying the predicate, or M.Nothing if there is no such element.
def findIndex (f: a -> Bool) (xs: List a) : Maybe Integer =
headMay (findIndices f xs)
-- Returns the indices of all elements satisfying the predicate, in ascending order.
def findIndices (f: a -> Bool) (xs: List a) =
let work acc x =
let i = fst acc
let is = snd acc
tuple (i + 1) (if f x then cons i is else is)
reverse (snd (foldl work (tuple 0 nil) xs))

Coq: Defining a function by pattern matching on the arity of its argument

I want to define a function, the behavior of which depends on whether it's argument is (at least) an n-place function. A rudimentary (failed) attempt is
Definition rT {y:Type}(x:y) := ltac: (match y with
| _ -> _ -> _ => exact True
| _ => exact False end).
Check prod: Type -> Type -> Type.
Compute rT prod. (*= False: Prop*)
Print rT. (*rT = fun (y : Type) (_ : y) => False: forall y : Type, y -> Prop*)
As you see, rT maps everything to False. Why? The result remains the same if I replace y in the match clause w/ type of x
The function you want cannot exist within Gallina at the type you expect.
Your function is accepted, but if you print it, you can see its body is:
rT = fun (y : Type) (_ : y) => False
Gallina has no way of match-ing on a Type. There are ways to deal with n-ary functions, in such a way that you can inspect their arity, but it involves dependent types to statically capture the arity. For instance, for uniform n-ary functions:
https://coq.inria.fr/library/Coq.Numbers.NaryFunctions.html

Returning True for only 1 Function out of the list of 3

Since I'm pretty sure that using global variables in Haskell is frowned upon. I'm wondering is there anyway I can achieve the following?
-- list has elements that are odd
listHasOdd :: [Integer] -> Bool
-- list has elements that are even
listHasEven :: [Integer] -> Bool
--list has a length > 5
longList :: [Integer] -> Bool
-- Maps the function to a [Bool]
-- This function cannot be modified to fix the problem.
checkList :: [Integer] -> [Bool]
checkList xs = map (\ y -> y xs) listChecker
where listChecker = [listHasOdd, listHasEven, longList]
Is there anyway that I can ensure that only one of them returns true?
For example, [1,2,3,5], I would want only want listHasOdd to return
True which is [True, False, False]. (Evaluated from top to bottom).
Another example, [2,4,6,8,10,12,14], the returns should be [False, True, False].
In other words, checkList [1,2,3,5] returns [True, False, False], checkList[2,4,6,8,10,12,14] returns [False, True, False]
**The last function would always be False in my example, since it is unreachable.
I know I can do an if statement to check if the previous one is True but that seems like a pretty dumb idea. Or is that actually the way to do it? (Considering Haskell "remembers" the results of the previous function)
I don't see the point of it, but
foldr foo [] $ map ($ xs) [listHasOdd, listHasEven, longList]
where
foo True zs = True : map (const False) zs
foo False zs = False : zs
would produce the desired result, and it would only evaluate the functions until one of them returned True (or the end of the list of functions is reached).
This is the best I can come up with. It generalises relatively painlessly to handle the number of possible outcomes of a poker hand, for example.
data Outcome
= ListHasOdd
| ListHasEven
| LongList
| Nope
deriving Eq
outcomeFromList :: [Integer] -> Outcome
outcomeFromList xs
| any odd xs = ListHasOdd
| any even xs = ListHasEven
| 5 < length xs = LongList
| otherwise = Nope
listHasOdd = (ListHasOdd ==) . outcomeFromList
listHasEven = (ListHasEven ==) . outcomeFromList
longList = (LongList ==) . outcomeFromList
But even this is stupid: instead of generating a [Bool], why not just use the Outcome directly?
Edit: Or we could pay attention to what the functions mean.
listHasOdd xs = any odd xs
listHasEven [] = False
listHasEven xs = all even xs
-- if not all of them are even, then at least one must be odd,
-- and `listHasOdd` would give `True`
longList _ = False
-- if the list has at least 5 elements,
-- then either the list has at least one odd element
-- (and `listHasOdd` would give `True`)
-- or the list has at least five even elements
-- (and `listHasEven` would give `True`)

returning two different types from one function

How can I return values of multiple types from a single function?
I want to do something like:
take x y | x == [] = "error : empty list"
| x == y = True
| otherwise = False
I have a background in imperative languages.
There is a type constructor called Either that lets you create a type that could be one of two types. It is often used for handling errors, just like in your example. You would use it like this:
take x y | x == [] = Left "error : empty list"
| x == y = Right True
| otherwise = Right False
The type of take would then be something like Eq a => [a] -> [a] -> Either String Bool. The convention with Either for error handling is that Left represents the error and Right represents the normal return type.
When you have an Either type, you can pattern match against it to see which value it contains:
case take x y of
Left errorMessage -> ... -- handle error here
Right result -> ... -- do what you normally would
There is several solutions to your problem, depending on your intention : do you want to make manifest in your type that your function can fail (and in this case do you want to return the cause of the failure, which may be unnecessary if there is only one mode of failure like here) or do you estimate that getting an empty list in this function shouldn't happen at all, and so want to fail immediately and by throwing an exception ?
So if you want to make explicit the possibility of failure in your type, you can use Maybe, to just indicate failure without explanation (eventually in your documentation) :
take :: (Eq a) => [a] -> [a] -> Maybe Bool
take [] _ = Nothing
take x y = x == y
Or Either to register the reason of the failure (note that Either would be the answer to "returning two types from one function" in general, though your code is more specific) :
take :: (Eq a) => [a] -> [a] -> Either String Bool
take [] _ = Left "Empty list"
take x y = Right $ x == y
Finally you can signal that this failure is completely abnormal and can't be handled locally :
take :: (Eq a) => [a] -> [a] -> Bool
take [] _ = error "Empty list"
take x y = x == y
Note that with this last way, the call site don't have to immediately handle the failure, in fact it can't, since exceptions can only be caught in the IO monad. With the first two ways, the call site have to be modified to handle the case of failure (and can), if only to itself call "error".
There is one final solution that allows the calling code to choose which mode of failure you want (using the failure package http://hackage.haskell.org/package/failure ) :
take :: (Failure String m, Eq a) => [a] -> [a] -> m Bool
take [] _ = failure "Empty list"
take x y = return $ x == y
This can mimics the Maybe and the Either solution, or you can use take as an IO Bool which will throw an exception if it fails. It can even works in a [Bool] context (returns an empty list in case of failure, which is sometimes useful).
You can use the error functions for exceptions:
take :: Eq a => [a] -> [a] -> Bool
take [] _ = error "empty list"
take x y = x == y
The three answers you've gotten so far (from Tikhon Jelvis, Jedai and Philipp) cover the three conventional ways of handling this sort of situation:
Use the error function signal an error. This is often frowned upon, however, because it makes it hard for programs that use your function to recover from the error.
Use Maybe to indicate the case where no Boolean answer can be produced.
Use Either, which is often used to do the same thing as Maybe, but can additionally include more information about the failure (Left "error : empty list").
I'd second the Maybe and Either approach, and add one tidbit (which is slightly more advanced, but you might want to get to eventually): both Maybe and Either a can be made into monads, and this can be used to write code that is neutral between the choice between those two. This blog post discusses eight different ways to tackle your problem, which includes the three mentioned above, a fourth one that uses the Monad type class to abstract the difference between Maybe and Either, and yet four others.
The blog entry is from 2007 so it looks a bit dated, but I managed to get #4 working this way:
{-# LANGUAGE FlexibleInstances #-}
take :: (Monad m, Eq a) => [a] -> [a] -> m Bool
take x y | x == [] = fail "error : empty list"
| x == y = return True
| otherwise = return False
instance Monad (Either String) where
return = Right
(Left err) >>= _ = Left err
(Right x) >>= f = f x
fail err = Left err
Now this take function works with both cases:
*Main> Main.take [1..3] [1..3] :: Maybe Bool
Just True
*Main> Main.take [1] [1..3] :: Maybe Bool
Just False
*Main> Main.take [] [1..3] :: Maybe Bool
Nothing
*Main> Main.take [1..3] [1..3] :: Either String Bool
Right True
*Main> Main.take [1] [1..3] :: Either String Bool
Right False
*Main> Main.take [] [1..3] :: Either String Bool
Left "error : empty list"
Though it's important to note that fail is controversial, so I anticipate reasonable objections to this approach. The use of fail here is not essential, though—it could be replaced with any function f :: (Monad m, ErrorClass m) => String -> m a such that f err is Nothing in Maybe and Left err in Either.