how would I go about deleting something from a list in Haskell - haskell

I want to make a function that given the name of a person deletes all entries in the phone book with that name.
type Name = String
type PhoneNumber = Int
type Person = (Name, PhoneNumber)
type PhoneBook = [Person]
delete::Name -> PhoneBook -> PhoneBook
how would go about this
would I use drop
I've been using this but I've been getting error
delete :: Name -> PhoneBook -> PhoneBook
delete name = (drop name xs)

Problem
First of all, if you're trying to delete one specific element from a list in Haskell you're usually doing something wrong. There are better types to do this, fromData.Map in this case to Data.Ord in many others.
However, if you want to do it your way, drop is not the function for it. If you look at its type, drop :: Int -> [a] -> [a] you'll realise it only drops the first n elements.
Solution
You can however use a higher order function, filter :: (a -> Bool) -> [a] -> [a] which does what it says on the tin. Just need to give it a function to filter what you need. You can use a lambda function with an easy pattern matching:
deletePerson :: Name -> [PhoneBook] -> [PhoneBook]
deletePerson na = filter (\(n, p) -> name /= n)
Also note that delete is a function in Data.List that deletes the first occurrence of something in a list

Related

Using Filter that requires multiple Input - Haskell

I'm relatively new to Haskell, and have been trying to learn it for the past few weeks, but have been stuck on Filters and Predicates, which I was hoping to get help with understanding.
I have come across a problem whereby I have a list of tuples. Each tuple consists of a (songName, songArtist, saleQty) and am required to remove a tuple from that list based on the user inputting the songName and SongArtist.
When returning the results, I understand I can remove a tuple by using the Filter function when returning the results. I have been doing some reading on it using LYAH. Its taught me that I have to use a Predicate (which is another function) to filter through my results. This has caught me off guard as I learnt a Filter function has type (a -> Bool) -> [a] -> [a], which means my input for the Filter needs to to be a Boolean and my output for my Predicate needs to be Boolean so it can be fed to the Filter.
This is a problem, as to filter my results from the list I need to input the songName and songArtist (both of which are String types) to the predicate when recursively going through the results, and output the songName and songArtist to the Filter to let it know which exact tuple needs to be removed from the list.
Am I going about this the wrong way or is there a better way I could go about this?
I learnt a Filter function has type (a -> Bool) -> [a] -> [a]
The filter :: (a -> Bool) -> [a] -> [a] takes two parameters, a predicate with signature a -> Bool, and a list of items, and it returns a list of items that satisfy the predicate. So the predicate is the first parameter.
which means my input for the Filter needs to to be a Boolean.
No the first parameter has type a -> Bool, so it is a function that maps an item a to a Bool, so a predicate.
You can for example create a function that checks if both the songName and songTitle match with:
filterSales :: String -> String -> [(String, String, Int)] -> [(String, String, Int)]
filterSales artist title items = filter p items
where p (artist', title', _) = artist == artist' && title == title'
Here p is thus the predicate, a function that maps a 3-tuple to a boolean. The predicate p will return True for a 3-tuple if the first two items are equal to the artist and title respectively.
This is a second answer and the existing one is great, so I'll show my alternate take; after all, two explanations can't be worse than one, right?
What filter expects of you is a function that will tell it one thing - should I keep the given element in the resulting collection?
The type of that function is (a -> Bool), and that's what we call a predicate.
In your specific case, assuming
type SongEntry = (SongName, SongArtist, SaleQty)
It's gonna be a function of type SongEntry -> Bool. Now, there could be a lot of such functions... maybe you want more than 100 sales?
hasMoreThan100Sales :: SongEntry -> Bool
hasMoreThan100Sales (_, _, sales) = sales > 100
To use it:
filter hasMoreThan100Sales songs
That should be easy enough. What if we wanted more than n sales? This is where Haskell's curry-by-default really shines. We can add one additional parameter:
hasMoreThanNSales :: Int -> SongEntry -> Bool
Which we can also read and understand as Int -> (SongEntry -> Bool). The implementation is straighforward at this point:
hasMoreThanNSales n (_, _, sales) = sales > n
And crucially, to get our previous "100" function, we just need to apply it:
hasMoreThanNSales 100 :: SongEntry -> Bool
This has the type we need to use it with the filter:
filter (hasMoreThanNSales 100) songs
At this point, you should understand it well enough to write your own predicate that can be parametrized in any way you want.
Oh, and one more thing that might be confusing. hasMoreThan100Sales is a predicate. hasMoreThanNSales is not, until you apply it with a value (e.g. 100) - (hasMoreThanNSales 100) is a predicate.

