Pattern-match list of tuple Strings - list

So I have a lost of String tuples in Haskell.
I declared a type for that:
type Book = [(String, String)]
Then I declared an empty book:
emptyBook :: Book
emptyBook = []
And now I want to create a function that inserts elements to a book. My solution:
insert :: String -> String -> Book -> Book
insert a b emptyBook = (a,b) : []
insert a b (x : xs)= (a, b) : (x:xs)
But the function insert is not working. The compiler loads the module but gives the warning 'Pattern match is redundant'.
Executing insert "a" "1" [("b","2")] gives [("a","1")]
instead of [("a","1"),("b","2")]
Do you know whats going wrong here?

I don't get why you:
use emptybook in your pattern matching part, instead of [];
why you repeat (x:xs) both in the left and in the right part of the expression;
make a distinction between an empty book and a non-empty book.
Why it doesn't work
Because Haskell, like many other languages uses variable scopes, and Haskell sees emptybook in your function as a variable. It does not see (at least not there) that emptybook is a function somewhere defined. So could have written:
insert a b c = (a,b) : []
as well (as second line in your function definition). Now since you define a variable c and did not put any constraints (guards, patterns,...) on it, it matches with everything: so a non-empty book as well. Therefore Haskell will always take the first line. In fact the compiler already warns you for this. It says:
haskell.hs:9:1: Warning:
Pattern match(es) are overlapped
In an equation for ‘insert’: insert a b (x : xs) = ...
This means that the last line of your function definition overlaps with the previous lines. In that case you have probably done something wrong.
Alternative
You can simply use:
insert :: String -> String -> book -> book
insert a b xs = (a,b) : xs
or even shorter:
insert :: String -> String -> book -> book
insert a b = (:) (a,b)
Furthermore types are usually denoted with a capital letter, so you better use Book instead of book.

