Haskell Matrix Addition/Subtraction - haskell

this is what I have for matrix addition in Haskell
> add :: (Num a) => [[a]] -> [[a]] -> [[a]]
> add [] [] = []
> add (x:xs) (y:ys) = zipWith (+) x y : add xs ys
add [[1,2], [3,4]] [[5,6], [7,8]] gives me [[6,8],[10,12]]
However, I am trying do with one line instead
> add :: (Num a) => [[a]] -> [[a]] -> [[a]]
> add = map ((zipWith (+))
How come the map function doesn't work?

The map function doesn't work here because you're iterating over two lists instead of one. To iterate over two lists in parallel, you use zipWith, just like you are already doing for the inner loop.
Prelude> let add = zipWith (zipWith (+))
Prelude> add [[1, 2], [3, 4]] [[5, 6], [7, 8]]
[[6,8],[10,12]]

map takes in a single list: you're trying to give it two.
Try something like:
add = zipWith (zipWith (+))

Related

Haskell map list of indices to !! operator

When checking the type of map (!!) [1,2] in the ghci parser I get back: Num [a] => [Int -> a]. This has to do with the fact that the first argument of (!!) should be a list. However, I want to input a list of indices into the operator to get this type [a] -> [a].
EDIT
After the suggestion of #dfeuer to wrap it in another function I figured it would also be possible by using flip then. Checking the type of (map (flip (!!)) [1,2]) give the type [[c] -> c] which is what I am looking for.
If you have a list of indices and you want a function that selects those indices from an input list, then you want the map to iterate over the indices, not the input as you’re currently doing:
getIndices :: [Int] -> [a] -> [a]
getIndices indices input = map (input !!) indices
> getIndices [1, 2] "beans"
"ea"
If you want to write this in a more compact fashion using an inline list of indices, you can reduce away the input parameter like this:
\ input -> map (input !!) [1, 2]
\ input -> [1, 2] <&> (input !!) -- Data.Functor.(<&>) = flip (<$>)
\ input -> [1, 2] <&> (!!) input
\ input -> (([1, 2] <&>) . (!!)) input
([1, 2] <&>) . (!!)
In other words, flip map [1, 2] . (!!). But I think there isn’t anything to be gained from pointfree style in this case.
With a helper function (this name from lens):
flap, (??) :: Functor f => f (a -> b) -> a -> f b
flap f x = ($ x) <$> f
(??) = flap
infixl 1 ??
index :: Int -> [c] -> c
index = flip (!!)
This can be written:
> oneTwo = flap (index <$> [1, 2])
> oneTwo "beans"
"ea"
> index <$> [1, 2] ?? "bears"
"ea"
Or there’s always the boring but readable option of a list comprehension or do notation:
oneTwo xs = [xs !! i | i <- [1, 2]]
oneTwo xs = do { i <- [1, 2]; pure (xs !! i) }
I'm guessing you want
pickAndChoose :: [Int] -> [a] -> [a]
pickAndChoose indices values
= map (values !!) indices
Since !! takes time linear in the position of the element it retrieves, this will be quite inefficient if many indices are used, especially if they are relatively large. You may wish to consider using something like Data.Sequence instead of lists.

Haskell, 2 list to list of tuples pointwise

List1 = [a,b]
List2 = [1,2]
I want the result list to look like this [a1, b2]
Currently i have:
[(v,a) | v <- List1, a <- List2 ]
but that gives [a1, a2, b1, b2]
What you need is zip :: [a] -> [b] -> [(a, b)]. This iterates concurrently over the two lists, and makes 2-tuples for these items.
For example:
Prelude> zip ['a', 'b'] [1,2]
[('a',1),('b',2)]
Prelude> zip [1,4,2,5] "bacd"
[(1,'b'),(4,'a'),(2,'c'),(5,'d')]
zip will stop from the moment that one of the two lists is exhausted. So if one of the lists is infinite, and the other is finite, then the result will be a finite list for example.
You can also make use of the ParallelListComp extension to iterate over collections in parallel in a list comprehension expression:
{-# LANGUAGE ParallelListComp #-}
myzip :: [a] -> [b] -> [(a, b)]
myzip la lb = [(a, b) | a <- la | b <- lb ]
but here it does not make much sense to do that. If you want to do more "complex" zipping, then this extension is probably more useful.
So, you want a function of type [Char] -> [Int] -> [(Char, Int)]. Let me introduce you to Hoogle:
zip :: [a] -> [b] -> [(a, b)]
base Prelude Data.List GHC.List GHC.OldList, Cabal Distribution.Compat.Prelude.Internal, ghc GhcPrelude
. zip takes two lists and returns a list of corresponding pairs.
zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]
If one input list is short, excess elements of the longer list are discarded:
zip [1] ['a', 'b'] = [(1, 'a')]
zip [1, 2] ['a'] = [(1, 'a')]
zip is right-lazy:
zip [] _|_ = []
zip _|_ [] = _|_
zip is capable of list fusion, but it is restricted to its first list argument and its resulting list.
zip :: () => [a] -> [b] -> [(a, b)]
hspec Test.Hspec.Discover, base-compat Prelude.Compat, protolude Protolude, rio RIO.List RIO.Prelude, universum Universum.List.Reexport, dimensional Numeric.Units.Dimensional.Prelude, rebase Rebase.Prelude, ghc-lib-parser GhcPrelude, xmonad-contrib XMonad.Config.Prime, stack Stack.Prelude, LambdaHack Game.LambdaHack.Core.Prelude Game.LambdaHack.Core.Prelude, mixed-types-num Numeric.MixedTypes.PreludeHiding, heart-core Heart.Core.Prelude, intro Intro, hledger-web Hledger.Web.Import, tonalude Tonalude, brittany Language.Haskell.Brittany.Internal.Prelude
zip takes two lists and returns a list of corresponding pairs.
zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]
If one input list is short, excess elements of the longer list are discarded:
zip [1] ['a', 'b'] = [(1, 'a')]
zip [1, 2] ['a'] = [(1, 'a')]
zip is right-lazy:
zip [] _|_ = []
zip _|_ [] = _|_
zipExact :: Partial => [a] -> [b] -> [(a, b)]
safe Safe.Exact
zipExact xs ys =
| length xs == length ys = zip xs ys
| otherwise = error "some message"
zip :: () => [a] -> [b] -> [(a, b)]
numeric-prelude NumericPrelude NumericPrelude.Base, distribution-opensuse OpenSuse.Prelude
zip takes two lists and returns a list of corresponding pairs. If one input list is short, excess elements of the longer list are discarded. zip is right-lazy:
zip [] _|_ = []
(+*+) :: [a] -> [b] -> [(a, b)]
universe-base Data.Universe.Helpers
cartesianProduct (,)
...
The first hit
One other way can also be achieved by the ZipList type which is defined in Control.Applicative to lower the undeterministic approach to a simpler one to one mapping for the List types.
All you need is to import Control.Applicative and use the ZipList data constructor.
λ> getZipList $ (,) <$> ZipList "ab" <*> ZipList [1,2]
[('a',1),('b',2)]
getZipList is an accessor which extracts a proper list from the ZipList type.

