Haskell "transform" function - haskell

I've written what I imagine would be a common function in Haskell, but I couldn't find it implemented anywhere. For want of a better word I've called it "transform".
What "transform" does three arguments: a list, and an initial state and a function that takes an element from the list, a state, and produces an element for an output list, and a new state. The output list is the same length as the input list.
It's kind of like "scanl" if it also took a state parameter, or like "unfoldr" if you could feed it a list.
Indeed, I've implemented this function below, in two different ways that have the same result:
transform1 :: (b -> c -> (a, c)) -> c -> [b] -> [a]
transform1 f init x = unfoldr f' (x, init)
where
f' ((l:ls), accum) = let (r, new_accum) = f l accum in Just (r, (ls, new_accum))
f' ([], _) = Nothing
transform2 :: (b -> c -> (a, c)) -> c -> [b] -> [a]
transform2 f init x = map fst $ tail $ scanl f' init' x where
f' (_,x) y = f y x
init' = (undefined, init)
This sort of operation seems relatively common though, that is, taking a list and walking through it with some state and producing a new list, so I'm wondering if there's a function that already exists and I'm reinventing the wheel. If so, I'll just use that, but if not, I might package what I've got into a (very) small library.

This is almost, but not exactly Data.List.mapAccumL. The difference is that mapAccumL also includes the final state. Also it recently got generalized to Traversable.
mapAccumL :: Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c)

Related

How can i fix this higher order function code in haskell?

