I am having trouble writing a function which deletes an element from a list within a tuple.
The problem is, I would like the function to return the tuple. However, using the delete function from Data.List gives me a list.
Code:
-- type Value = Int
type Cell = (Int, [Int])
type Board = [Cell]
----------- your solution goes here --------------
-- solvem :: Board -> Board
-- solvem bd = ???
deleteCandidate :: Int -> Cell -> Cell
deleteCandidate cand c1 = delete cand (snd c1) -- This gives me trouble
updateNeighbors :: Cell -> Cell -> Cell
updateNeighbors c1 c2 | isNeighbor c1 c2 = deleteCandidate (head (snd c1)) c2
| otherwise = c2
Since data in Haskell is immutable, how would I return a tuple in deleteCandidate function? Would I have to reconstruct a Cell?
Simply pattern-match the tuple to extract the two pieces, operate on one of them, and then put it back together into a new tuple:
deleteCandidate :: Int -> Cell -> Cell
deleteCandidate cand (x, xs) = (x, delete cand xs)
Alternatively, since (a,) has a Functor instance, you could write
deleteCandidate :: Int -> Cell -> Cell
deleteCandidate cand = fmap (delete cand)
Or, shorter still, you could elide the explicit cand argument as well, and express deleteCandidate as a simple function composition:
deleteCandidate :: Int -> Cell -> Cell
deleteCandidate = fmap . delete
Personally I like the second version best, because I find it hard to think about how this composition works, and how it's different from (fmap delete).
Related
I need help to fix this Haskell function using pattern matching. It should only return true if every formula in the list of formulas is True. Here is what I have so far:
eval_list :: [Formula] -> Bool
eval_list (f:fx) = (eval_list f) && (eval_list fx)
here is how Formula is defined:
data Formula = And Formula Formula
| Not Formula
| Con Bool
deriving Show
You forgot to implement the case for an empty list. Since you each time recurse with a list item that is one item shorter than the previous call, eventually you will make a recursive call with an empty list.
Another problem is that you call eval_list f, but f is the first item of your list and thus a Formula object, not a list of Formulas. You likely should use a eval_formula to evaluate the formula.
You thus can implement this with:
eval_list :: [Formula] -> Bool
eval_list [] = True
eval_list (f:fx) = eval_formula f && eval_list fx
where you will have to implement eval_formula yourself.
You do not need to use explicit recursion. You can for example work with all :: Foldable f => (a -> Bool) -> f a -> Bool:
eval_list :: Foldable f => f Formula -> Bool
eval_list = all eval_formula
In order to evaluate a single Formula, you can use recursion, the function thus will look like:
eval_formula :: Formula -> Bool
eval_formula (And f1 f2) = …
eval_formula (Not f) = …
eval_formula (Con b) = …
where I leave implement the … parts as an exercise.
I have the following function:
blockToPicture :: Int -> [Picture] -> Picture
blockToPicture n [pic1,pic2,pic3] | n==0 = ...
| n==1 = ...
| otherwise = ...
If n==0 I want to select pic1, if n==1 I want to select pic2. Otherwise I want to select pic3. The problem is when one of the pictures doesn't load, so it doesn't appear on the list.
Instead of [pic1,pic2,pic3] I have something like [Pic1,Pic3].
When the function is supposed to select a picture that isn't on the list I want it to write "X" instead. For that I'll use the function
text "X" instead. The problem is that I don't know how to make it write the "X" instead of selecting the wrong picture.
Edit:
I've created the following function but for some reason I'm getting the error "Variable not in scope" to the pictures.
blocoParaPicture :: Int -> [Picture] -> Picture
blocoParaPicture b l | b==0 = if elem pic1 l then pic1 else text "X"
| b==1 = if elem pic2 l then pic2 else text "X"
| otherwise = if elem pic3 l then pic3 else text "X"
You can't just discard a picture that doesn't load; if you tried to load 3 pictures and end up with [some_pic, some_other_pic], how do you know which one didn't load? You need a list of type [Maybe Picture], with Just pic representing a successfully loaded picture and Nothing a failure. Then your function would look like
blockToPicture :: Int -> [Maybe Picture] -> Maybe Picture
blockToPicture _ [] = Nothing -- No pictures to choose from
blockToPicture 0 (Nothing:_) = Nothing -- Desired picture failed to load
blockToPicutre 0 (x:_) = x -- Found desired picture!
blockToPicture n (_:xs) = blockToPicture (n-1) xs -- This isn't it; try the next one
Adapting Jorge Adriano's suggestion to use lookup (which is a good one)
import Control.Monad
blockToPicture :: Int -> [Maybe Picture] -> Maybe Picture
blockToPicture n pics = join (lookup n (zip [0..] pics))
Since lookup :: a -> [(a,b)] -> Maybe b and b here is Maybe Picture, we have
a scenario where lookup returns Nothing if n is too big; Just Nothing if the desired picture fails to load, and Just (Just pic) if the desired picture is found. The join function from Control.Monad reduces the Maybe (Maybe Picture) value that lookup returns to the "regular" Maybe Picture that we want.
blocoParaPicture :: Int -> [Picture] -> Picture
blocoParaPicture b l | b==0 = if elem pic1 l then pic1 else text "X"
| b==1 = if elem pic2 l then pic2 else text "X"
| otherwise = if elem pic3 l then pic3 else text "X"
I'm getting the error "Variable not in scope" to the pictures.
The expression elem x xs checks if a given x is in a list xs. In your code when you write pic1, there's no such variable in scope, it isn't defined anywhere. In any case you don't want to search for a specific value in the list, rather you want to know if a given position "exists", that is if the list is long enough.
Also you can't just "write" inside a function with this type. In Haskell input and output is reflected on the types. This is a pure function, that takes some arguments and calculates a result, no side effects.
So what you can do here is return a Maybe Picture, which has values Nothing or Just pic depending whether you can return a picture or not. Or you can use Either String Picture, where values are of the form Left string or Right pic. Lets go for this latter option.
blocoParaPicture :: Int -> [Picture] -> Either String Picture
In terms of implementation we could diverge from the subject to get into a discussion of error management (since the problem is that access to a position may fail). But at this point I think it's best to avoid that detour so lets keep it (relatively) simple.
direct recursion (simplest)
The simplest most direct method would be direct recursion (as suggested by #chepner in the comments below).
blocoParaPicture :: Int -> [Picture] -> Either String Picture
blocoParaPicture _ [] = Left "X"
blocoParaPicture 0 (x:_) = Right x
blocoParaPicture n (x:xs) = safe (n-1) xs
making sure !! succeds
If you do want to use the standard access function !!, one way to go about it (but potentially inefficient in the general case) would be to construct a "safe" infinite list.
import Data.List
blocoParaPicture :: Int -> [Picture] -> Either String Picture
blocoParaPicture n xs = zs !! n
where zs = [Right x | x <- xs] ++ repeat (Left "X")
The list zs is an infinite list made up of two lists. First [Right x | x <- xs] which just like your original list, but each element x becomes Right x. Then from then onwards all elements are of the form Left "X" to indicate failure. In general the above approach can be inefficient. If you look for a big n in a list:
[Right 1, Right 2] ++ [Left "X", Left "X", ...
you are doing many unnecessary steps, since you could stop when the first list ends. But works just fine for small n.
using lookup
Yet another possibility, similar to your attempt to use the elem function, would be to use lookup on indices. This function is safe by design.
lookup :: Eq a => a -> [(a, b)] -> Maybe b
Following this approach you first construct the list,
[(0,x0), (1,x1), (2,x2) ...(k,xk)]
and then look for your given n to return the associated xn (or Nothing).
blocoParaPicture' :: Int -> [Picture] -> Maybe Picture
blocoParaPicture' n xs = lookup n (zip [1..] xs)
This returns Nothing when not found though. But if you wish to, you can convert to Either via maybe :: b -> (a -> b) -> Maybe a -> b.
blocoParaPicture :: Int -> [Picture] -> Either String Picture
blocoParaPicture n xs = maybe (Left "X") Right (lookup n (zip [1..] xs))
This is certainly a bit too complex when all you want is a simple access function. But can be handy in situations where things are not as simple.
I'm following the NLPWP Computational Linguistics site and trying to create a Haskell procedure to find collocations (most common groupings of two words, like "United States" or "to find") in a list of words. I've got the following working code to find bigram frequency:
import Data.Map (Map)
import qualified Data.Map as Map
-- | Function for creating a list of bigrams
-- | e.g. [("Colorless", "green"), ("green", "ideas")]
bigram :: [a] -> [[a]]
bigram [] = []
bigram [_] = []
bigram xs = take 2 xs : bigram (tail xs)
-- | Helper for freqList and freqBigram
countElem base alow = case (Map.lookup alow base) of
Just v -> Map.insert alow (v + 1) base
Nothing -> Map.insert alow 1 base
-- | Maps each word to its frequency.
freqList alow = foldl countElem Map.empty alow
-- | Maps each bigram to its frequency.
freqBigram alow = foldl countElem Map.empty (bigram alow)
I'm trying to write a function that outputs a Map from each bigram to [freq of bigram]/[(freq word 1)*(freq word 2)]. Could you possibly provide advice on how to approach it?
None of the following code is working, but it gives a vague outline for what I was trying to do.
collocations alow =
| let f key = (Map.lookup key freqBi) / ((Map.lookup (first alow) freqs)*(Map.lookup (last alow) freqs))
in Map.mapWithKey f = freqBi
where freqs = (freqList alow)
where freqBi = (freqBigram alow)
I'm very new to Haskell, so let me know if you've got any idea how to fix the collocations procedure. Style tips are also welcome.
Most of your code looks sane, except for the final colloctions function.
I'm not sure why there's a stray pipe in there after the equals sign. You're not trying to write any kind of pattern guard, so I don't think that should be there.
Map.lookup returns a Maybe key, so trying to do division or multiplication isn't going to work. Maybe what you want is some kind of function that takes a key and a map, and returns the associated count or zero if the key doesn't exist?
Other than that, it looks like you're not too far off having this work.
As I read it, your confusion stems from mistaking types, more or less. General advice: Use type signatures on all your top level functions and make sure they are sensible and what you expect of the function (I often do this even before implementing the function).
Let's take a look at your
-- | Function for creating a list of bigrams
-- | e.g. [("Colorless", "green"), ("green", "ideas")]
bigram :: [a] -> [[a]]
If you're giving in a list of Strings, you'll be getting a list of lists of Strings, so your bigram is a list.
You could decide to be more explicit (only allow Strings instead of sometype a - for the beginning at least). So, actually we get a list of Words an make a list of Bigrams from it:
type Word = String
type Bigram = (Word, Word)
bigram :: [Word] -> [Bigram]
For the implementation you can try to use readily available functions from Data.List, for example zipWith and tail.
Now your freqList and freqBigram look like
freqList :: [Word] -> Map Word Int
freqBigram :: [Word] -> Map Bigram Int
With this error messages of the compiler will be clearer to you. To point at it: Take care what you're doing in the lookups for the word frequencies. You're searching for the frequency of word1 and word2, and the bigram is (word1,word2).
Now you should be able to figure the solution out on your own, I guess.
First of all I advise you to have a look at the function
insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
maybe you'll recognize the pattern if used
f freqs bg = insertWith (+) bg 1 freqs
Next as #MathematicalOrchid already pointed out your solution is not too far from being correct.
lookup :: Ord k => k -> Map k a -> Maybe a
You already took care of that in your countElems function.
what I'd like to note that there is this neat abstraction called Applicative, which works really well for problems like yours.
First of all you have to import Control.Applicative if you're using GHC prior to 7.10 for newer versions it is already at your fingertips.
So what does this abstraction provide, similar to Functor it gives you a way to handle "side effects" in your case the possibility of the failing lookup resulting in Nothing.
We have two operators provided by Applicative: pure and <*>, and in addition as every Applicative is required to be a Functor we also get fmap or <$> which are the latter is just an infix alias for convenience.
So how does this apply to your situation?
<*> :: Applicative f => f (a -> b) -> f a -> f b
<$> :: Functor f => a -> b -> f a -> f b
First of all you see that those two look darn similar but with <*> being slightly less familiar.
Now having a function
f :: Int -> Int
f x = x + 3
and
x1 :: Maybe Int
x1 = Just 4
x2 :: Maybe Int
x2 = Nothing
one couldn't simply just f y because that wouldn't typecheck - but and that is the first idea to keep in mind. Maybe is a Functor (it is also an Applicative - it is even more an M-thing, but let's not go there).
f <$> x1 = Just 7
f <$> x2 = Nothing
so you can imagine the f looking up the value and performing the calculation inside the Just and if there is no value - a.k.a. we have the Nothing situation, we'll do what every lazy student does - be lazy and do nothing ;-).
Now we get to the next part <*>
g1 :: Maybe (Int -> Int)
g1 = Just (x + 3)
g2 :: Maybe (Int -> Int)
g2 = Nothing
Still g1 x1 wouldn't work, but
g1 <*> x1 = Just 7
g1 <*> x2 = Nothing
g2 <*> x1 = Nothing -- remember g2 is Nothing
g2 <*> x2 = Nothing
NEAT! - but still how does this solve your problem?
The 'magic' is using both operators ... for multi-argument functions
h :: Int -> Int -> Int
h x y = x + y + 2
and partial function application, which just means put in one value get back a function that waits for the next value.
GHCi> :type h 1
h 1 :: Int -> Int
Now the strange thing happens we can use with a function like h.
GHCi> :type h1 <$> x1
h1 <$> x1 :: Maybe (Int -> Int)
well that's good because then we can use our <*> with it
y1 :: Maybe Int
y1 = Just 7
h1 <$> x1 <*> y1 = Just (4 + 7 + 2)
= Just 13
and this even works with an arbitrary number of arguments
k :: Int -> Int -> Int -> Int -> Int
k x y z w = ...
k <$> x1 <*> y1 <*> z1 <*> w1 = ...
So design a pure function that works with Int, Float, Double or whatever you like and then use the Functor/Applicative abstraction to make your lookup and frequency calculation work with each other.
I'm trying to apply a tuple of functions to a tuple of values
λ> let foo = ((+1), (*3), ((:)5)) #Each function has type: a -> a
λ> let bar = (1, 5, [0]) #Each value of the corresponding tuple has type a
How do I implement:
toImplement foo bar = ?
such that:
λ> toImplement foo bar
-> (2, 15, [0,5]) # using foo and bar above
How can you implement this in general for any valid foo and bar (of the same length)?
[I looked at this problem, but it is implemented for a fixed type. I require a general implementation]
Motivation:
I'm trying to write folds efficiently.
let acc1 = \x acc -> x*x:acc
let acc2 = (+)
foldr (\x acc -> (acc1 x (fst acc), acc2 x ( snd acc))) ([],0) [1..10]
> ([1,4,9,16,25,36,49,64,81,100],55)
I have 2 different accumulators acc1 & acc2 that loop over the list exactly once. I'd like to do this for arbitrary number of accumulators all of whom have type a -> b [where a is the type of the elements in the list and b is of the type of the output of the accumulator]
It looks clumsy, having to access the tuples using fst and snd :/
As mentioned in the comments, haskell does not allow one to implement generic functions for tuples of arbitrary size. Hence you need to implement a particular function for every size separately.
Eg:
toImplement3 :: (b0 -> c0, b1 -> c1, b2 -> c2) -> (b0, b1, b2) -> (c0, c1, c2)
toImplement3 (f1, f2, f3) (a1, a2, a3) = (f1 a1, f2 a2, f3 a3)
I came across this very old sudoku code which seems greek to me coz of mainly this ugly type
type T = (Int,Int) -> [Int]
To understand this function for instance
mark :: ((Int,Int),Int) -> T -> T
mark (p#(i,j),n) s q#(x,y) =
if p==q then [n] else
if x==i || y==j || e x i && e y j then delete n $ s q else s q
where e a b = div (a-1) 3==div (b-1) 3
I can replace the T with the actual type
mark :: ((Int,Int),Int) -> (Int,Int)->[Int] -> (Int,Int)->[Int]
mark (p#(i,j),n) s q#(x,y) =
Now the type arguments don't seem to line up properly. p matches perfectly, but i get confused with "s". If I jump into the call for mark it's like this.....here the list I can easily see it's array of key value pairs with keys like (1,2) etc. These have been filtered for blanks or zeros in sudoku.
input :: String -> (Int,Int) -> [Int]
input s = foldr mark (const [1..9]) $
[(p,n) | (p,n) <- zip idx $ map read $ lines s >>= words, n>0]
The mark function is called with this list and accumulator which is a function (const [1..9]). This doesn't fit the type signature.
mark :: ((Int,Int),Int) -> (Int,Int)->[Int] -> (Int,Int)->[Int]
Problem with the code is that I can't see the actual result of the mark function which I still don't understand. When it's passed to a third function it gets some output. Any explanation on how to understand this sphagetti code?
A value of this type
type T = (Int,Int) -> [Int]
maps the coordinates of any sudoku cell (x,y) :: (Int,Int) into a set of the possible values such cell might have (represented as a list of digits [Int]).
The function const [0..9] maps any cell into the set of all digits. It acts as the initial state for a sudoku solver: at the beginning, assume any cell may have any digit.