Stack overflow when folding infinite lists?

Consider the following function:
(<.>) :: [[a]] -> [[a]] -> [[a]]
xs <.> ys = zipWith (++) xs ys
This essentially takes two two-dimensional arrays of as and concatanates them, left to right, e.x.:
[[1,2],[3,4]] <.> [[1,2],[3,4]] == [[1,2,1,2],[3,4,3,4]]
I would like to be able to write something like the following:
x = foldr1 (<.>) $ repeat [[1,2],[3,4]]
Which should make sense due to Haskell's lazy evaluation, i.e. we should obtain:
x !! 0 == [1,2,1,2,1,2,1,2...]
x !! 1 == [3,4,3,4,3,4,3,4...]
However, when I try to run this example with GHCi, either using foldr1 or foldl1, I either get a non-terminating computation, or a stack overflow.
So my question is:
What's going on here?
Is it possible to do what I'm trying to accomplish here with some function other than foldr1 or foldl1? (I'm happy if I need to modify the implementation of <.>, as long as it computes the same function)
Also, note: I'm aware that for this example, map repeat [[1,2],[3,4]] produces the desired output, but I am looking for a solution that works for arbitrary infinite lists, not just those of the form repeat xs.
I'll expand on what's been said in the comments here. I'm going to borrow (a simplified version of) the GHC version of zipWith, which should suffice for the sake of this discussion.
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith f [] _ = []
zipWith f _ [] = []
zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys
Now, here's what your computation ends up looking like, in it's glorious infinite form.
[[1, 2], [3, 4]] <.> ([[1, 2], [3, 4]] <.> ([[1, 2], [3, 4]] ... ) ... )
Okay, so the top-level is a <.>. Fine. Let's take a closer look at that.
zipWith (++) [[1, 2], [3, 4]] ([[1, 2], [3, 4]] <.> ([[1, 2], [3, 4]] ... ) ... )
Still no problems yet. Now we look at the patterns for zipWith. The first pattern only matches if the left-hand-side is empty. Welp, that's definitely not true, so let's move on. The second only matches if the right-hand-side is empty. So let's see if the right-hand-side is empty. The right-hand-side looks like
[[1, 2], [3, 4]] <.> ([[1, 2], [3, 4]] <.> ([[1, 2], [3, 4]] ... ) ... )
Which is what we started with. So to compute the result, we need access to the result. Hence, stack overflow.
Now, we've established that our problem is with zipWith. So let's play with it. First, we know we're going to be applying this to infinite lists for our contrived example, so we don't need that pesky empty list case. Get rid of it.
-- (I'm also changing the name so we don't conflict with the Prelude version)
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys
(<.>) :: [[a]] -> [[a]] -> [[a]]
xs <.> ys = zipWith' (++) xs ys
But that fixes nothing. We still have to evaluate to weak head normal form (read: figure out of the list is empty) to match that pattern.
If only there was a way to do a pattern match without having to get to WHNF... enter lazy patterns. Let's rewrite our function this way.
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' f ~(x:xs) ~(y:ys) = f x y : zipWith' f xs ys
Now our function will definitely break if given a finite list. But this allows us to "pretend" pattern match on the lists without actually doing any work. It's equivalent to the more verbose
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' f xs ys = f (head xs) (head ys) : zipWith' f (tail xs) (tail ys)
And now we can test your function properly.
*Main> let x = foldr1 (<.>) $ repeat [[1, 2], [3, 4]]
*Main> x !! 0
[1,2,1,2,1,2,1,2,1,...]
*Main> x !! 1
[3,4,3,4,3,4,3,4,3,...]
The obvious downside of this is that it will definitely fail on finite lists, so you have to have a different function for those.
*Main> [[1, 2], [3, 4]] <.> [[1, 2], [3, 4]]
[[1,2,1,2],[3,4,3,4],*** Exception: Prelude.head: empty list
zipWith is not -- in fact, it can't possibly be -- as lazy as you'd like. Consider this variation on your example:
GHCi> foldr1 (zipWith (++)) [ [[1,2],[3,4]], [] ]
[]
Any empty list of lists in the input will lead to an empty list of lists result. That being so, there is no way to know any of the elements of the result until the whole input has been consumed. Therefore, your function won't terminate on infinite lists.
Silvio Mayolo's answer goes through some potential workarounds for this issue. My suggestion is using non-empty-lists of lists, instead of plain lists of lists:
GHCi> import qualified Data.List.NonEmpty as N
GHCi> import Data.List.NonEmpty (NonEmpty(..))
GHCi> take 10 . N.head $ foldr1 (N.zipWith (++)) $ repeat ([1,2] :| [[3,4]])
[1,2,1,2,1,2,1,2,1,2]
N.zipWith doesn't have to deal with an empty list case, so it can be lazier.

Using map and filter function

I can't figure out how to implement the map and filter function for a matrix. Does anyone have any suggestions that would satisfy these tests?
-- | Matrix Tests
--
-- prop> mapMatrix (\a -> a - 3) (mapMatrix (+ 3) x) == x
--
-- >>> filterMatrix (< 3) matrix1
-- [[1,2],[2]]
-- >>> filterMatrix (> 80) []
-- []
-- >>> transpose' matrix2
-- [[1,4],[5,8]]
mapMatrix :: (a -> b) -> [[a]] -> [[b]]
mapMatrix f [list] = [map f list]
filterMatrix :: (a -> Bool) -> [[a]] -> [[a]]
filterMatrix = undefined
transpose' :: [[a]] -> [[a]]
transpose' = undefined
matrix1 = [[1 .. 10], [2 .. 20]]
matrix2 = [[1, 5], [4, 8]]
Some hints, but not a complete solution because this sounds like homework. mapmatrix and filterMatrix: write functions that work on one row of your matrix at a time, then map those onto the list of rows. transpose': one way to do this would be with a list comprehension that applies the !! operator to lists of indices, and another would be a recursive function that removes one row at a time from the input and adds one column at a time to the output.
Is filterMatrix supposed to return a list of lists that is not a valid matrix?

Nested loop equivalent

I want to do a list of concatenations in Haskell.
I have [1,2,3] and [4,5,6]
and i want to produce [14,15,16,24,25,26,34,35,36].
I know I can use zipWith or sth, but how to do equivalent of:
foreach in first_array
foreach in second_array
I guess I have to use map and half curried functions, but can't really make it alone :S
You could use list comprehension to do it:
[x * 10 + y | x <- [1..3], y <- [4..6]]
In fact this is a direct translation of a nested loop, since the first one is the outer / slower index, and the second one is the faster / inner index.
You can exploit the fact that lists are monads and use the do notation:
do
a <- [1, 2, 3]
b <- [4, 5, 6]
return $ a * 10 + b
You can also exploit the fact that lists are applicative functors (assuming you have Control.Applicative imported):
(+) <$> (*10) <$> [1,2,3] <*> [4,5,6]
Both result in the following:
[14,15,16,24,25,26,34,35,36]
If you really like seeing for in your code you can also do something like this:
for :: [a] -> (a -> b) -> [b]
for = flip map
nested :: [Integer]
nested = concat nested_list
where nested_list =
for [1, 2, 3] (\i ->
for [4, 5, 6] (\j ->
i * 10 + j
)
)
You could also look into for and Identity for a more idiomatic approach.
Nested loops correspond to nested uses of map or similar functions. First approximation:
notThereYet :: [[Integer]]
notThereYet = map (\x -> map (\y -> x*10 + y) [4, 5, 6]) [1, 2, 3]
That gives you nested lists, which you can eliminate in two ways. One is to use the concat :: [[a]] -> [a] function:
solution1 :: [Integer]
solution1 = concat (map (\x -> map (\y -> x*10 + y) [4, 5, 6]) [1, 2, 3])
Another is to use this built-in function:
concatMap :: (a -> [b]) -> [a] -> [b]
concatMap f xs = concat (map f xs)
Using that:
solution2 :: [Integer]
solution2 = concatMap (\x -> map (\y -> x*10 + y) [4, 5, 6]) [1, 2, 3]
Other people have mentioned list comprehensions and the list monad, but those really bottom down to nested uses of concatMap.
Because do notation and the list comprehension have been said already. The only other option I know is via the liftM2 combinator from Control.Monad. Which is the exact same thing as the previous two.
liftM2 (\a b -> a * 10 + b) [1..3] [4..6]
The general solution of the concatenation of two lists of integers is this:
concatInt [] xs = xs
concatInt xs [] = xs
concatInt xs ys = [join x y | x <- xs , y <- ys ]
where
join x y = firstPart + secondPart
where
firstPart = x * 10 ^ lengthSecondPart
lengthSecondPart = 1 + (truncate $ logBase 10 (fromIntegral y))
secondPart = y
Example: concatInt [1,2,3] [4,5,6] == [14,15,16,24,25,26,34,35,36]
More complex example:
concatInt [0,2,10,1,100,200] [24,2,999,44,3] == [24,2,999,44,3,224,22,2999,244,23,1024,102,10999,1044,103,124,12,1999,144,13,10024,1002,100999,10044,1003,20024,2002,200999,20044,2003]

Resources