I want to fix this code
h :: (a -> b) -> [a] -> [b]
h f = foldr (\x y -> f x : y) []
if i put h (+100) [1,2,3,4,5] in GHCI
it returns to me [101,202,303,404,505]
when i put h (*10) [1,2,3,4,5] then
i want to get [10,200,3000,40000,500000] list
can anyone help me fixing this code?
You here implemented a map, but in order to repeat the same operation multiple times, you need to perform a mapping on the tail y:
h :: (a -> a) -> [a] -> [a]
h f = foldr (\x y -> f x : map f y) []
Solving the general problem, as Willem Van Onsem's answer does, requires O(n^2) time to calculate the first n elements, because the function has to be applied k times to calculate the kth element.
To solve this sort of problem efficiently, you will need to take advantage of some additional structure. Based on your examples, I think the most obvious approach is to think about semigroup actions. That is, instead of applying an arbitrary function repeatedly, look for an efficient way to represent the compositions of the function. For example, (*x) can be represented by x, allowing (*x) . (*y) to be represented by x*y.
To apply this idea, we first need to transform Willem's solution to make the compositions explicit.
h :: (a -> a) -> [a] -> [a]
h f0 as0 = go as0 f0
where
go [] _ = []
go (a:as) f = f a : go as (f0 . f)
If we like, we can write that as a fold:
h :: (a -> a) -> [a] -> [a]
h f0 as = foldr go stop as f0
where
stop _ = []
go a r f = f a : r (f0 . f)
Now we've structured the function using an accumulator (which is a function). As we compose onto the accumulator, it will get slower and slower to apply it. We want to replace that accumulator with one we can "apply" quickly.
{-# language BangPatterns #-}
import Data.Semigroup
repeatedly :: Semigroup s => (s -> a -> a) -> s -> [a] -> [a]
repeatedly act s0 as = foldr go stop as s0
where
stop _ = []
go a r !s = act s a : r (s0 <> s)
Now you can use, for example,
repeatedly (\(Product s) -> (s*)) (Product 10) [1..5]
==> [10,200,3000,40000,500000]
repeatedly (\(Sum s) -> (s+)) (Sum 100) [1..5]
==> [101,202,303,404,505]
In each of these, you accumulate a product/sum which is added to/multiplied by the current list element.

Taking a list of lists and generating all variants with one element replaced [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have types for a two-dimensional map of characters:
type Row = [Char]
type Mappy = [Row]
I'd like to write a function that takes a Mappy like:
[['o','o'],['o','o']]
and generates a list of all Mappys with a single 'o' element replaced with 'i':
[ [['i','o'],['o','o']]
, [['o','i'],['o','o']]
, [['o','o'],['i','o']]
, [['o','o'],['o','i']]
]
Here's what I've tried: I think I need to use the map function, because I need to go over each element, but I don't know how, because a map function doesn't keep track of the position it is working on.
type Row = [Char]
type Mappy = [Row]
func :: Mappy -> [Mappy]
func a = map (map someFunc a) a
someFunc :: Mappy -> Char -> Mappy
someFunc a b = if b == "o"
then undefined
else a
Obviously, I should change the undefined, but i have no idea how. Thanks in advance.
Zippers are great, and there's an interesting blog post about
implementing Conway's Game of Life using zippers and comonads in Haskell. On the other
hand, if this is still your first week learning Haskell, you might
want to save Comonads for Thursday, right?
Here's another approach that uses simple recursion and list
comprehensions and no complex Haskell features.
First, imagine we have an awesome function:
varyOne :: (a -> [a]) -> [a] -> [[a]]
varyOne = undefined
that works as follows. Given a function f that produces zero or
more variants of an element a, the function call varyOne f xs
generates all variants of the list xs that result from taking
exactly one element of xs, say x in the middle of the list, and replacing it with all the
variants given by f x.
This function is surprisingly flexible. It can generate the list of all variants resulting from forcibly replacing an element by a constant:
> varyOne (\x -> [3]) [1,2,3,4]
[[3,2,3,4],[1,3,3,4],[1,2,3,4],[1,2,3,3]]
By returning a singleton variant for a specific value and an empty list of variants for other values, it can generate all variants that replace an 'o' with an 'i' while suppressing the "variants" where no replacement is possible:
> let varyRow = varyOne (\c -> if c == 'o' then ['i'] else [])
> varyRow "ooxo"
["ioxo","oixo","ooxi"]
and, because varyRow itself generates variants of a row, it can be used with varyOne to generate variants of tables where a particular row has been replaced by its possible variants:
> varyOne varyRow ["ooo","oox","ooo"]
[["ioo","oox","ooo"],["oio","oox","ooo"],["ooi","oox","ooo"],
["ooo","iox","ooo"],["ooo","oix","ooo"],
["ooo","oox","ioo"],["ooo","oox","oio"],["ooo","oox","ooi"]]
It turns out that this awesome function is surprisingly easy to write:
varyOne :: (a -> [a]) -> [a] -> [[a]]
varyOne f (x:xs)
= [y:xs | y <- f x] ++ [x:ys | ys <- varyOne f xs]
varyOne _ [] = []
The first list comprehension generates all the variants for the current element. The second list comprehension generates variants that involve changes to the right of the current element using a recursive varyOne call.
Given varyOne, we can define:
replaceOne :: Char -> Char -> Mappy -> [Mappy]
replaceOne old new = varyOne (varyOne rep1)
where rep1 x = if x == old then [new] else []
and:
> replaceOne 'o' 'i' ["ooo","oox","ooo"]
[["ioo","oox","ooo"],["oio","oox","ooo"],["ooi","oox","ooo"]
,["ooo","iox","ooo"],["ooo","oix","ooo"]
,["ooo","oox","ioo"],["ooo","oox","oio"],["ooo","oox","ooi"]]
is probably the function you're looking for.
If you prefer to unconditionally replace a single element with i, no matter what the old element was, then this will work:
> varyOne (varyOne (const ['i'])) ["ooo","oox","ooo"]
[["ioo","oox","ooo"],["oio","oox","ooo"],["ooi","oox","ooo"]
,["ooo","iox","ooo"],["ooo","oix","ooo"],["ooo","ooi","ooo"]
,["ooo","oox","ioo"],["ooo","oox","oio"],["ooo","oox","ooi"]]
What you want, young BaasBartMans, is a Zipper.
data Zipper a = Zipper [a] a [a]
ofList :: [a] -> Maybe (Zipper a)
ofList [] = Nothing
ofList (a:as) = Just (Zipper [] a as)
A zipper gives you the context for a position in a list, so you
can easily modify them one at a time, step forward and backward and such.
We can recover a list from a zipper:
instance Foldable Zipper where
foldr f c (Zipper ls a rs) = foldl' (flip f) (f a (foldr f c rs)) ls
We can modify every position in a Zipper simultaneously:
instance Functor Zipper where
fmap f (Zipper ls a rs) = Zipper (fmap f ls) (f a) (fmap f rs)
Or just the focused element:
here :: Functor f => (a -> f a) -> Zipper a -> f (Zipper a)
here f (Zipper ls a rs) = fmap (\a' -> Zipper ls a' rs) (f a)
And as a Zipper is a Comonad, we can modify each element in context:
instance Comonad Zipper where
extract (Zipper _ a _) = a
extend f z#(Zipper ls a rs) = Zipper ls' a' rs' where
a' = f z
ls' = unfoldr (fmap (\z' -> (f z', z')) . goLeft) z
rs' = unfoldr (fmap (\z' -> (f z', z')) . goRight) z
Using that, we can build a function that modifies each element of a list in context:
everywhere :: Alternative f => (a -> f a) -> [a] -> f [a]
everywhere f as = case ofList as of
Nothing -> pure []
Just z -> asum $ extend (fmap toList . here f) z
Which works for simple lists:
λ everywhere (\a -> [a+1]) [10,20,30]
[[11,20,30]
,[10,21,30]
,[10,20,31]]
And nested lists:
λ everywhere (everywhere (\a -> [a+1])) [[10], [20,20], [30,30,30]]
[[[11],[20,20],[30,30,30]]
,[[10],[21,20],[30,30,30]]
,[[10],[20,21],[30,30,30]]
,[[10],[20,20],[31,30,30]]
,[[10],[20,20],[30,31,30]]
,[[10],[20,20],[30,30,31]]]

