Check and see if all elements of a list match a parameter - haskell

I want to make a function that checks to see if each row of the board for the Bert Bos puzzle is red one row at a time, but conceptually I'm having a hard time with this. Initially I make the board with all blue squares, but once the squares have been flipped with a flip function, the allRed function should be able to tell if the row is all red or not. Each row is represented by a list of colors, either Blue or Red
I know I should be using the all function, but I'm having some problems actually writing it out for my situation
Here is what I have so far:
generateboard :: Int -> [[Color]]
generateboard n = replicate n (replicate n Blue)
allRed :: [[Color]] -> Bool
let board = generateboard
allRed board = []
allRed board = all ([x:_ | x <- board, x == Red])
allRed board

There are many mistakes and misunderstandings here. I recommend reading any of the introductory Haskell materials to strengthen your basic understanding of the language. I will answer the question directly nonetheless.
generateboard looks great.
You are right to think all :: Foldable t => (a -> Bool) -> t a -> Bool will help us define allRed. If the type is confusing you can instead think of it as (a -> Bool) -> [a] -> Bool. The documentation says:
Determines whether all elements of the [list] satisfy the predicate.
To use all we need a predicate (a function) with type a -> Bool and a list of type [a]. We know what the predicate needs to be:
\x -> x == Red
Another way to write this is:
(==) Red
The predicate has type Color -> Bool and so our list must then have type [Color]. However, we have a list of type [[Color]]. There are two ways I can see to go about this.
The simpler idea is to observe that the board structure is irrelevant if all we care about is the cells. Therefore, we can flatten the structure with concat :: [[a]] -> [a]. Then our solution is thus:
allRed xs = all ((==) Red) (concat xs)
Which is also written:
allRed = all ((==) Red) . concat
Another solution is to observe that if all rows are red then the whole board must be red. This solution is:
allRed xs = all (all ((==) Red)) xs
Which is also written:
allRed = all (all ((==) Red))

First, the all function:
all :: (a -> Bool) -> [a] -> Bool
all p xs = ...
takes a function p representing a property and a list xs and tests if p x is true (i.e., if x has property p) for every element x of xs. (For example, all even [2,4,7] checks if all elements of the given list are even, and it returns False because even 7 equals False.) So, to use all, you need two arguments -- a list of items to check, and a function that checks one item.
Second, when faced with the problem of processing a data structure in Haskell (in this case [[Color]]), an excellent rule of thumb is to the deconstruct the structure from the outside in, using one function for each level of structure. You have an (outer) list of (inner) lists of colors, so start with the outer list, the list of rows.
How would you write a function that checks if all the rows in the outer list satisfy the property that they "contain only red colors"? Or, to put it more simply, how would you write this function using all if you already had a helper function redRow that expressed the property of a row having only red colors?
redRow :: [Color] -> Bool
redRow row = ...
If you can write allRed board using all, board, and redRow, you'll have reduced the problem to writing the definition of redRow, which operates on a simpler data structure, an (inner) list of colors.
To write redRow, you should likewise be able to use all again with a function expressing the property of a color being red:
isRed :: Color -> Bool
isRed col = ...
(or using an equivalent lambda or "section" directly).
In this case, another approach is possible, too -- you could use concat to "flatten" the outer and inner list together and then tackle the easier problem of checking if all colors in a big long list are red.

Related

Haskell taking in two list with a int and returning a tuple

