Using Bag in Haskell - list

I've been tasked with creating a Haskell program that contains a definition for a polymorphic datatype Bag and some simple functions, such as, converting a list to a bag and checking if two bags are the same.
My problem is I'm new to Haskell, so I'm not sure how to use Bags. Can anyone point me in the direction of some resources to do with Bags?

You can start by reading about algebraic data types.
First try to implement a simple algebraic data type like tree and then you can go and implement your own Bag data type. If you have any problems you can always ask here.
If this is not a homework then you can use already implemented Bags or use Data.Map to implement the same.
I have given the definition using Data.Map to compare your implementation which I suppose you would be writing using your own algebraic data types.
import qualified Data.Map as M
import Data.Map (Map)
newtype Bag a = Bag (Map a Int)
deriving (Show,Eq)
empty :: Bag a
empty = Bag $ M.empty
singleton :: a -> Bag a
singleton a = Bag $ M.singleton a 1
fromList :: (Ord a) => [a] -> Bag a
fromList = foldl f empty
where
f (Bag map) x = Bag $ M.insertWith (+) x 1 map
toList :: Bag a -> [a]
toList (Bag m) = concatMap f $ M.toList m
where f (a,b) = replicate b a
I have defined some very basic functions, but you can do things which you asked and a lot more, like
*Main> let x = fromList [1,2,3,2,2,1]
*Main> x
Bag (fromList [(1,2),(2,3),(3,1)])
*Main> let y = fromList [1,1,2,2,2,3]
*Main> y
Bag (fromList [(1,2),(2,3),(3,1)])
*Main> x==y
True

Related

Concatenation in Haskell and confusion with AList ([a] -> [a])

I have a project where we are improving the speed of concatenating a list in Haskell.
I'm new to Haskell and confused about AList ([a] -> [a]) Specifically how to convert my AppendedList to a regular List. Any help would be appreciated.
newtype AppendedList a = AList ([a] -> [a])
-- List[5] is represented as AList (\x -> 5:x)
-- This function takes an argument and returns the AppendedList for that
single :: a -> AppendedList a
single m = AList (\x -> m : x)
-- converts AppendedList to regular List
toList :: AppendedList a -> [a]
toList = ???
The toughest part is to not give you the answer directly :)
If you remember how lists are constructed in Haskell: [1, 2, 3] = 1 : 2 : 3 : [], with [] being the empty list.
Now let's "follow the types" (we also call this thought process TDD for Type Driven Development) and see what you have at hand:
toList :: AppendedList a -> [a]
toList (AList listFunction) = ???
and listFunction has the type [a] -> [a]. So you need to provide it a polymorphic list (i.e. a list of any type) so that it gives you back a list.
What is the only list of any type you know of? Pass this list to listFunction and everything will compile, which is a good indicator that it's probably right :D
I hope that helps without providing the plain answer (the goal is for you to learn!).
AppendedList a is a type.
AList f is a datum of that type, with some function f :: [a] -> [a] "inside it".
f is a function from lists to lists with the same type of elements.
We can call it with some_list :: [a] to get resulting_list :: [a]:
f :: [a] -> [a]
some_list :: [a]
-------------------------
f some_list :: [a]
resulting_list :: [a]
resulting_list = f some_list
We can use resulting_list as some_list, too, i.e..
resulting_list = f resulting_list
because it has the same type, that fits f's expectations (and because of Haskell's laziness). Thus
toList (...) = let { ... = ... }
in ...
is one possible definition. With it,
take 2 (toList (single 5))
would return [5,5].
edit: Certainly [5,5] is not the list containing a single 5. Moreover, take 4 ... would return [5,5,5,5], so our representation contains any amount of fives, not just one of them. But, it contains only one distinct number, 5.
This is reminiscent of two Applicative Functor instances for lists, the [] and the ZipList. pure 5 :: [] Int indeed contains just one five, but pure 5 :: ZipList Int contains any amount of fives, but only fives. Of course it's hard to append infinite lists, so it's mainly just a curiosity here. A food for thought.
In any case it shows that there's more than just one way to write a code that typechecks here. There's more than just one list at our disposal here. The simplest one is indeed [], but the other one is .... our list itself!

Writing test cases in Haskell for differing types