Mapping while showing intermediate states

I need a function that does this:
>>> func (+1) [1,2,3]
[[2,2,3],[2,3,3],[2,3,4]]
My real case is more complex, but this example shows the gist of the problem. The main difference is that in reality using indexes would be infeasible. The List should be a Traversable or Foldable.
EDIT: This should be the signature of the function:
func :: Traversable t => (a -> a) -> t a -> [t a]
And closer to what I really want is the same signature to traverse but can't figure out the function I have to use, to get the desired result.
func :: (Traversable t, Applicative f) :: (a -> f a) -> t a -> f (t a)
It looks like #Benjamin Hodgson misread your question and thought you wanted f applied to a single element in each partial result. Because of this, you've ended up thinking his approach doesn't apply to your problem, but I think it does. Consider the following variation:
import Control.Monad.State
indexed :: (Traversable t) => t a -> (t (Int, a), Int)
indexed t = runState (traverse addIndex t) 0
where addIndex x = state (\k -> ((k, x), k+1))
scanMap :: (Traversable t) => (a -> a) -> t a -> [t a]
scanMap f t =
let (ti, n) = indexed (fmap (\x -> (x, f x)) t)
partial i = fmap (\(k, (x, y)) -> if k < i then y else x) ti
in map partial [1..n]
Here, indexed operates in the state monad to add an incrementing index to elements of a traversable object (and gets the length "for free", whatever that means):
> indexed ['a','b','c']
([(0,'a'),(1,'b'),(2,'c')],3)
and, again, as Ben pointed out, it could also be written using mapAccumL:
indexed = swap . mapAccumL (\k x -> (k+1, (k, x))) 0
Then, scanMap takes the traversable object, fmaps it to a similar structure of before/after pairs, uses indexed to index it, and applies a sequence of partial functions, where partial i selects "afters" for the first i elements and "befores" for the rest.
> scanMap (*2) [1,2,3]
[[2,2,3],[2,4,3],[2,4,6]]
As for generalizing this from lists to something else, I can't figure out exactly what you're trying to do with your second signature:
func :: (Traversable t, Applicative f) => (a -> f a) -> t a -> f (t a)
because if you specialize this to a list you get:
func' :: (Traversable t) => (a -> [a]) -> t a -> [t a]
and it's not at all clear what you'd want this to do here.
On lists, I'd use the following. Feel free to discard the first element, if not wanted.
> let mymap f [] = [[]] ; mymap f ys#(x:xs) = ys : map (f x:) (mymap f xs)
> mymap (+1) [1,2,3]
[[1,2,3],[2,2,3],[2,3,3],[2,3,4]]
This can also work on Foldable, of course, after one uses toList to convert the foldable to a list. One might still want a better implementation that would avoid that step, though, especially if we want to preserve the original foldable type, and not just obtain a list.
I just called it func, per your question, because I couldn't think of a better name.
import Control.Monad.State
func f t = [evalState (traverse update t) n | n <- [0..length t - 1]]
where update x = do
n <- get
let y = if n == 0 then f x else x
put (n-1)
return y
The idea is that update counts down from n, and when it reaches 0 we apply f. We keep n in the state monad so that traverse can plumb n through as you walk across the traversable.
ghci> func (+1) [1,1,1]
[[2,1,1],[1,2,1],[1,1,2]]
You could probably save a few keystrokes using mapAccumL, a HOF which captures the pattern of traversing in the state monad.
This sounds a little like a zipper without a focus; maybe something like this:
data Zippy a b = Zippy { accum :: [b] -> [b], rest :: [a] }
mapZippy :: (a -> b) -> [a] -> [Zippy a b]
mapZippy f = go id where
go a [] = []
go a (x:xs) = Zippy b xs : go b xs where
b = a . (f x :)
instance (Show a, Show b) => Show (Zippy a b) where
show (Zippy xs ys) = show (xs [], ys)
mapZippy succ [1,2,3]
-- [([2],[2,3]),([2,3],[3]),([2,3,4],[])]
(using difference lists here for efficiency's sake)
To convert to a fold looks a little like a paramorphism:
para :: (a -> [a] -> b -> b) -> b -> [a] -> b
para f b [] = b
para f b (x:xs) = f x xs (para f b xs)
mapZippy :: (a -> b) -> [a] -> [Zippy a b]
mapZippy f xs = para g (const []) xs id where
g e zs r d = Zippy nd zs : r nd where
nd = d . (f e:)
For arbitrary traversals, there's a cool time-travelling state transformer called Tardis that lets you pass state forwards and backwards:
mapZippy :: Traversable t => (a -> b) -> t a -> t (Zippy a b)
mapZippy f = flip evalTardis ([],id) . traverse g where
g x = do
modifyBackwards (x:)
modifyForwards (. (f x:))
Zippy <$> getPast <*> getFuture

Circular programming - replace list elements by minimum value

I've just read this article about circular programming. It seems so alien to me. Although I can imagine the feedback as lazily evaluated thunk that will be evaluated to desired result later, just can't wrap my head around it. So I decided to write function that replaces every element of a list with it's minimum value.
trace :: (a -> c -> (b,c)) -> a -> b
trace f a = b
where (b,c) = f a c
repminList :: (Num a, Ord a) => [a] -> [a]
repminList = trace repIIminList
repIIminList [x] m = ([m], x)
repIIminList (a:as) m = let (replaced, m) = repIIminList as m
in (m : replaced, min a m)
But repminList [1,2,3] equals to [2,3,3]. What would be the correct version?
Your problem is that you have two different m variables and one shadows over the other so you don't end up using the actual circular variable at all. Here's the fixed version of your repIIminList:
repIIminList [x] m = ([m], x)
repIIminList (a:as) m = let (replaced, m') = repIIminList as m
in (m : replaced, min a m')
Here m is the final, smallest element of the list that you receive as circular parameter. The m' returned from the recursive call to repIIminList is the smallest value seen so far, so it's important that you append the final smallest value (i.e. m) to the result list and then update the current smallest value by returning min a m'.
That's a pretty cool technique! Here's a working program that's inspired by yours (I didn't really read the article except to glance at the picture, so this may not be exactly what the author intended, but it works):
looper :: (inputT -> feedfwdT -> feedbackT -> (feedbackT, outputT)) -> inputT -> feedfwdT -> outputT
looper f input primer = output
where (feedback, output) = f input primer feedback
min_feedback :: (Ord a) => [a] -> Maybe a -> a -> (a, [a])
min_feedback [] (Just p) _ = (p, [])
min_feedback (x:xs) partial_min minimum = (feedback, minimum:output)
where new_partial_min = case partial_min
of Nothing -> Just x
Just p -> Just $ min x p
(feedback, output) = min_feedback xs new_partial_min minimum
min_looped :: (Ord a) => [a] -> [a]
min_looped input = looper min_feedback input Nothing
main = print $ min_looped [1,4,6,2,6,3,-1,6,3,6,10]
The key here is that you need more than the feedback channel, you also need a feedforward channel to determine the minimum value on the first pass through the loop. My ASCII art skills are not up to the standard set in the article, so you'll just have to make do with this paint drawing:
The feedforward is the minimum value seen so far in the list. The primer kickstarts the feedforward channel. The feedback channel takes the result value from the feedforward channel back up to the start of the list. Finally the feedback value becomes the minimum value that gets used to fill the output list.
It's
repIIminList (x:[]) m' = ([m'], x)
repIIminList (x:xs) m' = (m' : xs', min x m) where (xs', m) = repIIminList xs m'
m is a current minimum, m' is a final minimum, xs is a current list, xs' is a final list. That is, repIIminList receives a list and a number and recursively replaces every element in a list with this number. repIIminList also computes the minimum of the list. trace applies repIIminList to the minimum, computed by repIIminList itself.
Using the state monad you can rewrite this in a pretty explicit way:
repminList :: [Int] -> [Int]
repminList [] = []
repminList (x:xs) = evalState (go xs) x where
go [] = get >>= return . (:[])
go (x:xs) = modify (min x) >> flip (:) <$> go xs <*> get
Or using CPS style directly:
repminList :: [Int] -> [Int]
repminList [] = []
repminList (x:xs) = foldr (\x r -> (\(x:xs) -> x:x:xs) . r . min x) (:[]) xs x
I'm too tired to analyze your code, divine your intent and the bug. However, I'll happily show you how I avoid having to think that hard when doing basic knot tying.
Its this State Monad, yay! My use of the State monad (below) is just a little plumbing that keeps track of a single current value in a manner that allows the value to be looked-up and updated.
repMin kicks off the computation by taking into account the empty list then running the state monad.
Our worker action f is provided with the input list and the minimum element in the list (currently a thunk, do not evaluate!)
f traverses the list computing the minimum on the way and replacing each element with the soon-to-be-known-but-not-yet-evaluatable minimum value m.
The code:
import Control.Monad.State
repMin :: [Int] -> [Int]
repMin [] = []
repMin xs#(x:_) = let (v,m) = runState (f m xs) x in v
f :: Int -> [Int] -> State Int [Int]
f m xs = mapM (λx -> checkMin x >> return m) xs
where
checkMin :: Int -> State Int ()
checkMin x = modify (min x)
Notice there's a lazyness leak here wrt our huge thunk of min a (min b ( min c ...))), but you get the picture.