I am trying to learn haskell and saw a exercise which says
Write two different Haskell functions having the same type:
[a] -> [b] -> Int -> (a,b)
So from my understanding the expressions should take in two lists, an int and return a tuple of the type of the lists.
What i tried so far was
together :: [a] -> [b] -> Int -> (a,b)
together [] [] 0 = (0,0)
together [b] [a] x = if x == a | b then (b,a) else (0,0)
I know I am way off but any help is appreciated!
First you need to make your mind up what the function should return. That is partly determined by the signature. But still you can come up with a lot of functions that return different things, but have the same signature.
Here one of the most straightforward functions is probably to return the elements that are placed on the index determined by the third parameter.
It makes no sense to return (0,0), since a and b are not per se numerical types. Furthermore if x == a | b is not semantically valid. You can write this as x == a || x == b, but this will not work, since a and b are not per se Ints.
We can implement a function that returns the heads of the two lists in case the index is 0. In case the index is negative, or at least one of the two lists is exhausted, then we can raise an error. I leave it as an exercise what to do in case the index is greater than 0:
together :: [a] -> [b] -> Int -> (a,b)
together [] _ = error "List exhausted"
together _ [] = error "List exhausted"
together (a:_) (b:_) 0 = (a, b)
together (a:_) (b:_) n | n < 0 = error "Negative index!"
| …
you thus still need to fill in the ….
I generally dislike those "write any function with this signature"-type excercises precisely because of how arbitrary they are. You're supposed to figure out a definition that would make sense for that particular signature and implement it. In a lot of cases, you can wing it by ignoring as many arguments as possible:
fa :: [a] -> [b] -> Int -> (a,b)
fa (a:_) (b:_) _ = (a,b)
fa _ _ _ = error "Unfortunately, this function can't be made total because lists can be empty"
The error here is the important bit to note. You attempted to go around that problem by returning 0s, but this will only work when 0 is a valid value for types of a and b. Your next idea could be some sort of a "Default" value, but not every type has such a concept. The key observation is that without any knowledge about a type, in order to produce a value from a function, you need to get this value from somewhere else first*.
If you actually wanted a more sensible definition, you'd need to think up a use for that Int parameter; maybe it's the nth element from each
list? With the help of take :: Int -> [a] -> [a] and head :: [a] -> a this should be doable as an excercise.
Again, your idea of comparing x with a won't work for all types; not every type is comparable with an Int. You might think that this would make generic functions awfully limited; that's the point where you typically learn about how to express certain expectations about the types you get, which will allow you to operate only on certain subsets of all possible types.
* That's also the reason why id :: a -> a has only one possible implementation.
Write two different Haskell functions having the same type:
[a] -> [b] -> Int -> (a,b)
As Willem and Bartek have pointed out, there's a lot of gibberish functions that have this type.
Bartek took the approach of picking two based on what the simplest functions with that type could look like. One was a function that did nothing but throw an error. And one was picking the first element of each list, hoping they were not empty and failing otherwise. This is a somewhat theoretical approach, since you probably don't ever want to use those functions in practice.
Willem took the approach of suggesting an actually useful function with that type and proceeded to explore how to exhaust the possible patterns of such a function: For lists, match the empty list [] and the non-empty list a:_, and for integers, match some stopping point, 0 and some categories n < 0 and ….
A question that arises to me is if there is any other equally useful function with this type signature, or if a second function would necessarily have to be hypothetically constructed. It would seem natural that the Int argument has some relation to the positions of elements in [a] and [b], since they are also integers, especially because a pair of single (a,b) is returned.
But the only remotely useful functions (in the sense of not being completely silly) that I can think of are small variations of this: For example, the Int could be the position from the end rather than from the beginning, or if there's not enough elements in one of the lists, it could default to the last element of a list rather than an error. Neither of these are very pleasing to make ("from the end" conflicts with the list being potentially infinite, and having a fall-back to the last element of a list conflicts with the fact that lists don't necessarily have a last element), so it is tempting to go with Bartek's approach of writing the simplest useless function as the second one.

Recursively merge list of lists based on shared elements

