Haskell data variable - list

I have this simple list structure where every leaf holds two values (a and b) and every node holds one value (a)
data List a b = Leaf (a, b) | Node (a, (List a b)) deriving Show
And I have this function just returning the value of a node or the first value of a leaf
func (Leaf (a, b)) = a
func (Node (a, c)) = a
Is there a way avoid one of these pattern matches? In fact I'm working on a ternary-tree and functions which have more than one argument, so I have a lot of pattern matches which are all doing the same thing.
I thought about something like this
func (var (a, b)) = a
where var can be a leaf or a node, but this does not work.

If you're comfortable with it, you can refactor your type as:
data List a b = L (a, Either b (List a b)) deriving Show
Then,
func :: List a b -> a
func (L (a,_)) = a
Previous values like
Leaf (a, b)
Node (a, list)
are now written as
L (a, Left b)
L (a, Right list)
Depending on your code, this might be more convenient to use.
However, keep in mind that if you need to access the second component of the pair, you need to pattern match anyway. It is likely that your current datatype is more convenient, overall, than this alternative.

I "solved" it by adding a help function returning the first value
gf (Leaf (a, b)) = a
gf (Node (a, b)) = a
So I can always use this function
func x = gf x
There are still two pattern matches but in case of more complex functions expecting more than one argument it is useful to avoid a lot of pattern matches
i.e
addValues (Leaf (a, b)) (Leaf (c, d)) (Leaf (e, f)) = a + c + e
addValues (Leaf (a, b)) (Leaf (c, d)) (Node (e, f)) = a + c + e
addValues (Leaf (a, b)) (Node (c, d)) (Leaf (e, f)) = a + c + e
addValues (Leaf (a, b)) (Node (c, d)) (Node (e, f)) = a + c + e
addValues (Node (a, b)) (Leaf (c, d)) (Leaf (e, f)) = a + c + e
addValues (Node (a, b)) (Leaf (c, d)) (Node (e, f)) = a + c + e
addValues (Node (a, b)) (Node (c, d)) (Leaf (e, f)) = a + c + e
addValues (Node (a, b)) (Node (c, d)) (Node (e, f)) = a + c + e
can now be written as
addValues (a, b, c) = (gf a) + (gf b) + (gf c)

Related

How can I convert a list of 3-tuples into one 3-triple of lists in Haskell?

I am attempting to write a function called that takes a list of triples and produces a 3-tuple of three lists. For instance, the function called on [(a,b,c), (d, e, f), (g, h, i)] should produce ([a,d,g], [b, e, j], [c, f, i]).
I have this so far:
-- This gives the head of a 3-tuple
fst3 :: (a, b, c) -> a
fst3 (x, _, _) = x
unzipTriples :: [(a, b, c)] -> a
unzipTriples (x : y : z : xs) = (fst3 x : fst3 y : fst3 z, unzipTriples xs)
I thought this would create a list [a, d, g] and then add it to the 3-tuple and do the rest for the remaining list. How can I improve this wrong function?
The pattern (x : y : z : xs) in unzipTriples (x : y : z : xs) = … will take the first three elements of the list, so then x, y and z are 3-tuples. But you thus would limit yourself to processing lists with three or more elements.
What you can do is use map and thus work with:
fst3 :: (a, b, c) -> a
fst3 (a, _, _) = a
snd3 :: (a, b, c) -> b
snd3 (_, b, _) = b
thd3 :: (a, b, c) -> c
thd3 (_, _, c) = c
unzipTriples :: [(a, b, c)] -> ([a], [b], [c])
unzipTriples xs = (map fst3 xs, map snd3 xs, map thd3 xs)
But it is probably more elegant, and will consume less memory when you pattern match on the first item of the list, a 3-tuple, and then recurse on the tail of the list, so:
unzipTriples :: [(a, b, c)] -> ([a], [b], [c])
unzipTriples [] = ([], [], [])
unzipTriples ((a, b, c):xs) = (a:as, b:bs, c:cs)
where ~(as, bs, cs) = unzipTriples xs
You can convert this into an expression with foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b, I leave this as an exercise.

How do I accumulate repeated application of a function to a list of values?