Does haskell's foldr always take a two-parameter lambda?

Haskell newb here
I'm working on this problem in haskell:
(**) Eliminate consecutive duplicates of list elements.
If a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed.
Example:
* (compress '(a a a a b c c a a d e e e e))
(A B C A D E)
The solution (which I had to look up) uses foldr:
compress' :: (Eq a) => [a] -> [a]
compress' xs = foldr (\x acc -> if x == (head acc) then acc else x:acc) [last xs] xs
This foldr, according to the solution, takes two parameters, x and acc. It would seem like all foldr's take these parameters; is there any exception to this? Like a foldr that takes 3 or more? If not, is this convention redundant and can the formula be written with less code?
foldr takes a function of 2 arguments, but this doesn't prevent it from taking a function of 3 arguments provided that function has the right type signature.
If we had a function
g :: x -> y -> z -> w
With
foldr :: (a -> b -> b) -> b -> [a] -> b
Where we want to pass g to foldr, then (a -> b -> b) ~ (x -> y -> z -> w) (where ~ is type equality). Since -> is right associative, this means we can write g's signature as
x -> y -> (z -> w)
and its meaning is the same. Now we've produced a function of two parameters that returns a function of one parameter. In order to unify this with the type a -> b -> b, we just need to line up the arguments:
a -> | x ->
b -> | y ->
b | (z -> w)
This means that b ~ z -> w, so y ~ b ~ z -> w and a ~ x so g's type really has to be
g :: x -> (z -> w) -> (z -> w)
implying
foldr g :: (z -> w) -> [x] -> (z -> w)
This is certainly not impossible, although more unlikely. Our accumulator is a function instead, and to me this begs to be demonstrated with DiffLists:
type DiffList a = [a] -> [a]
append :: a -> DiffList a -> DiffList a
append x dl = \xs -> dl xs ++ [x]
reverse' :: [a] -> [a]
reverse' xs = foldr append (const []) xs $ []
Note that foldr append (const []) xs returns a function which we apply to [] to reverse a list. In this case we've given an alias to functions of the type [a] -> [a] called DiffList, but it's really no different than having written
append :: a -> ([a] -> [a]) -> [a] -> [a]
which is a function of 3 arguments.
As with all things in haskell have a look at the types of things to guide your way you can do this for any function in ghci.
Looking at this for foldr we see:
Prelude> :t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
This slightly abstract string can be written in english as:
foldr is a function that takes
1 ) a function with two parameters one of type a and one of type b and returns something of type b
2 ) A value of type b
3 ) A list of values of type a
And returns a value of type b
Where a and b are type variables (see here for a good tutorial on them) which can be filled in with any type you like.
It turns out that you can solve your compress problem using a foldr with a three-argument function.
compress :: Eq a => [a] -> [a]
compress [] = []
compress (z:zs) = z : foldr f (const []) zs z
where f x k w | x==w = k x
| otherwise = x : k x
Let's dissect that. First, we can improve readability by changing the last two lines to
where f x k = \w -> if x==w then k x else x : k x
This makes it evident that a ternary function is nothing but a binary function returning a unary function. The advantage of looking at it in this way is that foldr is best understood when passed a binary function. Indeed, we are passing a binary function, which just happens to return a function.
Let's focus on types now:
f :: a -> (a -> [a]) -> (a -> [a])
f x k
So, x::a is the element of the list we are folding on. Function k is the result of the fold on the list tail. The result of f x k is something having the same type as k.
\w -> if .... :: (a -> [a])
The overall idea behind this anonymous function is as follows. The parameter k plays the same role as acc in the OP code, except it is a function expecting the previous element w in the list before producing the accumulated compressed list.
Concretely, we use now k x when we used acc, passing on the current element to the next step, since by that time x will become the previous element w. At the top-level, we pass z to the function which is returned by foldr f (const []).
This compress variant is lazy, unlike the posted solution. In fact, the posted solution needs to scan the whole list before starting producing something: this is due to (\x acc -> ...) being strict in acc, and to the use of last xs. Instead, the above compress outputs list elements in a "streaming" fashion. Indeed, it works with infinite lists as well:
> take 10 $ compress [1..]
[1,2,3,4,5,6,7,8,9,10]
That being said, I think using a foldr here feels a bit weird: the code above is arguably less readable than the explicit recursion.

Resources