I've made a library that creates "list like" sequences, and of which many Prelude style functions are implemented. I want to write some test cases for this, to ensure my library is producing correct output, and I thought the easiest way to do this is write some functions, convert the results to lists and compare them to the Prelude results. Lets say we've got this:
import qualified MyLibrary as ML
import qualified Prelude as P
For example I may want the following testcase:
P.take 5 (P.enumFrom 1) == toList (ML.take 5 (ML.enumFrom 1))
Note that ML.enumFrom does not output a list, it outputs it's own datatype.
The above works fine, but notice how I'm "repeating myself" (TM). I have to ensure the left and right side are the same otherwise my test case is erroneous.
Is there a nice way to write test cases like this so I don't have to repeat myself?
The first problem that P.take and ML.take, etc., only look similar – in fact they are totally unrelated functions and the compiler doesn't know anything about their common behaviour. So, as #jd823592 proposed, we need to group them with a typeclass (I used a simple newtype wrapper so the example would be compilable):
import Prelude hiding (take, enumFrom)
import qualified Prelude as P (take, enumFrom)
newtype MySeq a = MySeq [a]
class Sequence s where
take :: Int -> s a -> s a
enumFrom :: Enum a => a -> s a
toList :: s a -> [a]
instance Sequence MySeq where
take n (MySeq xs) = MySeq (P.take n xs)
enumFrom n = MySeq (P.enumFrom n)
toList (MySeq xs) = xs
instance Sequence [] where
take = P.take
enumFrom = P.enumFrom
toList = id
Then we'll try to define some tests using now-unified functions from the class definition. They may just generate a Sequence of any type, and we'll then force them to produce explicit types.
test1 = doTest (take 5 $ enumFrom 1) -- the part in brackets is polymorphic
doTest :: (Eq a, Sequence s) => s a -> Bool
doTest test = ???
Now the second problem is that we pass a polymorphic function as a parameter and then need to instantiate it with different type parameters ([a] and MySeq a in this case). In standard Haskell 2010 it is impossible, but we can exploit the Rank2 (or RankN) extension:
{-# LANGUAGE Rank2Types #-}
<...>
doTest :: forall a . Eq a => (forall s . Sequence s => s a) -> Bool
doTest test = (test `asTypeOf` dummy1) == toList (test `asTypeOf` dummy2) where
dummy1 :: Eq a => [a]
dummy1 = undefined
dummy2 :: Eq a => MySeq a
dummy2 = undefined
This solution is a bit clumsy, but still works. Please feel free to improve.

You can find out if a list is a palindrome using (==) <*> reverse. How does it work?

I've tried to go through this using the types, but I'm still having difficulty understanding how it works.
Given:
> :t (==)
(==) :: Eq a => a -> a -> Bool
> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
> :t reverse
reverse :: [a] -> [a]
> :t (==) <*> reverse
(==) <*> reverse :: Eq a => [a] -> Bool
Intuitively I can understand that it combines the equality operator with reverse in such a way that it creates a function that checks if a reversed list is equal to the original, but that's really not much more information than what is already pretty obvious.
Could someone break down in more detail the internals of what is actually happening here?
Start with the type of (<*>)
> : t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Now (->) k is an instance of Applicative, with implementation
instance Applicative ((->) k) where
pure a = \_ -> a
f <*> g = \k -> f k (g k)
In particular, the type of (<*>) specialised to (->) k is
(<*>) :: (k -> a -> b) -> (k -> a) -> (k -> b)
So the application (==) <*> reverse is
(==) <*> reverse = \k -> (==) k (reverse k)
= \k -> k == reverse k
i.e. it checks that a list is equal to its reverse.
Chris Taylor's answer is just right, but another way of looking at it, that I find more intuitive, is this: what the Applicative instance of function types does is this:
"Feed" the same argument value to two functions with the same argument type;
Combine their results with another function.
So basically, if you have f :: t -> a and g:: t -> b, the Applicative instance lets you map functions h :: a -> b -> c over the a and b results, under the assumption that f and g will be fed the same argument.
So think of how you'd write the palindrome test in a non-convoluted way:
palindrome :: Eq a => [a] -> Bool
palindrome xs = xs == reverse xs
xs appears twice on the right hand side of the definition: once as argument to ==, and a second time as argument to reverse. This automatically tells you that there is likely a way to use the (->) t applicative instance to eliminate the duplication. A different, perhaps more intuitive attack on this would be to first rewrite the function to this:
palindrome xs = id xs == reverse xs
...where id x = x is the identity function, which just returns its argument (and is a standard library function). Now you can rewrite that using the standard Applicative idiom (f <$> a0 <*> ... <*> an) to this:
-- Function that feed the same argument value to both `id` and `reverse`,
-- then tests their results with `==`:
palindrome = (==) <$> id <*> reverse
And now we can ask if there is a way to get rid of id in that rewrite. Since <$> is just shorthand for fmap, we can study the Functor instance for (->) t, which is just another way to express function composition:
instance Functor ((->) t) where
-- Mapping `f` over a *function* `g` is just the same as composing `f`
-- on the results of `g`.
fmap f g = f . g
One of the most important properties of function composition is that for any function f:
f . id = f
So applying that to the version of palindrome above, we get:
-- Since `f . id = f` for all `f`, then `(==) <$> id` is just `(==)`:
palindrome = (==) <*> reverse

All combinations of elements of two lists in Haskell

Given two lists, [a, b] and [c, d], I'd like to get the following result:
[(a,c), (a,d), (b,c), (b,d)]
How can I do this in Haskell? Is there a built-in function for this, or should I implement one myself?
[ (x,y) | x<-[a,b], y<-[c,d] ]
This doesn't really require any further explanation, does it?
Applicative style all the way!
λ> :m + Control.Applicative
λ> (,) <$> ['a','b'] <*> ['c','d']
[('a','c'),('a','d'),('b','c'),('b','d')]
(I've eschewed any String syntactic sugar above, in order to stay close to your example.)
For information, (,) is special syntax for a function that takes two arguments and makes a pair out of them:
λ> :t (,)
(,) :: a -> b -> (a, b)
Edit: As noted by leftaroundabout in his comment, you can also use liftA2:
λ> :m + Control.Applicative
λ> let combine = liftA2 (,)
λ> combine "ab" "cd"
[('a','c'),('a','d'),('b','c'),('b','d')]
How can you do this in an imperative pseudocode?
for each element x in [a,b]:
for each element y in [c,d]:
produce (x,y)
In Haskell, this is written as
outerProduct xs ys =
do
x <- xs -- for each x drawn from xs:
y <- ys -- for each y drawn from ys:
return (x,y) -- produce the (x,y) pair
(following comments by leftaroundabout) this is of course extremely close to how liftM2 monadic combinator is defined, so in fact
outerProduct = liftM2 (,)
which is the same as liftA2 (,), and its various re-writes in terms of list comprehensions, concatMap function, >>=, <$> and <*> operators.
Conceptually though this is the stuff of the Applicative – which would be better named as Pairing, – because this pairing up of the elements of two "containers" ⁄ "carriers" ⁄ whatever is exactly what Applicative Functor is about. It just so happens that Haskell's do notation works for monads, and not (yet) for applicatives.
In some sense compile-time nested loops are Applicative ⁄ Pairing functors; Monads add the ability to create nested loops on the fly, depending on the values produced by an "outer" enumeration.
The most inuitive would be using list comprehension, other aproaches include using applicative functors:
(,) <$> [1,2,3] <*> [4,5,6]
So what does this do?
Remember that (,) :: a -> b -> (a, b) Takes two arguments and returns a tuple.
<$> is acutally fmap, (<$>) :: Functor f => (a -> b) -> f a -> f b
It takes a function and lift it. In this case it takes (,) and lift it to work on list. So let x = (,) <$> [1,2] would generate x :: [b -> (Integer, b)] which is the the list of functions that takes b and returns tuple with one fixed argument (Integer,b). Finally we apply it using <*> to generate all the combinations.
use List Comprehension:
s = [a,b]
s' = [c,d]
all_combinations = [(x,y) | x <- s, y <- s']

Iterate over all (Row, Column) possibilities?

This will be a TicTacToe implementation:
data Row = A | B | C deriving (Show, Read, Eq, Ord, Enum, Bounded)
data Column = X | Y | Z deriving (Show, Read, Eq, Ord, Enum, Bounded)
type Pos = (Row, Column)
data Player = Player String
data Field = Field [(Pos, Player)]
initialField :: Field
initialField = Field []
As you can see, the initialField is just an empty list and as players make moves, (pos, player) tupels will get added to the list. So far so good. But now I have trouble writing a possibleMoves :: Field -> [Pos] function to get the empty fields. How do I iterate over all Row, Column possibilities in Haskell? I get the feeling that my approach is wrong, but I'm new to Haskell so I have no better idea.
We can get all positions with list comprehensions (see also the other answers)
positions :: [Pos]
positions = [(r,c) | r <- [A,B,C], c <- [X,Y,Z]]
and all plays with a map
occupied :: Field -> [Pos]
occupied (Field l) = fmap fst l
Then we can define possibleMoves (you will need to import Data.List to get \\, list difference):
possibleMoves :: Field -> [Pos]
possibleMoves f = positions \\ (occupied f)
A somewhat more compact version takes advantage of list comprehension constraints:
possibleMoves :: Field -> [Pos]
possibleMoves (Field l) = [(r,c) | r <- [A,B,C], c <- [X,Y,Z], (r,c) `notElem` occupied]
where occupied = fmap fst l
All rows (ref = Getting a list of all possible data type values in Haskell):
Prelude> [(minBound :: Row) ..]
[A,B,C]
All columns:
Prelude> [(minBound :: Column) ..]
[X,Y,Z]
The compute the Cartesian product to find all possibilities (ref = Cartesian product of 2 lists in Haskell):
Prelude> [(x, y) | x <- [(minBound :: Row)..], y <- [(minBound :: Column)..]]
[(A,X),(A,Y),(A,Z),(B,X),(B,Y),(B,Z),(C,X),(C,Y),(C,Z)]
If you want an ultra short, "ulta-Haskelly" version:
enumAll :: (Bounded a, Enum a) => [a]
enumAll = [minBound..maxBound]
positions :: [Pos]
positions = (,) <$> enumAll <*> enumAll
(You'll also need to import Control.Applicative for the <$> and <*> operators)
Then in ghci:
*Main> positions
[(A,X),(A,Y),(A,Z),(B,X),(B,Y),(B,Z),(C,X),(C,Y),(C,Z)]
How the hell does this work?
enumAll is just a generic helper function (I was surprised not to be able to quickly find it in the standard libraries; it's possible I missed it and you don't even need to define it yourself). It gives you a list of every possibility for any bounded enumerable type. It's fairly straightforward; Bounded means the type has minBound and maxBound, Enum means you can use the [a..b] syntax to get a list of everything from a to b.
(,) is just the pair-building function. If you type :t (,) into ghci, it tells you (,) :: a -> b -> (a, b).
Now, what about those weird <$> and <*> symbols? They're basically "special" forms of function application. So you can read it almost like we're simply applying (,) to the two arguments enumAll and enumAll. But because it's "special" application, it doesn't just give us the pair (enumAll, enumAll).
What we're doing here is using the Applicative instance for lists. I'm not going to get into that in full detail, but what this does is help us think that [Row] is not a list of row values, but rather a single "unknown" row value. It's a value that could be any element of the list, but we don't know which one. The technical term usually used for this is that [Row] can be thought of as a nondeterministic Row; it's a Row value that could be a number of possibilities, but we haven't been able to determine which one it actually is.
So what we're doing is applying the function (,) (which just takes two arguments to build a pair), to two nondeterminsitic values, to get a nondeterminsitic pair (this is where we need the "special" version of function application with <$> and <*>; if we apply (,) normally with (,) enumAll enumAll or build the pair directly with (enumAll, enumAll) then all we get is a normal pair of nondeterminsitic values, instead of a nondeterministic pair of normal values - ([a], [b]) vs [(a, b)]) . And if I take a pair from all possibilities of one bounded enum and all possibilities of another bounded enum, then I should get all possibilities of pair! Which is exactly what happens.
The type signature positions :: [Pos] is actually necessary here. That's what tells Haskell we're building a list of (Row, Column) pairs rather than any other kind of pair of enums, which is how it knows that the first enumAll was enumerating all rows and the second wsa enumerating all columns. The most general type (,) <$> enumAll <*> enumAll is actually (Enum a, Bounded a, Enum b, Bounded b) => [(a, b)], which will work just fine but is a pain to work with interactively in ghci because you'll keep getting ambiguous type variables whenever you try to print things.