Haskell lookup table to return functions

Trying to extend "The Maybe monad" example on this page. Their lookup table phonebook:
phonebook :: [(String, String)]
phonebook = [ ("Bob", "01788 665242"),
("Fred", "01624 556442"),
("Alice", "01889 985333"),
("Jane", "01732 187565") ]
and there chained monad examples:
getRegistrationNumber :: String -- their name
-> Maybe String -- their registration number
getRegistrationNumber name =
lookup name phonebook >>=
(\number -> lookup number governmentalDatabase)
What happens if we want to return a function (that then returns a specific type) instead? So extending from their example, instead of looking up a registration number, we want to lookup lookup either their age, their ZIP, or the years that there property taxes were paid. Given these examples, an INT seems appropriate for the first two, and a List of Ints for the last. FIRST Question: since the lookup table has a type, must all of the return types of the functions be of the same type? I am assuming yes, but am unsure, hence the next question.
lets say that we write these 'finding' functions that return the same type [Int]. Maybe something like these:
getAge :: String -> Maybe [Int]
getAge phoneNumberString =
lookup name phonebook >>==
(\phoneNumberString -> lookup phoneNumberString governmentalAgeDatabase)
getZip :: String -> Maybe [Int]
getZip phoneNumberString =
lookup name phonebook >>==
(\phoneNumberString -> lookup phoneNumberString governmentalZipCodeDatabase)
getTaxPaidYears :: String -> Maybe [Int]
getTaxPaidYears phoneNumberString =
lookup name phonebook >>==
(\phoneNumberString -> lookup phoneNumberString governmentalTaxYearDatabase)
Now, assuming each of the the *Databases return an [Int] type, Second Question How do we write ONE function like lookupPersonsInformation that would return the appropriate information from what's typed in the input String, and given a lookup that returns the appropriate function, returns the information requested? Here is what I am trying to make work:
lookupAppropriateFunction :: [(String, String -> [Int])] --Here I want the second part
-- of the tuple to be the functions
lookupAppropriateFunction = [ ("age", getAge),
("zip", getZip),
("taxes", getTaxPaidYears) ]
lookupPersonsInformation :: String -> Maybe [Int]
lookupPersonsInformation nameAndInfo =
lookup ( words nameAndInfo!!0 ) >>=
( \phoneNumberString -> lookup ( words nameAndInfo!!1 ) lookupAppropriateFunction )
-- >> lookupPersonsInformation "Bob age"
[53] --Bob's age
-- >> lookupPersonsInformation "Fred zip"
[28202] --Fred's age
-- >> lookupPersonsInformation "Alice taxes"
[2010,2011,2013] --Alice's paid taxes years, It looks like she skipped 2012 :)
It is apparent that the errors propagate through to the end as Nothing, but I am unsure how to take the next step in applying this to a higher order function. Is it more in the parsing using words or in the structure of the lookup table that I want to return a function`
I ended up with going with something like the following:
-------------------------------------------------------------------------
intPusher :: String -> Stack -> Maybe Stack
-- ^ Takes a word, and tries to turn it into an Int, and push it onto the stack
intPusher word = case (reads word) of
[] -> \stak -> Nothing
[(x,"")] -> \stak -> Just (x:stak)
[(x,y)] -> \stak -> Nothing
-------------------------------------------------------------------------
dicLookup :: String -> Stack -> Maybe Stack
-- ^ Takes a word, and looks it up in the dictionary
dicLookup word = case (lookup word wordsTable) of
Nothing -> intPusher word
Just f -> f
-------------------------------------------------------------------------
wordsTable :: [(String, Stack -> Maybe Stack)]
-- ^ Checks the string against the commands
wordsTable = [ ("+", addIt)
,("-", subIt)
,("*", multIt)
,("/", divIt)
,("/MOD", modQuotIt)
,("MOD", modIt)
....
,("2DROP", drop2It) ]
-------------------------------------------------------------------------
interpretProgram :: String -> Maybe Stack
interpretProgram str = foldl (>>=) (Just[]) (map dicLookup (words str))
and for each tuple value in the dictionary, I provided the function declaration:
-------------------------------------------------------------------------
addIt :: Stack -> Maybe Stack
-- ^ Adds the first two elements of the stack
addIt stak = case stak of
x:y:xs -> Just (x + y:xs)
x:xs -> Nothing
_ -> Nothing
-------------------------------------------------------------------------
subIt :: Stack -> Maybe Stack
-- ^ Subtracts the first two elements of the stack
subIt stak = case stak of
x:y:xs -> Just (y - x:xs)
x:xs -> Nothing
_ -> Nothing
-------------------------------------------------------------------------
multIt :: Stack -> Maybe Stack
-- ^ Multiplies the first two elements of the stack
multIt stak = case stak of
x:y:xs -> Just (x * y:xs)
x:xs -> Nothing
_ -> Nothing
...
This works by taking a string, breaking it into individual 'words' (if possible, and returning Nothing if it can't) that are then passed into a dictionary to lookup the value of the word compared to the keys in the dictionary, thus acting like a lookup table. If the word is a key in the dictionary, it returns the value, which is a higher order function that does certain tasks (just like the words function, if the higher order function encounters an error, it will return Nothing).
When dealing with Monads, there are only TWO types of return values. Maybe AnyType and Nothing. An AnyType can be any type already declared in the module, or any basic type in Haskell (Int, Char, [Char], etc...). The trick is to return either a Maybe AnyType or a Nothing type. Since Haskell requires terminal declaration for if statements, it can be convention to 'catch' any potential errors and pass along the 'Nothing' type to the final return of a [grand]parent function.

Searching through tuple of more than 2 elements

How can I search a tuple based on the first element or second or third?
I know how to search tuple of two but how do i do it for more than two?
type Stuff = (String, String, Int)
testStuff :: [Stuff]
testStuff = [
("beans","black",5),
("cod","fish",4),
("coke","diet",3)
]
How can I write a function that will search "Stuff" and return the "int" value?
e.g searchStuff "beans" should return 5.
Since you haven't provided your function for searching in a list of pairs, I'm going to assume that you used lookup. Lets focus on find for your new function. find can be found in Data.List (and a more general version in Data.Foldable) and has the following type:
find :: (a -> Bool) -> [a] -> Maybe a
Now, if you need to find something in a list of triples based on the first element, you could use
find (\(a,_,_) -> a == "beans") testStuff
However, this will leave you with a Maybe Stuff. But since Maybe is an instance of Functor, it is easy to change the result to Maybe Int (and is left as an exercise).
The Prelude defines lookup to handle searching a list of pairs. Here's the definition:
-- | 'lookup' #key assocs# looks up a key in an association list.
lookup :: (Eq a) => a -> [(a,b)] -> Maybe b
lookup _key [] = Nothing
lookup key ((x,y):xys)
| key == x = Just y
| otherwise = lookup key xys
Can you see how one would define a similar function to search a list of triples?

Haskell introspecting a record's field names and types

Based on a recent exchange, I've been convinced to use Template Haskell to generate some code to ensure compile-time type safety.
I need to introspect record field names and types. I understand I can get field names by using constrFields . toConstr :: Data a => a -> [String]. But I need more than the field names, I need to know their type. For example, I need to know the names of fields that are of type Bool.
How do I construct a function f :: a -> [(String, xx)] where a is the record, String is the field name and xx is the field type?
The type should be available, along with everything else, in the Info value provided by reify. Specifically, you should get a TyConI, which contains a Dec value, from which you can get the list of Con values specifying the constructors. A record type should then use RecC, which will give you a list of fields described by a tuple containing the field name, whether the field is strict, and the type.
Where you go from there depends on what you want to do with all this.
Edit: For the sake of actually demonstrating the above, here's a really terrible quick and dirty function that finds record fields:
import Language.Haskell.TH
test :: Name -> Q Exp
test n = do rfs <- fmap getRecordFields $ reify n
litE . stringL $ show rfs
getRecordFields :: Info -> [(String, [(String, String)])]
getRecordFields (TyConI (DataD _ _ _ cons _)) = concatMap getRF' cons
getRecordFields _ = []
getRF' :: Con -> [(String, [(String, String)])]
getRF' (RecC name fields) = [(nameBase name, map getFieldInfo fields)]
getRF' _ = []
getFieldInfo :: (Name, Strict, Type) -> (String, String)
getFieldInfo (name, _, ty) = (nameBase name, show ty)
Importing that in another module, we can use it like so:
data Foo = Foo { foo1 :: Int, foo2 :: Bool }
foo = $(test ''Foo)
Loading that in GHCi, the value in foo is [("Foo",[("foo1","ConT GHC.Types.Int"),("foo2","ConT GHC.Types.Bool")])].
Does that give you the rough idea?

What to call a function that splits lists?

I want to write a function that splits lists into sublists according to what items satisfy a given property p. My question is what to call the function. I'll give examples in Haskell, but the same problem would come up in F# or ML.
split :: (a -> Bool) -> [a] -> [[a]] --- split lists into list of sublists
The sublists, concatenated, are the original list:
concat (split p xss) == xs
Every sublist satisfies the initial_p_only p property, which is to say (A) the sublist begins with an element satisfying p—and is therefore not empty, and (B) no other elements satisfy p:
initial_p_only :: (a -> Bool) -> [a] -> Bool
initial_p_only p [] = False
initial_p_only p (x:xs) = p x && all (not . p) xs
So to be precise about it,
all (initial_p_only p) (split p xss)
If the very first element in the original list does not satisfy p, split fails.
This function needs to be called something other than split. What should I call it??
I believe the function you're describing is breakBefore from the list-grouping package.
Data.List.Grouping: http://hackage.haskell.org/packages/archive/list-grouping/0.1.1/doc/html/Data-List-Grouping.html
ghci> breakBefore even [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6]
[[3,1],[4,1,5,9],[2],[6,5,3,5],[8,9,7,9,3],[2,3],[8],[4],[6],[2],[6]]
I quite like some name based on the term "break" as adamse suggests. There are quite a few possible variants of the function. Here is what I'd expect (based on the naming used in F# libraries).
A function named just breakBefore would take an element before which it should break:
breakBefore :: Eq a => a -> [a] -> [[a]]
A function with the With suffix would take some kind of function that directly specifies when to break. In case of brekaing this is the function a -> Bool that you wanted:
breakBeforeWith :: (a -> Bool) -> [a] -> [[a]]
You could also imagine a function with By suffix would take a key selector and break when the key changes (which is a bit like group by, but you can have multiple groups with the same key):
breakBeforeBy :: Eq k => (a -> k) -> [a] -> [[a]]
I admit that the names are getting a bit long - and maybe the only function that is really useful is the one you wanted. However, F# libraries seem to be using this pattern quite consistently (e.g. there is sort, sortBy taking key selector and sortWith taking comparer function).
Perhaps it is possible to have these three variants for more of the list processing functions (and it's quite good idea to have some consistent naming pattern for these three types).

Resources