I don't know what the official technical name is for what I'm trying to do so I'll try to explain it as best I can.
Given a list of lists:
[[2,3,4,5], [1,5,6], [7,8,9]]
I want to union only the lists that have atleast one common element. So basically something like this:
simUnion :: [[Int]] -> [[Int]]
simUnion list = --...
--Result
-- [[1,2,3,4,5,6], [7,8,9]]
The problem I'm running into is running a match process between each element. Basically this is like the old math class problem where each person in a room must shake the hand of each other person. Ordinarily I'd accomplish this with a nested for loop, but how can I do this using Haskell's recursion?
Any help at all would be great!
If there is a finite number of distinct elements, you can turn the task inside out and make a Ord elem => Map elem [[elem]] out of your [[elem]] and then start iteratively merging the elements by the next algorithm:
while map isn't empty, take away a key, put it in the queue
get all the groups containing key popped from the queue
concat them and put into the queue (and in some accumulator, too)
if the queue got empty, the group is finished; take another key from the map
Note: The following post is written in literate Haskell. Save it as *.lhs and load it in GHCi. Also note that the discussed algorithm has runtime O(n²) and isn't optimal. A better approach would use union find or similar.
First, let us think about the tools we need if we want to group a single list x with the rest of the lists xs. We need to separate between the lists from xs that have an element in common with x, and we need to build the union of such lists. Therefore, we should import some functions from Data.List:
> import Data.List (partition, union)
Next, we need to check whether two lists are suitable to get merged:
> intersects :: Eq a => [a] -> [a] -> Bool
> intersects xs ys = any (`elem` ys) xs
Now we have all the tools at hand to define simUnion. The empty case is clear: if we don't have any lists, the result doesn't have any list either:
> simUnion :: Eq a => [[a]] -> [[a]]
> simUnion [] = []
Suppose we have at least two lists. We take the first one and check whether they have any element in common with any other list. We can do so by using partition:
> simUnion (x:xs) =
> let (common, noncommon) = partition (intersects x) xs
Now, common :: [[a]] will only contain those lists that have at least one element in common. There can be two cases now: either common is empty, and our list x has no element in common with any list from xs:
> in if null common
> then x : simUnion xs
We ignore uncommon here, since xs == uncommon in this case. In the other case, we need to build the union of all lists in common and x. This can be done with foldr union. However, this new list must be used in simUnion again, since it may have new intersections. For example, in
simUnion [[1,2], [2,3], [3,4]]
you want to end up with [[1,2,3,4]], not [[1,2,3],[3,4]]:
> else simUnion (foldr union x common : noncommon)
Note that the result will be unsorted, but you can map sort over it as a last step.
I have two main recommendations:
Don't think of it in terms of recursion! Instead, make liberal use of library utility functions.
Use appropriate data structures! Since you're talking about membership tests and unions, sets (from the Data.Set module) sound like they would be a better choice.
Applying those ideas, here's a fairly simple (though perhaps very naïve and suboptimal) solution:
import Data.Set (Set)
import qualified Data.Set as Set
simUnion :: Set (Set Int) -> Set (Set Int)
simUnion sets = Set.map outer sets
where outer :: Set Int -> Set Int
outer set = unionMap middle set
where middle :: Int -> Set Int
middle i = unionMap inner sets
where inner :: Set Int -> Set Int
inner set
| i `Set.member` set = set
| otherwise = Set.empty
-- | Utility function analogous to the 'concatMap' list function, but
-- for sets.
unionMap :: (Ord a, Ord b) => (a -> Set b) -> Set a -> Set b
unionMap f as = Set.unions (map f (Set.toList as))
Now using your example:
-- | This evaluates to:
--
-- >>> simUnion sampleData
-- fromList [fromList [1,2,3,4,5,6],fromList [7,8,9]]
sampleData :: Set (Set Int)
sampleData = Set.fromList (map Set.fromList sampleData')
where sampleData' :: [[Int]]
sampleData' = [[2,3,4,5], [1,5,6], [7,8,9]]
Ordinarily I'd accomplish this with a nested for loop, but how can I do this using Haskell's recursion?
You don't use recursion directly. You use higher-order functions like Set.map and unionMap. Note that these functions are analogous to loops, and that we're using them in a nested manner. Rule of thumb: imperative for loops very often translate to functional map, filter, reduce or similar operations. Nested imperative loops correspondingly often translate to nested use of such functions.

Is there a way to unmap in Haskell?

I'm writing a Haskell program. I've created a data type called measurement which is an array of doubles, it looks like this:
data Measurement = Measurement [Double] deriving (Show)
I have a function to cast to Measurement, it takes a list of lists of doubles and will cast it to a list of Measurements. It looks like this:
castToMeasurement :: [[Double]] -> [Measurement]
castToMeasurement = map Measurement
But now I want to do some opereations on the double values. So is there a way I can unmap to an array of doubles? So when I give it a Measurement (or list of Measurements), it will cast it to a list of Doubles (or a list of lists of double). Thanks!
Yes, there is:
data Measurement = Measurement { getMeasurement :: [Double] } deriving Show
castToMeasurement :: [[Double]] -> [Measurement]
castToMeasurement = map Measurement
castFromMeasurement :: [Measurement] -> [[Double]]
castFromMeasurement = map getMeasurement
Simple, isn't it?
Well, no and yes.
The way you phrase the question, whether there's a way to "unmap," the answer would have to be no, not in general. Suppose we have a list of strings:
example1 :: [String]
example1 = ["Hello", "cruel", "world"]
We can use map length to map this to the lengths of the strings:
example2 :: [Int]
example2 = map length example
-- value: [5, 5, 5]
But there is no way to "unmap" the value of example2 to get back the original example1. That would require there to be a function that, given the length, figured out which string the original list had—but that is clearly insufficient information!
But this gives us a hint about what sort of situation we can perform the "unmapping" that you want. If the function that we originally mapped with has an inverse, then we can map with that inverse to "undo" the effect of map. In your case, the Measurement constructor does have an inverse:
-- | The inverse of the 'Measurement' constructor. Laws:
--
-- > Measurement (getMeasurement x) == x
-- > getMeasurement (Measurement xs) == xs
getMeasurement :: Measurement -> [Double]
getMeasurement (Measurement xs) = xs
Since Measurement and getMeasurement are inverses it follows that map Measurement and map getMeasurement are as well, and so:
map getMeasurement (map Measurement xs) == xs
map Measurement (map getMeasurement xs) == xs
Sure you can. Here you can read more about it.
Let think about the function f:
f :: [Double] -> Measurement
f list = Measurement list
It just wraps the constructor of Measurement. I am using new function because it is much easier for me to think about function than about constructors.
Now you need the inverse function to f:
g :: Measurement -> [Double]
g (Measurement list) = list
So now you can construct function:
castFromMeasurement :: [Measurement] -> [[Double]]
castFromMeasurement = map g
It looks a bit ugly. So we can modify it using lambdas:
castFromMeasurement :: [Measurement] -> [[Double]]
castFromMeasurement = map (\(Measurement list) -> list)
But notice that it works only when your data type is not abstract (you have full access to constructor). Also you can redefine your data as follows:
data Measurement = Measurement { getMeasurement :: [Double] } deriving Show
In this case you already have function g = getMeasurement. So castFromMeasurement looks like:
castFromMeasurement :: [Measurement] -> [[Double]]
castFromMeasurement = map getMeasurement
More generally, you can unmap if and only if function f you used to map is reversable.
You got an answer to your question but let's bring math to the table and learn when and how it's possible to unmap.
We're pure functional programmers; that means that the functions we write are very mathematical (which is beyond awesome for many reasons, one of them: it's possible to write this answer). When dealing with functions, the function domain is every possible value of the input type (+ bottom for boxed types). The range, likewise, is every possible value of the output type.
What you are basically asking for is an inverse function for the function in your example (fmap Measurement).
An inverse function for function will "undo" what that function "did".
If I have value x and function f, and the inverse function of f is g, then by definition x = f(g(x))) = g(f(x))). This is probably gibberish, so think about the functions f = (+1) and g = subtract 1, and pick any integer for x. Let's say x=5 for example. f(5) = 6, and now notice how when you apply g -- g(6) = 5 -- you got the number you started off with.You "undid" f by applying the result to g, because g is the inverse of f.
Some functions don't have an inverse function (as Luis Casillas demonstrated in his answer here).
When your function does have, it's up to you to find it. If indeed possible, it's usually it's as difficult as the function you're inversing (e.g. like in the above, plus becomes minus. Like in your example too - your function was simple so the inverse was bound to also be simple).
An easy way to tell if there's an inverse function is to see if there exists a one-to-one mapping between the domain and the range. If there isn't - you lost data when you applied the function and you can't go back. So if an inverse function doesn't exist and you still need to go back, you should find other means. E.g. zip the original value before-hand ((x, f x)), and to get to the original value just apply fst.
Inverse Functions on Khan Academy
Inverse Functions on TheMathPage
Inverse Functions on Wikipedia

