I'm trying to calculate the module of an index of a list.
list=[5,6,7,8]
a = elemIndex 7 list
b = mod a 2
Ideally, this would give me b = 0 since a = 2 (technically).
But I'm getting error messages since a is not 2 but Just 2.
You can do this with fmap :: Functor f => (a -> b) -> f a -> f b or its operator variant (<$>) :: Functor f => (a -> b) -> f a -> f b to apply a function to the item wrapped in the Just … data constructor:
b = (`mod` 2) <$> a
this will then return Just 0 when a is Just 2, and Nothing if the elemIndex returned a Nothing. This thus means that if elemIndex fails (because the index is out of range), b will be Nothing.
You can just use pattern matching with let to get to the inner part of the Maybe value when it is guaranteed to be Just _:
list = [5,6,7,8]
a = elemIndex 7 list
b = mod a 2
foo list = [b | n <- [5,6,7,8]
, let a = elemIndex n [5,6,7,8]
, let Just i = a
, let b = mod i 2]
= [b | n <- list
, let Just i = elemIndex n list
, let b = mod i 2]
= [b | (_, i) <- zip list [0..]
, let b = mod a 2]
= ls where ls = [0,1] ++ ls
bar list = [(n,b) | n <- list
, let Just i = elemIndex n list
, let b = mod i 2]
= [(n,b) | (n, i) <- zip list [0..]
, let b = mod i 2]
= zip list ls where ls = cycle [0,1]
Normally this kind of pattern matching is frowned upon since it is partial, i.e. can cause error if the value is actually Nothing, but here it is correct by construction.
But then really, why put it into a Just -- just use it as it is. And we did.
Related
My function rtnDryPlaces is supposed to return a list of all dry places if they were dry on a particular day - with day 1 being yesterday (last element) and day 7 being last week (first element).
type Name = String
type Location = (Float,Float)
type RainfallFigures = [Int]
type Place = (Name,Location,RainfallFigures)
testData=[("London", (51.5, -0.1), [0, 0, 5, 8, 8, 0, 0]),("Cardiff", (51.5 , -3.2),[12, 8, 15, 0, 0, 0, 2])]
rtnDryPlaces :: [Place] -> Int -> [Name]
rtnDryPlaces ((a,(b,c),d):xs) n
| d == [] = []
| (reverse d)!!n-1 == 0 = a:rtnDryPlaces xs n
demo 4 = print (rtnDryPlaces testData 2 )
The second guard reverses the list and returns the element at that index (index is day). If it returns 0, then the name a is appended to the list of names which have also returned 0 for that day. When the test data runs out, so does the rainfall data so I've set the stop condition to be when d = []
One of the problems is that the recursive calls will eventually reach the empty list, and you did not define a result for that:
rtnDryPlaces :: [Place] -> Int -> [Name]
rtnDryPlaces [] _ = []
rtnDryPlaces ((a,(b,c),d):xs) n
| d == [] = []
| (reverse d)!!n-1 == 0 = a:rtnDryPlaces xs n
But even then it will not work (yet). For example (reversed d)!!n-1 is interpreted as ((reverse d)!!n)-1, so it first takes the element at index n, and then it will subtract that element with 1. It will not take the n-1 element.
Furthermore if the (reversed d)!!(n-1) is not zero, then that guard will not "fire", and thus we get again an exhaustive pattern failure. We thus should add an otherwise at the end:
rtnDryPlaces :: [Place] -> Int -> [Name]
rtnDryPlaces [] _ = []
rtnDryPlaces ((a,_,d):xs) n
| d == [] = []
| (reverse d)!!(n-1) == 0 = a:rtnDryPlaces xs n
| otherwise = rtnDryPlaces xs n
Now this will give us a result:
Prelude> rtnDryPlaces testData 2
["London","Cardiff"]
But we can still make this more elegant by making use of filter and map:
rtnDryPlaces :: [Place] -> Int -> [Name]
rtnDryPlaces ps n = map (\(x,_,_) -> x) (filter p ps)
where p (_,_,d) | (0:_) <- drop (n-1) (reverse d) = True
| otherwise = False
or as #DanielWagner says, with list comprehension:
rtnDryPlaces :: [Place] -> Int -> [Name]
rtnDryPlaces ps n = [p | (p, _, d) <- ps, 0 <- take 1 . drop (n-1) . reverse $ d]
Here the take 1 . drop (n-1) will make a singleton list (given the list has enough elements) with the amount of rain for that day. If that then pattern matches with 0, we will yield p in the result. If the value for that day does not match with 0, or the list has not enough elements (then take 1 . drop (n-1) (reverse d) will yield an empty list), then that element is not emitted in the result.
I have such a code;
type El = Int
type Idx = Int
type Mat a = [[a]]
type Row a = [a]
mapr :: Idx -> (Row El -> Row El) -> Mat El -> Mat El
mapr ----- ??????
main = do
let a = [[2,1,-1,8],[-3,-1,2,-11],[-2,1,2,-3]]
let res = mapr 2 a
By using mapr function type, I want to update all values on a row on a matrix. Let's say I want to increase all the values in a specific row by 1. But the way I have explained mapr function is wrong. How should I modify my code to update values on a row on matrix a by using mapr function type?
I think it would be easiest to write this in a recursive function
mapr n _ [] = error $ "index: "++ show n ++" out of bounds"
mapr n f (x:xx) | n < 0 = error "negative index"
| n == 0 = f x : xx
| otherwise = x : mapr (n-1) f xx
the following code runs:
main :: IO ()
main = do let a = [[2,1,-1,8],[-3,-1,2,-11],[-2,1,2,-3]]
res = mapr 2 (const []) a
print res
you can replace const [] with all functions that work on rows - for example map (+1) as well.
Update:
Here is one version that uses zip to get indices for comparison, and I have changed the type of the function to work element-wise instead of row wise.
mapr' :: Idx -> (El -> El) -> Mat El -> Mat El
mapr' n f xx = map (mapIf n f) $ zip xx [0..]
where mapIf n f (row,idx) = if idx == n then (map f row)
else row
This is a bit terse so, would ask you to fire up ghci and evaluate the following expressions to get a feeling what it does:
zip ['a'..'z'] [0..]
map succ ['a'..'c'] and map (*3) [10,9..1]
let mapIf n f (row,idx) = if idx == n then (map f row) else row
mapIf 1 (*3) ([10,9..1],0)
mapIf 0 (*3) ([10,9..1],0)
map (map (*3)) [[1,2,3],[1,2,4]]
Your code contains several problems:
the mapr function should take three arguments (an index, a function that should be applied to the row, and a matrix), but the stub implementation contains only two
mapr idx f m = ...
the +1 in the definition of mapr should be replaced by the function that is provided as an argument to mapr
mapr idx f m = ... f ...
there should be parentheses around +1
(+1)
your mapr expects a function of type [a] -> [a]; +1 doesn't fit the bill, you need map (+1)
Altogether, we get:
type El = Int
type Idx = Int
type Mat a = [[a]]
type Row a = [a]
mapr :: Idx -> (Row El -> Row El) -> Mat El -> Mat El
mapr idx f m = [ m!!i | i <- [0.. (idx-1)]] ++ [(f (m !! idx))] ++ [m!!i | i <- [(idx+1) .. (length m-1)]]
main =
let
a = [[2,1,-1,8],[-3,-1,2,-11],[-2,1,2,-3]]
res = mapr 2 (\x -> map (\y -> y + 1) x) a
in
print res
I'm writing a function like this:
testing :: [Int] -> [Int] -> [Int]
testing lst1 lst2 =
let t = [ r | (x,y) <- zip lst1 lst2, let r = if y == 0 && x == 2 then 2 else y ]
let t1 = [ w | (u,v) <- zip t (tail t), let w = if (u == 2) && (v == 0) then 2 else v]
head t : t1
What the first let does is: return a list like this: [2,0,0,0,1,0], from the second let and the following line, I want the output to be like this: [2,2,2,2,1,0]. But, it's not working and giving parse error!!
What am I doing wrong?
There are two kinds of lets: the "let/in" kind, which can appear anywhere an expression can, and the "let with no in" kind, which must appear in a comprehension or do block. Since your function definition isn't in either, its let's must use an in, for example:
testing :: [Int] -> [Int] -> [Int]
testing lst1 lst2 =
let t = [ r | (x,y) <- zip lst1 lst2, let r = if y == 0 && x == 2 then 2 else y ] in
let t1 = [ w | (u,v) <- zip t (tail t), let w = if (x == 2) && (y == 0) then 2 else y] in
return (head t : t1)
Alternately, since you can define multiple things in each let, you could consider:
testing :: [Int] -> [Int] -> [Int]
testing lst1 lst2 =
let t = [ r | (x,y) <- zip lst1 lst2, let r = if y == 0 && x == 2 then 2 else y ]
t1 = [ w | (u,v) <- zip t (tail t), let w = if (x == 2) && (y == 0) then 2 else y]
in return (head t : t1)
The code has other problems, but this should get you to the point where it parses, at least.
With an expression formed by a let-binding, you generally need
let bindings
in
expressions
(there are exceptions when monads are involved).
So, your code can be rewritten as follows (with simplification of r and w, which were not really necessary):
testing :: [Int] -> [Int] -> [Int]
testing lst1 lst2 =
let t = [ if y == 0 && x == 2 then 2 else y | (x,y) <- zip lst1 lst2]
t1 = [ if (v == 0) && (u == 2) then 2 else v | (u,v) <- zip t (tail t)]
in
head t : t1
(Note, I also switched u and v so that t1 and t has similar forms.
Now given a list like [2,0,0,0,1,0], it appears that your code is trying to replace 0 with 2 if the previous element is 2 (from the pattern of your code), so that eventually, the desired output is [2,2,2,2,1,0].
To achieve this, it is not enough to use two list comprehensions or any fixed number of comprehensions. You need to somehow apply this process recursively (again and again). So instead of only doing 2 steps, we can write out one step, (and apply it repeatedly). Taking your t1 = ... line, the one step function can be:
testing' lst =
let
t1 = [ if (u == 2) && (v == 0) then 2 else v | (u,v) <- zip lst (tail lst)]
in
head lst : t1
Now this gives:
*Main> testing' [2,0,0,0,1,0]
[2,2,0,0,1,0]
, as expected.
The rest of the job is to apply testing' as many times as necessary. Here applying it (length lst) times should suffice. So, we can first write a helper function to apply another function n times on a parameter, as follows:
apply_n 0 f x = x
apply_n n f x = f $ apply_n (n - 1) f x
This gives you what you expected:
*Main> apply_n (length [2,0,0,0,1,0]) testing' [2,0,0,0,1,0]
[2,2,2,2,1,0]
Of course, you can wrap the above in one function like:
testing'' lst = apply_n (length lst) testing' lst
and in the end:
*Main> testing'' [2,0,0,0,1,0]
[2,2,2,2,1,0]
NOTE: this is not the only way to do the filling, see the fill2 function in my answer to another question for an example of achieving the same thing using a finite state machine.
I can use let inside other expression.
foo n = (let a = True in (\x -> a)) 3
foo' n | n == 1 = let a = True in a
| n /= 1 = False
But I can't do the same with where
foo n = ((\x -> a) where a = True) 3
foo' n | n == 1 = a where a = True
| n /= 1 = False
1:20: parse error on input `where'
Is it really impossible in haskell or just my mistake?
let is an expression while where is a clause. where is bound to syntactic constructs, let can be used anywhere expressions can.
You could of course write it like this:
foo n = ((\x -> a)) 3 where a = True
foo' n | n == 1 = a
| n /= 1 = False
where a = True
or like this:
foo n = (\a -> (\x -> a) 3) True
You need to put the where clause at the end:
foo n = ((\x -> a)) 3
where a = True
foo' n | n == 1 = a
| n /= 1 = False
where a = True
The difference is that let is an expression, whereas where requires some other construct to be bound to. See let vs where
let ... in ... is for introducing name bindings in an expression.
where is convenience syntax for giving local auxiliary definitions along with an equation. You can only use it as part of an equation (at the end), not in the middle of an arbitrary expression.
Their usage is not the same.
The claim that let is an expression is a bit off, it seems to me; in a do block it is a statement, though we say that there it abbreviates let ... in. The thing to say, I think, is
let_in_ :: Statement -> Expression -> Expression
_where_ :: Statement -> Statement -> Statement
Thus the first part of a let is a statement and can be modified by a where. So for example
foo n = (let a = b where b = True in (\x -> a)) 3
bip = do
let a = b where b = let c = d where d = True in c
return a
Similarly we can maybe say something like this:
case_of_ :: Expression -> [Statement] -> Expression
so that e.g.
z x = case even x of
True -> d where d = x + 1
False -> w - 1 where w = let a = x in a + 1
I am doing another Project Euler problem and I need to find when the result of these 3 lists is equal (we are given 40755 as the first time they are equal, I need to find the next:
hexag n = [ n*(2*n-1) | n <- [40755..]]
penta n = [ n*(3*n-1)/2 | n <- [40755..]]
trian n = [ n*(n+1)/2 | n <- [40755..]]
I tried adding in the other lists as predicates of the first list, but that didn't work:
hexag n = [ n*(2*n-1) | n <- [40755..], penta n == n, trian n == n]
I am stuck as to where to to go from here.
I tried graphing the function and even calculus but to no avail, so I must resort to a Haskell solution.
Your functions are weird. They get n and then ignore it?
You also have a confusion between function's inputs and outputs. The 40755th hexagonal number is 3321899295, not 40755.
If you really want a spoiler to the problem (but doesn't that miss the point?):
binarySearch :: Integral a => (a -> Bool) -> a -> a -> a
binarySearch func low high
| low == high = low
| func mid = search low mid
| otherwise = search (mid + 1) high
where
search = binarySearch func
mid = (low+high) `div` 2
infiniteBinarySearch :: Integral a => (a -> Bool) -> a
infiniteBinarySearch func =
binarySearch func ((lim+1) `div` 2) lim
where
lim = head . filter func . lims $ 0
lims x = x:lims (2*x+1)
inIncreasingSerie :: (Ord a, Integral i) => (i -> a) -> a -> Bool
inIncreasingSerie func val =
val == func (infiniteBinarySearch ((>= val) . func))
figureNum :: Integer -> Integer -> Integer
figureNum shape index = (index*((shape-2)*index+4-shape)) `div` 2
main :: IO ()
main =
print . head . filter r $ map (figureNum 6) [144..]
where
r x = inIncreasingSerie (figureNum 5) x && inIncreasingSerie (figureNum 3) x
Here's a simple, direct answer to exactly the question you gave:
*Main> take 1 $ filter (\(x,y,z) -> (x == y) && (y == z)) $ zip3 [1,2,3] [4,2,6] [8,2,9]
[(2,2,2)]
Of course, yairchu's answer might be more useful in actually solving the Euler question :)
There's at least a couple ways you can do this.
You could look at the first item, and compare the rest of the items to it:
Prelude> (\x -> all (== (head x)) $ tail x) [ [1,2,3], [1,2,3], [4,5,6] ]
False
Prelude> (\x -> all (== (head x)) $ tail x) [ [1,2,3], [1,2,3], [1,2,3] ]
True
Or you could make an explicitly recursive function similar to the previous:
-- test.hs
f [] = True
f (x:xs) = f' x xs where
f' orig (y:ys) = if orig == y then f' orig ys else False
f' _ [] = True
Prelude> :l test.hs
[1 of 1] Compiling Main ( test.hs, interpreted )
Ok, modules loaded: Main.
*Main> f [ [1,2,3], [1,2,3], [1,2,3] ]
True
*Main> f [ [1,2,3], [1,2,3], [4,5,6] ]
False
You could also do a takeWhile and compare the length of the returned list, but that would be neither efficient nor typically Haskell.
Oops, just saw that didn't answer your question at all. Marking this as CW in case anyone stumbles upon your question via Google.
The easiest way is to respecify your problem slightly
Rather than deal with three lists (note the removal of the superfluous n argument):
hexag = [ n*(2*n-1) | n <- [40755..]]
penta = [ n*(3*n-1)/2 | n <- [40755..]]
trian = [ n*(n+1)/2 | n <- [40755..]]
You could, for instance generate one list:
matches :: [Int]
matches = matches' 40755
matches' :: Int -> [Int]
matches' n
| hex == pen && pen == tri = n : matches (n + 1)
| otherwise = matches (n + 1) where
hex = n*(2*n-1)
pen = n*(3*n-1)/2
tri = n*(n+1)/2
Now, you could then try to optimize this for performance by noticing recurrences. For instance when computing the next match at (n + 1):
(n+1)*(n+2)/2 - n*(n+1)/2 = n + 1
so you could just add (n + 1) to the previous tri to obtain the new tri value.
Similar algebraic simplifications can be applied to the other two functions, and you can carry all of them in accumulating parameters to the function matches'.
That said, there are more efficient ways to tackle this problem.