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)
Related
This question already has answers here:
Haskell: Double every 2nd element in list
(6 answers)
Closed 4 years ago.
If f1 and f2 are two functions, I want to be able to invoke f1 and f2 alternatively on a list. I came up with following:
[ ((snd p) (fst p)) | p <- zip [1,2,3,4] (repeat [f1, f2])]
The above does not work:
Couldn't match expected type ‘Integer -> t’
with actual type ‘[Integer -> Integer]’
• The function ‘snd’ is applied to two arguments,
How do I apply function which is evaluated as second of the pair?
Update:
Applying the function was right, as pointed out in the answers and comments. The problem was with: zip [1,2,3,4] (repeat [f1, f2])
You want to use cycle and zipWith:
zipWith id (cycle [f1, f2]) [1..4]
cycle makes a finite list infinite by, well, cycleing it:
cycle [f1, f2] = [f1, f2, f1, f2, f1, f2, f1, f2, ...]
-- it is equivalent to (but is not implemented by)
cycle = concat . repeat
-- repeat :: a -> [a]; repeats a single element forever
-- concat :: [[a]] -> [a]; concatenates all the lists together
-- concat . repeat :: [a] -> [a]; concatenates infinitely many copies of the input
-- this forms a (inefficient) cycle
zipWith id takes a list of functions and a list of arguments and applies them pairwise:
zipWith id [f1, f2, f1, f2, ...]
[1 , 2 , 3 , 4 ]
= [id f1 1, id f2 2, id f1 3, id f2 4]
= [f1 1, f2 2, f1 3, f2 4]
Note that ($) = id (just a more restricted type), so you can also write zipWith ($).
Can you explain how exactly mapAccumR works, the kind of problems it solves,and how it's different from foldr. I have a hard time picturing how it works.
This is a good question. I wish the documentation was a bit nicer around this. I recently had a use for them myself, so hopefully I can explain from the perspective of someone who also had some trouble understanding how they worked.
So, the type signature of mapAccumR is:
Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c)
Let's just assume the Traversable under question is a list because it's possibly a bit easier to understand that way, so specialising the types:
(a -> b -> (a, c)) -> a -> [b] -> (a, [c])
So, to explain this, mapAccumR is a function of three arguments (ignoring currying, as we do for easy explanation), and I'm going to annotate these arguments here:
mapAccumR :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c])
mapAccumR :: mappingAndAccumulationFunction -> initialAccumulatorValue -> listToMapOver -> resultantAccumulatorAndMappedListPair
Cool, so that clears things a little bit, but it's still a bit confusing, right. So what the heck does it do?
Well, it does an accumulating map: so let's say in the first step, what it does is take the initialAccumulatorValue and the first b from the listToMapOver, and passes those to the mappingAndAccumulationFunction function, which will do something with them and return two things: 1. a new value of type a and 2. a mapped value for later collection into the mapped list (see the type of resultantAccumulatorAndMappedListPair). These two values are paired, hence the return type of the mappingAndAccumulationFunction function as (a, c).
In the second and subsequent steps, it takes this (a, c) pair from the last step, pulls the c out and remembers it by appending it to an internal list it's keeping track of until the end, and pulls the a out as the first argument to the next application of the mappingAndAccumulationFunction along with the next b value of the listToMapOver.
Once it runs out of b values from listToMapOver, it returns a pair which has the last value of a and a list whose contents are of type c.
So why the heck would you want this function? Example time!
annotateLeastFavourites items = snd (mapAccumR (\num item -> (num + 1, show num ++ ": " ++ item)) 1 items)
itemList = ["Geese","Monkeys","Chocolate","Chips"]
> annotateLeastFavourites itemList
["4: Geese","3: Monkeys","2: Chocolate","1: Chips"]
or, maybe this is a bit simpler to see what's going on:
> mapAccumR (\num item -> (num + 1, show num ++ ": " ++ item)) 1 ["Geese", "Monkeys", "Chocolate", "Chips"]
(5,["4: Geese","3: Monkeys","2: Chocolate","1: Chips"])
So we can see that it's a function that can give us a "cumulative value" along with our accumulating value anytime we need some information to pass along a map, for example, or if we want to build up a collection value (on the right) that also needs to have information passed along that changes with each step (the value on the left).
Maybe you want to get the max length of a list of items as you also annotate them with each item's length
> mapAccumR (\biggestSoFar item -> (max biggestSoFar (length item), (item, length item))) 0 ["Geese", "Monkeys", "Chocolate", "Chips"]
(9,[("Geese",5),("Monkeys",7),("Chocolate",9),("Chips",5)])
There are lots of possibilities here. Hopefully now it's clear why people say this is like a combination of map and foldr. If you happen to think geometrically as I do, I think of it as when you need to transform a collection of some kind, and you need to thread some changing thing through that collection as part of the transformation.
Hope this has helped give you an intuition and store the pattern in your mind for later when you recognise you might need it in the future :)
let (_, result) =
mapAccumR
(\cumulativeLength item ->
let newLength = cumulativeLength + length item
in (newLength, take cumulativeLength (repeat ' ') ++ item)
)
0
["Geese", "Monkeys", "Chocolate", "Chips", "Dust", "Box"]
in mapM_ putStrLn $ reverse result
Box
Dust
Chips
Chocolate
Monkeys
Geese
Sometimes, and depending on the shape of the computation you want, you'd want to use mapAccumL instead of mapAccumR, but you get the picture.
Also, note that it's defined for Traversable instances, not just lists, so it will work on all sorts of traversable containers and data structures such as Trees, Maps, Vectors, etc.
Here are some examples, generated using Debug.SimpleReflect.
Below, f is the same f you would use in a foldr, except the arguments have been flipped. Otherwise, there's no difference.
Instead g is similar to what you would use in a map, except g x y does not only depend on the current list element y, but also on the results of the former fold x.
> import Data.List
> import Debug.SimpleReflect
> mapAccumR (\x y -> (f x y, g x y)) a [] :: (Expr, [Expr])
(a,[])
> mapAccumR (\x y -> (f x y, g x y)) a [b] :: (Expr, [Expr])
(f a b,[g a b])
> mapAccumR (\x y -> (f x y, g x y)) a [b,c] :: (Expr, [Expr])
(f (f a c) b,[g (f a c) b,g a c])
> mapAccumR (\x y -> (f x y, g x y)) a [b,c,d] :: (Expr, [Expr])
(f (f (f a d) c) b,[g (f (f a d) c) b,g (f a d) c,g a d])
Here is a foldr with f having its arguments flipped, by comparison.
> foldr (\x y -> f y x) a [b,c,d]
f (f (f a d) c) b
(I have no idea about why mapAccumR chose the arguments of f in the flipped order compared to foldr.)
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).
I want to translate the following procedural program to Haskell [written in pseudocode]:
f(x) {
if(c1(x)) {
if(c2(x)) {
return a(x);
}
else if (c3(x)) {
if(c4(x)) {
return b(x);
}
}
return d(x);
}
I have written the following implementation:
f x =
if (c1 x) then
if(c2 x) then
a x
else if (c3 x) then
if (c4 x) then
b x
else d x
else d x
else d x
Unfortunately it contains (else d x) three times.
Is there a better way to implement the function? (i.e, to return (d x) if none of the conditions was met?)
I understand that we could combine conditions c1 and c2 into (c1 x) && (c2 x) to make the number of if's smaller, but my conditions c1, c2, c3, c4 are indeed very long and if I combine them I will get a condition which takes more than one line.
Easiest, most apparent solution
If you're using GHC, you can turn on
{-# LANGUAGE MultiWayIf #-}
and your entire thing becomes
f x = if | c1 x && c2 x -> a x
| c1 x && c3 x && c4 x -> b x
| otherwise -> d x
Slightly more advanced and flexible solution
However, it's not always you want to blindly replicate imperative code in Haskell. Often, it's useful to think of your code as data instead. What you are really doing is setting up a list of requirements that x must satisfy, and then if x satisfies those requirements you take some action on x.
We can represent this with actual lists of functions in Haskell. It would look something like
decisions :: [([a -> Bool], a -> b)]
decisions = [([c1, c2], a)
,([c1, c3, c4], b)]
,([], d)]
Here, we should read this as, "if x satisfies both c1 and c2, take action a on x" and so on. Then we can define f as
f x = let maybeMatch = find (all ($ x) . fst) decisions
match = fromMaybe (error "no match!") maybeMatch
result = snd match
in result x
This works by walking through the list of requirements and finding the first set of decisions that x satisfy (maybeMatch). It pulls that out of the Maybe (you might want some better error handling there!) Then it chooses the corresponding function (result), and then it runs x through that.
Very advanced and flexible solution
If you have a really complex tree of decisions, you might not want to represent it with a flat list. This is where actual data trees come in handy. You can create a tree of the functions you want, and then search that tree until you hit a leaf node. That tree might in this example look something like
+-> c1 +-> c2 -> a
| |
| +-> c3 -> c4 -> b
+-> d
In other words, if x satisfies c1, it's gonna see if it satisfies c2 too, and if it does take action a on x. If it doesn't, it goes on to the next branch with c3, and so on, until it reaches an action (or has walked through the entire tree).
But first you're going to need a data type to tell the difference between a requirement (c1, c2 etc.) and an action (a, b etc.)
data Decision a b = Requirement (a -> Bool)
| Action (a -> b)
Then you build a tree of decisions as
decisions =
Node (Requirement (const True))
[Node (Requirement c1)
[Node (Requirement c2)
[Node (Action a) []]
,Node (Requirement c3)
[Node (Requirement c4)
[Node (Action b) []]]
,Node (Action d) []]
This looks more complicated than it is, so you should probably invent a neater way of expressing decision trees. If you define the functions
iff = Node . Requirement
action = flip Node [] . Action
you can write the tree as
decisions =
iff (const True) [
iff (c1) [
iff (c2) [
action a
],
iff (c3) [
iff (c4) [
action b
]
]
],
action d
]
and suddenly it's very similar to the imperative code you started with, despite the fact that it's valid Haskell code that's just building a data structure! Haskell is powerful for defining custom little "languages inside the language" like this.
Then you need to search through the tree for the first action you can reach.
decide :: a -> Tree (Decision a b) -> Maybe b
decide x (Node (Action f) _) = Just (f x)
decide x (Node (Requirement p) subtree)
| p x = asum $ map (decide x) subtree
| otherwise = Nothing
This uses a little bit of Maybe magic (asum) to stop at the first successful hit. This in turn means it will not compute the conditions of any branch in vain (which is efficient and important if the computations are expensive) and it should handle infinite decision trees just fine.
You can make decide even more general, taking full advantage of the Alternative class, but I've chosen to specialise it for Maybe so as to not write a book about this. Making it even more general might allow you to have fancy monadic decisions too, which would be very cool!
But, lastly, as a very simple example of this in action – take the Collatz conjecture. If you give me a number, and ask me what the next number should be, I can build a decision tree to find out. The tree may look like this:
collatz =
iff (> 0) [
iff (not . even) [
action (\n -> 3*n + 1)
],
action (`div` 2)
]
so the number has to be bigger than 0, and then if it's odd you multiply by three and add one, otherwise you halve it. Test runs show that
λ> decide 3 collatz
Just 10
λ> decide 10 collatz
Just 5
λ> decide (-4) collatz
Nothing
You can probably imagine much more interesting decision trees.
Edit like a year later: The generalisation to Alternative is actually very simple, and fairly interesting. The decide function gets the new look
decide :: Alternative f => a -> Tree (Decision a b) -> f b
decide x (Node (Action f) _) = pure (f x)
decide x (Node (Requirement p) subtree)
| p x = asum $ map (decide x) subtree
| otherwise = empty
(that's a total of only three changes, for those keeping count.) What this gives you is the opportunity to assemble "all" actions the input satisfies by using the applicative instance of lists instead of Maybe. This reveals an "error" in our collatz tree – if we look carefully at it, we see it says that all odd and positive integers n turn to 3*n +1 but it also says that all positive numbers turn to n/2. There is no additional requirement that says the number has to be even.
In other words, the (`div` 2) action is only under the (>0) requirement and nothing else. This is technically incorrect, but it happens to work if we just get the first result (which is basically what using the Maybe Alternative instance does). If we list all results, we also get an incorrect one.
When is getting multiple results interesting? Maybe we're writing the decision tree for an AI, and we want to humanise the behaviour by first getting all the valid decisions, and then picking one of them at random. Or ranking them based on how good they are in the circumstances, or something else.
You could use guards and a where clause:
f x | cb && c2 x = a x
| cb && c3 x && c4 x = b x
| otherwise = d x
where cb = c1 x
If you're just worried about writing them out then that's what where blocks are for
f x =
case () of
() | c1 && c2 -> a x
| c1 && c3 && c4 -> b x
| otherwise -> d x
where
c1 = ...
c2 = ...
c3 = ...
c4 = ...
Not that I'm using the case trick to introduce a new place for guard statements. I can't use guards on the function definition itself because the where clause won't scope over all of the guards. You could use if just the same, but guards have nice pass-through semantics.
There's another pattern you can use: I wouldn't use it in your specific example but there are very similar situations where I have used it.
f x = case (c1 x, c2 x, c3 x, c4 x) of
(True,True,_,_) -> a x
(True,False,True,True) -> b x
_ -> d x
Only the bare minimum evaluation required to choose which path to take will actually be evaluated: it won't actually evaluate c2 x unless c1 x is True.
Lets say I'm given two functions:
f :: [a] -> b
g :: [a] -> c
I want to write a function that is the equivalent of this:
h x = (f x, g x)
But when I do that, for large lists inevitably I run out of memory.
A simple example is the following:
x = [1..100000000::Int]
main = print $ (sum x, product x)
I understand this is the case because the list x is being stored in memory without being garbage collected. It would be better instead of f and g worked on x in, well, "parallel".
Assuming I can't change f and g, nor want to make a separate copy of x (assume x is expensive to produce) how can I write h without running into out of memory issues?
A short answer is you can't. Since you have no control over f and g, you have no guarantee that the functions process their input sequentially. Such a function can as well keep the whole list stored in memory before producing the final result.
However, if your functions are expressed as folds, the situation is different. This means that we know how to incrementally apply each step, so we can parallelize those steps in one run.
The are many resources about this area. For example:
Haskell: Can I perform several folds over the same lazy list without keeping list in memory?
Classic Beautiful folding
More beautiful fold zipping
The pattern of consuming a sequence of values with properly defined space bounds is solved more generally with pipe-like libraries such conduit, iteratees or pipes. For example, in conduit, you could express the combination of computing sums and products as
import Control.Monad.Identity
import Data.Conduit
import Data.Conduit.List (fold, sourceList)
import Data.Conduit.Internal (zipSinks)
product', sum' :: (Monad m, Num a) => Sink a m a
sum' = fold (+) 0
product' = fold (*) 1
main = print . runIdentity $ sourceList (replicate (10^6) 1) $$
zipSinks sum' product'
If you can turn your functions into folds, you can then just use them with a scan:
x = [1..100000000::Int]
main = mapM_ print . tail . scanl foo (a0,b0) . takeWhile (not.null)
. unfoldr (Just . splitAt 1000) -- adjust the chunk length as needed
$ x
foo (a,b) x = let a2 = f' a $ f x ; b2 = g' b $ g x
in a2 `seq` b2 `seq` (a2, b2)
f :: [t] -> a -- e.g. sum
g :: [t] -> b -- (`rem` 10007) . product
f' :: a -> a -> a -- e.g. (+)
g' :: b -> b -> b -- ((`rem` 10007) .) . (*)
we consume the input in chunks for better performance. Compiled with -O2, this should run in a constant space. The interim results are printed as indication of progress.
If you can't turn your function into a fold, this means it has to consume the whole list to produce any output and this trick doesn't apply.
You can use multiple threads to evaluate f x and g x in parallel.
E.g.
x :: [Int]
x = [1..10^8]
main = print $ let a = sum x
b = product x
in a `par` b `pseq` (a,b)
Its a nice way to exploit GHC's parallel runtime to prevent a space leak by doing two things at once.
Alternatively, you need to fuse f and g into a single pass.