Storing values in a data structure Haskell

I'm trying to store randomly generated dice values in some data structure, but don't know how exactly to do it in Haskell. I have so far, only been able to generate random ints, but I want to be able to compare them to the corresponding color values and store the colors instead (can't really conceive what the function would look like). Here is the code I have --
module Main where
import System.IO
import System.Random
import Data.List
diceColor = [("Black",1),("Green",2),("Purple",3),("Red",4),("White",5),("Yellow",6)]
diceRoll = []
rand :: Int -> [Int] -> IO ()
rand n rlst = do
num <- randomRIO (1::Int, 6)
if n == 0
then printList rlst -- here is where I need to do something to store the values
else rand (n-1) (num:rlst)
printList x = putStrLn (show (sort x))
--matchColor x = doSomething()
main :: IO ()
main = do
--hSetBuffering stdin LineBuffering
putStrLn "roll, keep, score?"
cmd <- getLine
doYahtzee cmd
--rand (read cmd) []
doYahtzee :: String -> IO ()
doYahtzee cmd = do
if cmd == "roll"
then do rand 5 []
else putStrLn "Whatever"
After this, I want to be able to give the user the ability to keep identical dices (as in accumulate points for it) and give them a choice to re-roll the left over dices - I'm thinking this can done by traversing the data structure (with the dice values) and counting the repeating dices as points and storing them in yet another data structure. If the user chooses to re-roll he must be able to call random again and replace values in the original data structure.
I'm coming from an OOP background and Haskell is new territory for me. Help is much appreciated.
So, several questions, lets take them one by one :
First : How to generate something else than integers with the functions from System.Random (which is a slow generator, but for your application, performance isn't vital).
There is several approaches, with your list, you would have to write a function intToColor :
intToColor :: Int -> String
intToColor n = head . filter (\p -> snd p == n) $ [("Black",1),("Green",2),("Purple",3),("Red",4),("White",5),("Yellow",6)]
Not really nice. Though you could do better if you wrote the pair in the (key, value) order instead since there's a little bit of support for "association list" in Data.List with the lookup function :
intToColor n = fromJust . lookup n $ [(1,"Black"),(2,"Green"),(3,"Purple"),(4,"Red"),(5,"White"),(6,"Yellow")]
Or of course you could just forget this business of Int key from 1 to 6 in a list since lists are already indexed by Int :
intToColor n = ["Black","Green","Purple","Red","White","Yellow"] !! n
(note that this function is a bit different since intToColor 0 is "Black" now rather than intToColor 1, but this is not really important given your objective, if it really shock you, you can write "!! (n-1)" instead)
But since your colors are not really Strings and more like symbols, you should probably create a Color type :
data Color = Black | Green | Purple | Red | White | Yellow deriving (Eq, Ord, Show, Read, Enum)
So now Black is a value of type Color, you can use it anywhere in your program (and GHC will protest if you write Blak) and thanks to the magic of automatic derivation, you can compare Color values, or show them, or use toEnum to convert an Int into a Color !
So now you can write :
randColorIO :: IO Color
randColorIO = do
n <- randomRIO (0,5)
return (toEnum n)
Second, you want to store dice values (colors) in a data structure and give the option to keep identical throws. So first you should stock the results of several throws, given the maximum number of simultaneous throws (5) and the complexity of your data, a simple list is plenty and given the number of functions to handle lists in Haskell, it is the good choice.
So you want to throws several dices :
nThrows :: Int -> IO [Color]
nThrows 0 = return []
nThrows n = do
c <- randColorIO
rest <- nThrows (n-1)
return (c : rest)
That's a good first approach, that's what you do, more or less, except you use if instead of pattern matching and you have an explicit accumulator argument (were you going for a tail recursion ?), not really better except for strict accumulator (Int rather than lists).
Of course, Haskell promotes higher-order functions rather than direct recursion, so let's see the combinators, searching "Int -> IO a -> IO [a]" with Hoogle gives you :
replicateM :: Monad m => Int -> m a -> m [a]
Which does exactly what you want :
nThrows n = replicateM n randColorIO
(I'm not sure I would even write this as a function since I find the explicit expression clearer and almost as short)
Once you have the results of the throws, you should check which are identical, I propose you look at sort, group, map and length to achieve this objective (transforming your list of results in a list of list of identical results, not the most efficient of data structure but at this scale, the most appropriate choice). Then keeping the colors you got several time is just a matter of using filter.
Then you should write some more functions to handle interaction and scoring :
type Score = Int
yahtzee :: IO Score
yahtzeeStep :: Int -> [[Color]] -> IO [[Color]] -- recursive
scoring :: [[Color]] -> Score
So I recommend to keep and transmit a [[Color]] to keeps track of what was put aside. This should be enough for your needs.
You are basically asking two different questions here. The first question can be answered with a function like getColor n = fst . head $ filter (\x -> snd x == n) diceColor.
Your second question, however, is much more interesting. You can't replace elements. You need a function that can call itself recursively, and this function will be driving your game. It needs to accept as parameters the current score and the list of kept dice. On entry the score will be zero and the kept dice list will be empty. It will then roll as many dice as needed to fill the list (I'm not familiar with the rules of Yahtzee), output it to the user, and ask for choice. If the user chooses to end the game, the function returns the score. If he chooses to keep some dice, the function calls itself with the current score and the list of kept dice. So, to sum it up, playGame :: Score -> [Dice] -> IO Score.
Disclaimer: I am, too, very much a beginner in Haskell.
at first thought:
rand :: Int -> IO [Int]
rand n = mapM id (take n (repeat (randomRIO (1::Int, 6))))
although the haskellers could remove the parens

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