The clause
insert a b emptyBook = (a,b) : []
defines insert as a function of three general arguments a, b and emptyBook. Well, the last isn't actually used, but that makes no difference – that clause will succeed, no matter what arguments you pass in.
The third argument also shadows the top-level definition emptyBook – basically this makes it so that within the scope of the function, emptyBook is now whatever book you pass in, no matter whether it's empty.
GHC can actually give a warning highlighting this real problem with your code, if you tell it to give generous warnings:
sagemuej#sagemuej-X302LA:~$ runhaskell -Wall /tmp/wtmpf-file2776.hs
/tmp/wtmpf-file2776.hs:7:12: Warning:
This binding for ‘emptyBook’ shadows the existing binding
defined at /tmp/wtmpf-file2776.hs:4:1
/tmp/wtmpf-file2776.hs:7:12: Warning:
Defined but not used: ‘emptyBook’
If you want emptyBook to be a constant that should be matched on, you have to make it explicit that this is not a newly-bound argument variable. A couple of options:
(Not recommended) use equality comparison instead of pattern matching
insert a b book
| book==emptyBook = (a,b) : []
insert a b (x : xs) = (a, b) : (x:xs)
We generally avoid equality comparison in Haskell – it's less general, less efficient and more error-prone than pattern matching.
(Very not recommended) use a C-preprocessor macro (Template Haskell would also work) to actually insert literally [] in that pattern matching. You can't have a variable named [], so this will do the right thing:
{-# LANGUAGE CPP #-}
#define emptyBook []
insert :: String -> String -> Book -> Book
insert a b emptyBook = (a,b) : []
insert a b (x : xs) = (a, b) : (x:xs)
Such macro definitions don't work very well with Haskell – they're completely oblivious of the languages scopes, can't be exported etc..
(Not very recommended) use pattern synonyms. Those are essentially the modern, Haskell-native way of achieving the behaviour I did above with a CPP macro:
{-# LANGUAGE PatternSynonyms #-}
pattern EmptyBook :: Book
pattern EmptyBook = []
insert :: String -> String -> Book -> Book
insert a b emptyBook = (a,b) : []
insert a b (x : xs) = (a, b) : (x:xs)
So, what would be the recommended solution? Well, as Willem Van Onsem says, you just don't need that clause at all – it's already a special case of the second clause!
insert :: String -> String -> Book -> Book
insert a b (x : xs) = (a, b) : (x:xs)
...which is the same as
insert a b (x : xs) = (a, b) : x : xs
or
insert a b xxs = (a, b) : xxs
or
insert a b = ((a, b) :)
or
import Data.Function.Pointless
insert=(:).:(,)

Related

How to apply a function in an iterable list

so I am new to OCaml and im having some trouble with lists.
What I have is a List of chars as follows:
let letters = [a;b;c;d]
I would like to know how can I iterate the list and apply a fuction that takes as arguments every possible combination of two chars on the list (do_someting char1 char2), for example: a and b (do_something a b), a and c .... d and b, d and c; never repeating the same element (a and a or c and c should not happen).
OCaml is a functional language, so we want to try to break down the procedure into as many functional pieces as we can.
Step 1 is "take a list of things and produce all combinations". We don't care what happens afterward; we just want to know all such combinations. If you want each combination to appear only once (i.e. (a, b) will appear but (b, a) will not, in your example), then a simple recursive definition will suffice.
let rec ordered_pairs xs =
match xs with
| [] -> []
| (x :: xs) -> List.append (List.map (fun y -> (x, y)) xs) (ordered_pairs xs)
If you want the reversed duplicates ((a, b) and (b, a)), then we can add them in at the end.
let swap (x, y) = (y, x)
let all_ordered_pairs xs =
let p = ordered_pairs xs in
List.append p (List.map swap p)
Now we have a list of all of the tuples. What happens next depends on what kind of result you want. In all likelihood, you're looking at something from the built-in List module. If you want to apply the function to each pair for the side effects, List.iter does the trick. If you want to accumulate the results into a new list, List.map will do it. If you want to apply some operation to combine the results (say, each function returns a number and you want the sum of the numbers), then List.map followed by List.fold_left (or the composite List.fold_left_map) will do.
Of course, if you're just starting out, it can be instructive to write these List functions yourself. Every one of them is a simple one- or two- line recursive definition and is very instructive to write on your own.

OCaml - Expression was expected of type 'b list

I'm trying to write a function that checks whether a set (denoted by a list) is a subset of another.
I already wrote a helper function that gives me the intersection:
let rec intersect_helper a b =
match a, b with
| [], _ -> []
| _, [] -> []
| ah :: at, bh :: bt ->
if ah > bh then
intersect_helper a bt
else if ah < bh then
intersect_helper at b
else
ah :: intersect_helper at bt
I'm trying to use this inside of the subset function (if A is a subset of B, then A = A intersect B):
let subset a_ b_ =
let a = List.sort_uniq a_
and b = List.sort_uniq b_
in intersect_helper a b;;
Error: This expression has type 'a list -> 'a list but an expression was expected of type 'b list
What exactly is wrong here? I can use intersect_helper perfectly fine by itself, but calling it with lists here does not work. From what I know about 'a, it's just a placeholder for the first argument type. Shouldn't the lists also be of type 'a list?
I'm glad you could solve your own problem, but your code seems exceedingly intricate to me.
If I understood correctly, you want a function that tells whether a list is a subset of another list. Put another way, you want to know whether all elements of list a are present in list b.
Thus, the signature of your function should be
val subset : 'a list -> 'a list -> bool
The standard library comes with a variety of functions to manipulate lists.
let subset l1 l2 =
List.for_all (fun x -> List.mem x l2) l1
List.for_all checks that all elements in a list satisfy a given condition. List.mem checks whether a value is present in a list.
And there you have it. Let's check the results:
# subset [1;2;3] [4;2;3;5;1];;
- : bool = true
# subset [1;2;6] [4;2;3;5;1];;
- : bool = false
# subset [1;1;1] [1;1];; (* Doesn't work with duplicates, though. *)
- : bool = true
Remark: A tiny perk of using List.for_all is that it is a short-circuit operator. That means that it will stop whenever an item doesn't match, which results in better performance overall.
Also, since you specifically asked about sets, the standard library has a module for them. However, sets are a bit more complicated to use because they need you to create new modules using a functor.
module Int = struct
type t = int
let compare = Pervasives.compare
end
module IntSet = Set.Make(Int)
The extra overhead is worth it though, because now IntSet can use the whole Set interface, which includes the IntSet.subset function.
# IntSet.subset (IntSet.of_list [1;2;3]) (IntSet.subset [4;2;3;5;1]);;
- : bool = true
Instead of:
let a = List.sort_uniq a_
Should instead call:
let a = List.sort_uniq compare a_

How do you pass list in a function parameter in haskell?

I know this question has been asked previously many times, and I've carefully read them, but it doesn't help me answer my type of question. I'm very new to Haskell,
Lets suppose we have the following:
filter p [] = []
filter p (h:l) = if (p h) then (h:(filter p l)) else (filter p l)
I have two questions
How can I call filter? All I know is that you pass p which is a list
I honestly don't know what is polymorphic type in general, and I cant figure out the polymorphic type of filter function.
I dont event understand what the function filter does in the if statement.
I would really appreciate if you can assist me in these two question.
There's plenty of resources to explain polymorphism, but I don't understand them.
p is not a list. p is short for predicate - usual terminology for a function taking a value and returning Bool. A list is the second argument to filter.
How do you call filter? You need to be reading one of the many haskell books out there. Right now. Some examples:
filter (> 5) [1, 6, 2, 8, 9, 3] -- [6, 8, 9]
filter (== 'z') "bazzz" -- "zzz" (String === [Char])
Here (> 5) :: Int -> Bool and (== 'z') :: Char -> Bool are predicates.
Polymorphic very loosely means it has the same form for different types:
filter :: (a -> Bool) -> [a] -> [a]
filter must work for any type a. The particular a is thus unknown to the implementer and the function cannot assume anything about a. a is chosen by the function user at the call site.
Btw. it's a fun little exercise to figure out what the following function is allowed to do:
:: a -> a
(Hint: there's only one thing it can do, and the name gives it away so I left it out)
You could also think of filter as a family of functions that are implemented exactly the same and only differ in a. Some of those could be:
:: (Int -> Bool) -> [Int] -> [Int]
:: (Char -> Bool) -> [Char] -> [Char]
:: (Foo -> Bool) -> [Foo] -> [Foo]
SO is not really a great place to start when learning new concepts. You should really grab a good book.
Before getting into any details about the implementation, we should settle on what the type of filter should be. Indeed you should generally design the type signature of a function without ever writing any actual code... but the damage is done here already. (As chi remarks, you could at this point actually ask GHCi what the type of your implementation is... but again, that's backwards so I won't delve into it.)
So what do you want filter to accomplish? Indeed it should take a list. You want to extract certain elements of that list depending on some property each of them might have; but filter shouldn't have any hard-baked assumptions what criteria to use, i.e. it should be the type of a list of any type of element. In Haskell, we write this [a] (which is actually shorthand for ∀ a . [a], read this as “for all element-types you might consider – say, A – it's a list of type [A]”).
What the actual criterion is should then be determined by an extra argument: the filtering predicate. For instance, you might want to filter all numbers smaller than 5 from a list of integers – you'd use the predicate (<5) :: Int -> Bool. In general, for your [a] list you need a predicate with the type a -> Bool. The end result would have the same list-elements as you passes in, so then filter would have the signature
filter :: [a] -> (a -> Bool) -> [a]
...except by convention, we put the predicate first, i.e.
filter :: (a -> Bool) -> [a] -> [a]
Let's check this makes sense... we'd want, for instance,
> filter ((<5) :: Int -> Bool) ([4,9,3] :: [Int])
in which case a ~ Int so
filter :: (Int -> Bool) -> [Int] -> [Int]
...yup, that makes sense.
Now you start actually worrying about the implementation. There are two general approaches:
Use some pre-existing combinators from a library to define the function. This is very of preferrable to start dabbling with manual recursion etc., but for now let's do everything by hand.
Deconstruct the list. Basically, there are only two ways a list can look: it can either contain something, or be empty. Empty is easy, because in this case you can't possibly return anything but an empty list again. You can't even use the predicate because there is no element you could check with it, hence just discard it by matching to _:
filter _ [] = []
(Alternatively as you had it, you can also match the predicate as p, but then people will wonder: what happened to the mouse p?)
If the list is not empty, we can straight pop one element from it:
filter p (h:l) = …
here, h is the head element and l is the rest of the list. So great, we now have an element of type a, let's see what the predicate tells us about it!
filter p (h:l) = if p h then … else …
So if the predicate is fulfilled we want to see h again in the final result, won't we? In fact the final result should start with h, thus
filter p (h:l) = if p h then h : … else …
The rest of the final result should have something to do with the rest of the input list. We could pass is as is then h : l else …, but that would mean we would only ever control the condition for the head element. No, we still have to filter the rest of the list as well:
filter p (h:l) = if p h then h : filter p l else …
Indeed we also want to do that even if the predicate is not fulfilled for h, except then we don't prepend it:
filter p (h:l) = if p h then h : filter p l else filter p l
And there you go:
filter _ [] = []
filter p (h:l) = if p h then h : filter p l else filter p l
This if looks a bit clunky, the preferred syntax are actually guards (which do the same thing)
filter _ [] = []
filter p (h:l)
| p h = h : filter p l
| otherwise = filter p l

Getting the head and tail of a custom list type in Haskell

I have a custom list type:
data NNList a = Sing a | Append ( NNList a) ( NNList a) deriving (Eq)
data CList a = Nil | NotNil ( NNList a) deriving (Eq)
I'm trying to implement a function that returns the head and tail of a list:
cListGet :: CList a -> Maybe (a, CList a)
My attempt:
cListGet :: CList a -> Maybe (a, CList a)
cListGet Nil = Nothing
cListGet xs#(NotNil nxs) =
case nxs of
Sing x -> (x, Nil)
Append l r -> ((fst $ cListGet (NotNil l)), (Append (snd $ cListGet (NotNil l)), r))
Which to me means keep going leftwards until I get a single. Once I get the single element (head), return the element and a Nil list. This Nil list is then combined with the list before it's returned as the final result.
I'm not even sure if the logic is 100% correct.
Well, people would normally refer to the data structure you have as a kind of tree, not as a list. But anyway...
Problem #1: Haskell is indentation sensitive, and your case expression is not indented. This leads to a parse error.
Problem #2, and the bigger one: you haven't understood how the Maybe type works yet. I get the impression that you think it works like nulls in more common languages, and this is throwing you off.
In a language like, say, Java, null is a value that can occur where most any other value can. If we have a method with the following signature:
public Foo makeAFoo(Bar someBar)
...then it is legal to call it either of these ways:
// Way #1: pass in an actual value
Bar theBar = getMeABar();
Foo result = makeAFoo(theBar);
// Way #2: pass in a null
Foo result2 = makeAFoo(null)
theBar and null are "parallel" in a sense, or said more precisely, they have the same type—you can replace one with the other in a program and it will compile in both cases.
In Haskell, on the other hand, the string "hello" and Nothing do not have the same type, and you cannot use one where the other goes. Haskell distinguishes between these three things:
A string that's required to be there: "hello" :: String
The absence of an optional string: Nothing :: Maybe String
The presence of an optional string: Just "hello" :: Maybe String
The difference between #1 and #3 is what you're systematically missing in your function. With Maybe a, in the cases where you do have a value you must use Just, which acts like a wrapper to signify "this isn't just an a, it's a Maybe a."
First place you're missing Just is the right hand sides of the case expressions, which we can fix like this:
-- This still fails to compile!
cListGet :: CList a -> Maybe (a, CList a)
cListGet Nil = Nothing
cListGet xs#(NotNil nxs) =
case nxs of
-- I added 'Just' here and in the next line:
Sing x -> Just (x, Nil)
Append l r -> Just (fst $ cListGet (NotNil l), (Append (snd $ cListGet (NotNil l)), r))
But this isn't the end of it, because you're doing fst $ cListGet (NotNil l), which suffers from the converse problem: cListGet returns Maybe (a, CList a), but fst works on (a, b), not on Maybe (a, b). You need to pattern match on the result of cListGet to test whether it's Nothing or Just (x, l'). (This same problem occurs also in your snd $ cListGet (NotNil l).)
Third, you're using your Append constructor wrong. You have it in the form of (Append foo, bar), which should have no comma between foo and bar. In Haskell this sort of thing will give you more confusing error messages than most other languages, because when Haskell sees this, it doesn't tell you "you made a syntax error"; Haskell is rather more literal than most languages, so it figures you're trying to make a pair with Append foo as the first element, and bar as the second one, so it concludes that (Append foo, bar) must have type (NNList a -> NNList a, NNList a).
The fourth and final problem: the problem you've set yourself is not clearly stated, and thus has no good answer. You say you want to find the "head" and "tail" of a CList a. What does that mean? In the case of the Haskell [a] type, with constructors [] and :, this is clear: the head is the x in x:xs, and the tail is the xs.
As I understand you, what you mean by "head" seems to be the leftmost element of the recursive structure. We could get that this way:
cListHead :: CList a -> Maybe a
cListHead Nil = Nothing
-- No need to cram everything together into one definition; deal with
-- the NNList case in an auxiliary function, it's easier...
cListGet (NotNil nxs) = Just (nnListHead nxs)
-- Note how much easier this function is to write, because since 'NNList'
-- doesn't have a 'Nil' case, there's no need to mess around with 'Maybe'
-- here. Basically, by splitting the problem into two functions, only
-- 'cListHead' needs to care about 'Maybe' and 'Just'.
nnListHead :: NNList a -> a
nnListHead (Sing a) = a
nnListHead (Append l _) = nnListHead l
So you might think that "the tail" is everything else. Well, the problem is that "everything else" is not a subpart of your CList or NNList. Take this example:
example :: CList Int
example = NotNil (Append (Append (Sing 1) (Sing 2)) (Sing 3))
The "head" is 1. But there is no subpart of the structure defined in example that contains 2 and 3 without containing 1 as well. You'd have to construct a new CList with a different shape than the original to get that. That's possible to do, but I don't see the value of it as a beginner's exercise, frankly.
In case it's not clear what I mean by a "subpart," think of the example as a tree:
NotNil
|
v
Append
/ \
v v
Sing Append
| / \
v v v
1 Sing Sing
| |
v v
2 3
Subpart = subtree.
Hint: try to rewrite this using only pattern matching and not equality-checking (==).
Edit:
First off, it's crucial that you understand what pattern matching is and how it works. I'd recommend going here and reading up; there are also plenty of other resources about this on the web (Google is your friend).
Once you've done that, here's another hint: First write a function nnListGet :: NNList a -> (a, CList a), then use it to implement cListGet.
Just to add to the other (very thorough) answers: It's good to realize that your custom list is a foldable structure. This means, it represents a sequence of values that can be combined together. Such datatypes can implement Foldable type class. In your case, it would be:
import Prelude hiding (foldr)
import Data.Foldable
data NNList a = Sing a | Append (NNList a) (NNList a) deriving (Eq)
data CList a = Nil | NotNil (NNList a) deriving (Eq)
instance Foldable NNList where
foldr f z (Sing x) = f x z
foldr f z (Append xs ys) = foldr f (foldr f z ys) xs
instance Foldable CList where
foldr _ z Nil = z
foldr f z (NotNil xs) = foldr f z xs
From that you'll get all functions defined in Data.Foldable for free, such as maximum/minimum, searching for an element etc.
For any Foldable, you can implement headMaybe that returns its first element by using First monoid. It's a very simple monoid that returns the left-most non-empty element. So if you fold all elements of a Foldable using this monoid, you'll get its first one:
import Data.Monoid
headMaybe :: (Foldable f) => f a -> Maybe a
headMaybe = getFirst . foldMap (First . Just)
(Alternatively, you can use foldr directly, using Maybe's instance of Alternative, which again returns the left-most non-empty element:
import Control.Applicative
headMaybe = foldr (\x y -> pure x <|> y) Nothing
.)
However, this doesn't solve the second part of your question - computing tailMaybe. This can't be defined in a generic way like headMaybe, and you'll need your custom function for that, as you did.
See also:
Fold on Wikipedia.
Foldable and Traversable on Haskell wiki.
Fold on Haskell wiki.
List processing on Haskell wikibook.
Why did you declare that in terms of two types? Here's a seemingly more appropriate type declaration with a correct function:
data CList a
= Nil
| Sing a
| Append (CList a) (CList a)
deriving (Eq)
headAndTail :: CList a -> Maybe (a, CList a)
headAndTail Nil = Nothing
headAndTail (Sing a) = Just (a, Nil)
headAndTail (Append a b) =
case headAndTail a of
Nothing -> headAndTail b
Just (head, tail) -> Just (head, Append tail b)

What does :: and ' mean in oCaml?

What doesx :: xs' mean?
I dont have much functional experience but IIRC in F# 1 :: 2 :: 3 :: [];; creates an array of [1,2,3]
so what does the ' do?
let rec sum xs =
match xs with
| [] -> 0
| x :: xs' -> x + sum xs'
I think sepp2k already answered most of the question, but I'd like to add a couple of points that may clarify how F#/OCaml compiler interprets the code and explain some common uses.
Regarding the ' symbol - this is just a part of a name (a valid identifier starts with a letter and then contains one or more letters, numbers or ' symbols). It is usually used if you have a function or value that is very similar to some other, but is in some way new or modified.
In your example, xs is a list that should be summed and the pattern matching decomposes the list and gives you a new list (without the first element) that you need to sum, so it is called xs'
Another frequent use is when declaring a local utility function that implements the functionality and takes an additional parameter (typically, when writing tail-recursive code):
let sum list =
let rec sum' list res =
match list with
| [] -> res
| x::xs -> sum' xs (res + x)
sum' list 0
However, I think there is usually a better name for the function/value, so I try to avoid using ' when writing code (I think it isn't particularly readable and moreover, it doesn't colorize correctly on StackOverflow!)
Regarding the :: symbol - as already mentioned, it is used to create lists from a single element and a list (1::[2;3] creates a list [1;2;3]). It is however worth noting that the symbol can be used in two different ways and it is also interpreted in two different ways by the compiler.
When creating a list, you use it as an operator that constructs a list (just like when you use + to add two numbers). However, when you use it in the match construct, it is used as a pattern, which is a different syntactic category - the pattern is used to decompose the list into an element and the remainder and it succeeds for any non-empty list:
// operator
let x = 0
let xs = [1;2;3]
let list = x::xs
// pattern
match list with
| y::ys -> // ...
The ' is simply part of the variable name. And yes foo :: bar, where foo is an element of type a and bar is a list of type a, means "the list that has foo as its first element, followed by the elements of bar". So the meaning of the match statement is:
If xs is the empty list, the value is 0. If xs is the list containing the item x followed by the items in xs' the value is x + sum xs'. Since x and xs' are fresh variables, this has the effect that for any non empty list, x will be assigned the value of the first element and xs' will be assigned the list containing all other elements.
Like others have said, the ' is a carryover from mathematics where x' would be said as "x prime"
It's idiomatic in ML-family languages to name a variable foo' to indicate that it's somewhat related to another variable foo, especially in recursions like your code sample. Just like in imperative languages you use i, j for loop indices. This naming convention may be a little surprising since ' is typically an illegal symbol for identifiers in C-like languages.
What does x :: xs' mean?
If you have two variables called x and xs' then x :: xs' creates a new list with x prepended onto the front of xs'.
I dont have much functional experience but IIRC in F# 1 :: 2 :: 3 :: [];; creates an array of [1,2,3]
Not quite. It's a list.
so what does the ' do?
It is treated as an alphabetical character, so the following is equivalent:
let rec sum xs =
match xs with
| [] -> 0
| x :: ys -> x + sum ys
Note that :: is technically a type constructor which is why you can use it in both patterns and expressions.