How do I accumulate the successive application of a function to a list of values in Haskell?
I'm not sure I'm phrasing that right, but what I'm looking for, for example, is that I have a list values of type X,
l = [a, b, c, d, e]
and a function
f :: X -> X -> X
and I want
(f e (f d (f c (f b a))))
which I think can perhaps be expressed with $ somehow.
I see that Haskell has some fold functions, but I can't quite figure out how to get it to work like the fold operations I'm familiar with.
Isn't this just foldl1 (flip f) l? You want a left fold, and you want the operation to start with the first item in the list rather than a specific accumulator.
Well, your function f really has type:
f :: X -> X -> X
Then the expression you are interested in is:
foldr1 f [e, d, c, a, b] -- note the twist at the end.
If you want to compute:
f e (f d (f c (f b a))) -- note last term is: f b a
then it is just:
foldr1 f [e, d, c, b, a]
Play with simple-reflect to figure it out.
ghci> import Debug.SimpleReflect
ghci> foldl1 f [a,b,c,d,e]
f (f (f (f a b) c) d) e
ghci> foldl (flip f) z [a,b,c,d,e]
f e (f d (f c (f b (f a z))))
And so on...

Swap two elements in a list by its indices

Is there any way to swap two elements in a list if the only thing I know about the elements is the position at which they occur in the list.
To be more specific, I am looking for something like this:
swapElementsAt :: Int -> Int -> [Int] -> [Int]
that would behave like that:
> swapElementsAt 1 3 [5,4,3,2,1] -- swap the first and third elements
[3,4,5,2,1]
I thought that a built-in function for this might exists in Haskell but I wasn't able to find it.
Warning: differential calculus. I don't intend this answer entirely seriously, as it's rather a sledgehammer nutcracking. But it's a sledgehammer I keep handy, so why not have some sport? Apart from the fact that it's probably rather more than the questioner wanted to know, for which I apologize. It's an attempt to dig out the deeper structure behind the sensible answers which have already been suggested.
The class of differentiable functors offers at least the following bits and pieces.
class (Functor f, Functor (D f)) => Diff (f :: * -> *) where
type D f :: * -> *
up :: (I :*: D f) :-> f
down :: f :-> (f :.: (I :*: D f))
I suppose I'd better unpack some of those definitions. They're basic kit for combining functors. This thing
type (f :-> g) = forall a. f a -> g a
abbreviates polymorphic function types for operations on containers.
Here are constant, identity, composition, sum and product for containers.
newtype K a x = K a deriving (Functor, Foldable, Traversable, Show)
newtype I x = I x deriving (Functor, Foldable, Traversable, Show)
newtype (f :.: g) x = C {unC :: f (g x)} deriving (Functor, Foldable, Traversable, Show)
data (f :+: g) x = L (f x) | R (g x) deriving (Functor, Foldable, Traversable, Show)
data (f :*: g) x = f x :*: g x deriving (Functor, Foldable, Traversable, Show)
D computes the derivative of a functor by the usual rules of calculus. It tells us how to represent a one-hole context for an element. Let's read the types of those operations again.
up :: (I :*: D f) :-> f
says we can make a whole f from the pair of one element and a context for that element in an f. It's "up", because we're navigating upward in a hierarchical structure, focusing on the whole rather than one element.
down :: f :-> (f :.: (I :*: D f))
Meanwhile, we can decorate every element in a differentiable functor structure with its context, computing all the ways to go "down" to one element in particular.
I'll leave the Diff instances for the basic components to the end of this answer. For lists we get
instance Diff [] where
type D [] = [] :*: []
up (I x :*: (xs :*: ys)) = xs ++ x : ys
down [] = C []
down (x : xs) = C ((I x :*: ([] :*: xs)) :
fmap (id *:* ((x :) *:* id)) (unC (down xs)))
where
(*:*) :: (f a -> f' a) -> (g a -> g' a) -> (f :*: g) a -> (f' :*: g') a
(ff' *:* gg') (f :*: g) = ff' f :*: gg' g
So, for example,
> unC (down [0,1,2])
[I 0 :*: ([] :*: [1,2]),I 1 :*: ([0] :*: [2]),I 2 :*: ([0,1] :*: [])]
picks out each element-in-context in turn.
If f is also Foldable, we get a generalized !! operator...
getN :: (Diff f, Foldable f) => f x -> Int -> (I :*: D f) x
getN f n = foldMap (: []) (unC (down f)) !! n
...with the added bonus that we get the element's context as well as the element itself.
> getN "abcd" 2
I 'c' :*: ("ab" :*: "d")
> getN ((I "a" :*: I "b") :*: (I "c" :*: I "d")) 2
I "c" :*: R ((I "a" :*: I "b") :*: L (K () :*: I "d"))
If we want a functor to offer swapping of two elements, it had better be twice differentiable, and its derivative had better be foldable too. Here goes.
swapN :: (Diff f, Diff (D f), Foldable f, Foldable (D f)) =>
Int -> Int -> f x -> f x
swapN i j f = case compare i j of
{ LT -> go i j ; EQ -> f ; GT -> go j i } where
go i j = up (I y :*: up (I x :*: f'')) where
I x :*: f' = getN f i -- grab the left thing
I y :*: f'' = getN f' (j - 1) -- grab the right thing
It's now easy to grab two elements out and plug them back in the other way around. If we're numbering the positions, we just need to be careful about the way removing elements renumbers the positions.
> swapN 1 3 "abcde"
"adcbe"
> swapN 1 2 ((I "a" :*: I "b") :*: (I "c" :*: I "d"))
(I "a" :*: I "c") :*: (I "b" :*: I "d")
As ever, you don't have do dig down too far below a funny editing operation to find some differential structure at work.
For completeness. Here are the other instances involved in the above.
instance Diff (K a) where -- constants have zero derivative
type D (K a) = K Void
up (_ :*: K z) = absurd z
down (K a) = C (K a)
instance Diff I where -- identity has unit derivative
type D I = K ()
up (I x :*: K ()) = I x
down (I x) = C (I (I x :*: K ()))
instance (Diff f, Diff g) => Diff (f :+: g) where -- commute with +
type D (f :+: g) = D f :+: D g
up (I x :*: L f') = L (up (I x :*: f'))
up (I x :*: R g') = R (up (I x :*: g'))
down (L f) = C (L (fmap (id *:* L) (unC (down f))))
down (R g) = C (R (fmap (id *:* R) (unC (down g))))
instance (Diff f, Diff g) => Diff (f :*: g) where -- product rule
type D (f :*: g) = (D f :*: g) :+: (f :*: D g)
up (I x :*: (L (f' :*: g))) = up (I x :*: f') :*: g
up (I x :*: (R (f :*: g'))) = f :*: up (I x :*: g')
down (f :*: g) = C (fmap (id *:* (L . (:*: g))) (unC (down f))
:*: fmap (id *:* (R . (f :*:))) (unC (down g)))
instance (Diff f, Diff g) => Diff (f :.: g) where -- chain rule
type D (f :.: g) = (D f :.: g) :*: D g
up (I x :*: (C f'g :*: g')) = C (up (I (up (I x :*: g')) :*: f'g))
down (C fg) = C (C (fmap inner (unC (down fg)))) where
inner (I g :*: f'g) = fmap wrap (unC (down g)) where
wrap (I x :*: g') = I x :*: (C f'g :*: g')
Haskell doesn't have such a function, mainly because it is a little bit un-functional. What are you actually trying to achieve?
You can implement your own version of it (maybe there is a more idiomatic way to write this). Note that I assume that i < j, but it would be trivial to extend the function to correctly handle the other cases:
swapElementsAt :: Int -> Int -> [a] -> [a]
swapElementsAt i j xs = let elemI = xs !! i
elemJ = xs !! j
left = take i xs
middle = take (j - i - 1) (drop (i + 1) xs)
right = drop (j + 1) xs
in left ++ [elemJ] ++ middle ++ [elemI] ++ right
There are several working answers here, but I thought that a more idiomatic haskell example would be useful.
In essence, we zip an infinite sequence of natural numbers with the original list to include ordering information in the first element of the resulting pairs, and then we use a simple right fold (catamorphism) to consume the list from the right and create a new list, but this time with the correct elements swapped. We finally extract all the second elements, discarding the first element containing the ordering.
The indexing in this case is zero-based (congruent with Haskell's typical indexes) and the pointers must be in range or you'll get an exception (this can be easily prevented if you change the resulting type to Maybe [a]).
swapTwo :: Int -> Int -> [a] -> [a]
swapTwo f s xs = map snd . foldr (\x a ->
if fst x == f then ys !! s : a
else if fst x == s then ys !! f : a
else x : a) [] $ ys
where ys = zip [0..] xs
And a single liner, doing the swap in just one pass (combining the functionality of the foldr and map into a zipWith):
swapTwo' f s xs = zipWith (\x y ->
if x == f then xs !! s
else if x == s then xs !! f
else y) [0..] xs
That's how I solved it:
swapElementsAt :: Int -> Int -> [a] -> [a]
swapElementsAt a b list = list1 ++ [list !! b] ++ list2 ++ [list !! a] ++ list3
where list1 = take a list;
list2 = drop (succ a) (take b list);
list3 = drop (succ b) list
Here I used the convention that position 0 is the first. My function expects a<=b.
What I like most in my program is the line take a list.
Edit: If you want to get more such cool lines, look at this code:
swapElementsAt :: Int -> Int -> [a] -> [a]
swapElementsAt a another list = list1 ++ [list !! another] ++ list2 ++ [list !! a] ++ list3
where list1 = take a list;
list2 = drop (succ a) (take another list);
list3 = drop (succ another) list
first-order one-pass swapping
swap 1 j l = let (jth,ith:l') = swapHelp j l ith in jth:l'
swap j 1 l = swap 1 j l
swap i j (h:t) = h : swap (i-1) (j-1) t
swapHelp 1 (h:t) x = (h,x:t)
swapHelp n (h:t) x = (y,h:t') where
(y, t') = swapHelp (n-1) t x
now with precondition in compliance with original question, i.e. relaxed to 1 <= i,j <= length l for swap i j l
draws heavily on an idea by #dfeuer to reduce the problem to swapping the 1st element of a list with another from a given position
This is a strange thing to do, but this should work, aside from the off-by-one errors you'll have to fix since I'm writing this on my phone. This version avoids going over the same segments of the list any more times than necessary.
swap' :: Int -> Int -> [a] -> [a]
swap' first second lst = beginning ++ [y] ++ middle ++ [x] ++ end
where
(beginning, (x : r)) = splitAt first lst
(middle, (y : end)) = splitAt (second - first - 1) r
swap x y | x == y = id
| otherwise = swap' (min x y) (max x y)
There is also a recursive solution:
setElementAt :: a -> Int -> [a] -> [a]
setElementAt a 0 (_:tail) = a:tail
setElementAt a pos (b:tail) = b:(setElementAt a (pred pos) tail)
swapElementsAt :: Int -> Int -> [a] -> [a]
swapElementsAt 0 b list#(c:tail) = (list !! b):(setElementAt c (pred b) tail)
swapElementsAt a b (c:tail) = c:(swapElementsAt (pred a) (pred b) tail)
I really like #dfeuer 's solution. However there's still room for optimization by way of deforestation:
swap' :: Int -> Int -> [a] -> [a]
swap' first second lst = beginning $ [y] ++ (middle $ [x] ++ end)
where
(beginning, (x : r)) = swapHelp first lst
(middle, (y : end)) = swapHelp (second - first - 1) r
swapHelp :: Int -> [a] -> ([a] -> [a],[a])
swapHelp 0 l = ( id , l)
swapHelp n (h:t) = ((h:).f , r) where
( f , r) = swapHelp (n-1) t
For positional swapping, using a more complex fold function I have changed the value of the smalest (min) index with the value of the greates (xs!!(y-ii)) and then keep the value for the greatest index in the temp, until find it, the index(max).
I used min and max to make sure I encounter in proper order the indices otherwise I would have to put more checks and conditions in the folds function.
folds _ _ _ _ [] = []
folds i z y tmp (x:xs)
| i == z = (xs!!(y-ii)):folds ii z y x xs
| i == y = tmp:folds ii z y 0 xs
| otherwise = x:folds ii z y tmp xs
where
ii = i+1
swapElementsAt x y xs = folds 0 a b 0 xs
where
a = min x y
b = max x y
Results
> swapElementsAt 0 1 [1,1,1,3,4,9]
[1,1,1,3,4,9]
> swapElementsAt 0 5 [1,1,1,3,4,9]
[9,1,1,3,4,1]
> swapElementsAt 3 1 [1,1,1,3,4,5]
[1,3,1,1,4,5]
> swapElementsAt 1 3 [1,1,1,3,4,5]
[1,3,1,1,4,5]
> swapElementsAt 5 4 [1,1,1,3,4,5]
[1,1,1,3,5,4]
Efficiency aside, we can do a fully recursive definition with only pattern matching.
swapListElem :: [a] -> Int -> Int -> [a]
-- Get nice arguments
swapListElem xs i j
| (i>= length xs) || (j>=length xs) = error "Index out of range"
| i==j = xs
| i>j = swapListElem xs j i
-- Base case
swapListElem (x:y:xs) 0 1 = (y:x:xs)
-- Base-ish case: If i=0, use i'=1 as a placeholder for j-th element
swapListElem (x:xs) 0 j = swapListElem (swapListElem (x:(swapListElem xs 0 (j-1))) 0 1) 1 j
-- Non-base case: i>0
swapListElem (x:xs) i j = x:(swapListElem xs (i-1) (j-1))

How to define Eq instance of List without GADTs or Datatype Contexts

I am using Glasgow Haskell Compiler, Version 7.8.3, stage 2 booted by GHC version 7.6.3.
I attempted to use the following data definition for a List type in Haskell:
data Eq a => List a = Nil | Cons a (List a)
However, the -XDatatypeContexts flag is required, depricated, and even removed from the language by default. It is widely viewed as a misfeature of the language. I also do not want to have to use special flags for my definition of List since I am trying to replicate the functionality of the existing list type.
Then I was able to use the following segment of code instead:
data List a where
Nil :: List a
Cons :: Eq a => a -> List a -> List a
It runs fine. The visible issue with this solution is that now I need to use the -XGADTs flag, which I still don't want to depend on in this case since it is not necessary for the built in version of list to function. Is there a way to restrict the type within Cons to be Eq a so that I can compare two lists without the need for compiler flags and without using the derived keyword?
The remaining code is as follows:
instance Eq (List a) where
(Cons a b) == (Cons c d) = (a == c) && (b == d)
Nil == Nil = True
_ == _ = False
testfunction = Nil :: List Int
main = print (if testfunction == Nil then "printed" else "not printed")
I see that the following solution works:
data List a = Nil | Cons a (List a)
instance Eq a => Eq (List a) where
(Cons a b) == (Cons c d) = (a == c) && (b == d)
Nil == Nil = True
_ == _ = False
testfunction = Nil :: List Int
main = print (if testfunction == Nil then "printed" else "not printed")
However, for some reason, it does not work with a manual definition for Eq (Equals here).
class Equal a where
(=+=) :: a -> a -> Bool
(/+=) :: a -> a -> Bool
x =+= y = not (x /+= y)
x /+= y = not (x =+= y)
data List a = Nil | Cons a (List a)
instance Equal a => Equal (List a) where
(Cons a b) =+= (Cons c d) = (a =+= c) && (b =+= d)
Nil =+= Nil = True
_ =+= _ = False
testfunction = Nil :: List Int
main = print (if testfunction =+= Nil then "printed" else "not printed")
I get the following error:
No instance for (Equal Int) arising from a use of ‘=+=’
In the expression: testfunction =+= Nil
In the first argument of ‘print’, namely
‘(if testfunction =+= Nil then "printed" else "not printed")’
In the expression:
print (if testfunction =+= Nil then "printed" else "not printed")
However, by using GADT's, I can show that my Equal class does actually function. This code works:
class Equal a where
(=+=) :: a -> a -> Bool
(/+=) :: a -> a -> Bool
x =+= y = not (x /+= y)
x /+= y = not (x =+= y)
data List a where
Nil :: List a
Cons :: Equal a => a -> List a -> List a
instance Equal (List a) where
(Cons a b) =+= (Cons c d) = (a =+= c) && (b =+= d)
Nil =+= Nil = True
_ =+= _ = False
testfunction = Nil :: List Int
main = print (if testfunction =+= Nil then "printed" else "not printed")
However, I have to use instance Equal (List a) where instead of instance Equal a => Equal (List a) where otherwise I get the error:
No instance for (Equal Int) arising from a use of ‘=+=’
In the expression: testfunction =+= Nil
In the first argument of ‘print’, namely
‘(if testfunction =+= Nil then "printed" else "not printed")’
In the expression:
print (if testfunction =+= Nil then "printed" else "not printed")
It looks like you're trying to restrict lists to only be able to hold values that implement Eq, and you can't do that without extensions. You can, however, tell the compiler how to compare two List as when a has a type that implements Eq. There are two easy ways to do this. The simplest is with a deriving statement:
data List a = Nil | Cons a (List a) deriving (Eq)
Or you can define it manually:
instance Eq a => Eq (List a) where
(Cons a b) == (Const c d) = (a == c) && (b == d)
Nil == Nil = True
_ == _ = False
Now whenever you fill your List type with something that implements Eq, the list will also be comparable using ==. There's no need to restrict the values that can be inside Cons. You can certainly have a normal list of functions, like
fs1 :: [Int -> Int]
fs1 = [(+1), (*3), (+2), (*4)]
Or in your case
fs2 :: List (Int -> Int)
fs2 = Cons (+1) $ Cons (*3) $ Cons (+2) $ Cons (*4) Nil
Which can be used as
> map ($ 10) fs1
[11, 30, 12, 40]
And given
map' :: (a -> b) -> List a -> List b
map' f Nil = Nil
map' f (Cons x xs) = Cons (f x) (map' f xs)
Then
> map' ($ 10) fs2
Cons 11 (Cons 30 (Cons 12 (Cons 40 Nil)))
Although to actually view it in GHCi you should also derive Show:
data List a = Nil | Cons a (List a) deriving (Eq, Show)
There are several other useful typeclasses that can be derived in GHC, too.
To make it work with your custom Equal typeclass, you'll have to write multiple instances by hand:
class Equal a where
(=+=) :: a -> a -> Bool
(/+=) :: a -> a -> Bool
x =+= y = not (x /+= y)
x /+= y = not (x =+= y)
instance Equal Int where
x =+= y = x == y
instance Equal a => Equal (List a) where
(Cons a b) =+= (Cons c d) = (a =+= c) && (b =+= d)
Nil =+= Nil = True
_ =+= _ = False
Now because you have an instance Equal Int and Equal a => Equal (List a), you can compare two List Ints:
> let x = Cons 1 (Cons 2 (Cons 3 Nil)) :: List Int
> let y = Cons 1 (Cons 2 (Cons 3 Nil)) :: List Int
> x =+= y
True
> x =+= Nil
False
For whatever type you want to store in a List and use =+= on, you'll have to implement Equal for that type.
The usual solution to this is to to use this structure:
data List a = Nil | Cons a (List a)
instance Eq a => Eq (List a) where
(Cons a b) == (Cons c d) = (a == c) && (b == d)
Nil == Nil = True
_ == _ = False
Noticed I've added Eq a as a constraint to the instance, not to the data type. This way all the lists that you could compare for equality the way you're trying to write it can be compared for equality, but you also allow the existence of lists of things which cannot be compared for equality. And this is supported by every version of Haskell you will encounter, even very old ones, with no extensions.
This approach then also extends nicely when you want to add a Show instance, an Ord instance, etc; to do it your way you have to keep going back and making the data structure more restrictive by adding more constraints (potentially breaking existing code that worked fine because it didn't need those instances). Whereas if you leave the data type unconstrained and just make your instances Show a => Show (List a), Ord a => Ord (List a), etc, then you can show and order lists of types which happen to support both, but you can still have (and show) lists of types that support Show but not Ord and vice versa.
Plus, there are lots of useful type classes for parameterised types (such as List a) that require them to be fully generic in their type parameter. Examples are Functor, Applicative, Monad; it is not possible to correctly implement these for the constrained list type you're trying to create.
While it is possible to create constrained lists like you're trying to (but only by using extensions, as you've found), it has been found to be usually much more useful to leave your data types fully generic in their type parameter, and if a particular usage of your type needs to impose restrictions on the type parameter you impose them at that usage site, not at every use of the data type. This should be your "default setting"; depart from it when you have a good reason (you may well have such a reason here, but you haven't given it to us in the question, so nobody can recommend the best way of handling it).

foldr confusion

I execute this statement on the interpreter
foldr (\x (a, b) -> if x == '_' then (a+1, [((div a 3), (mod a 3))] ++ b) else (a, b)) (0, []) "_______OX"
I expected the output to be
(7,[(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2.0)])
however the output is
(7,[(2,0),(1,2),(1,1),(1,0),(0,2),(0,1),(0,0)])
what am I doing wrong. As far as I know, foldr starts from the last element of the list and my lambda function appends it to the beginning of the accumulator list. So I should get (0,0) as the first element. However, it's the opposite and I'm puzzled. :(
Also, a small question - How do I go about assigning tags for questions like these?
After 'X' you have
(0,[])
After '0' you have
(0,[])
After first '_' you have
(1,[(0,0)])
After secont '_' you have
(2,[(0,1),(0,0)]) -- you prepend in: [((div a 3), (mod a 3))] ++ b
After third '_' you have
(3,[(O,2),(0,1),(0,0)])
...
Let's simplify this a bit, for better explanation:
foldr (\c (a,b) -> (a+1, a:b)) (0, []) "hi"
Foldr is defined as
foldr f a [] = a
foldr f a (x:xs) = f x (foldr f a xs)
Let us call the lambda function g
Hence, the trace of the expression above:
g 'h' (foldr g (0,[]) "i")
g 'h' (g 'i' (foldr g (0,[]) ""))
g 'h' (g 'i' (0, []))
g 'h' (1, [0])
(2, [1,0])