How would you (re)implement iterate in Haskell? - haskell

iterate :: (a -> a) -> a -> [a]
(As you probably know) iterate is a function that takes a function and starting value. Then it applies the function to the starting value, then it applies the same function to the last result, and so on.
Prelude> take 5 $ iterate (^2) 2
[2,4,16,256,65536]
Prelude>
The result is an infinite list. (that's why I use take).
My question how would you implement your own iterate' function in Haskell, using only the basics ((:) (++) lambdas, pattern mataching, guards, etc.) ?
(Haskell beginner here)

Well, iterate constructs an infinite list of values a incremented by f. So I would start by writing a function that prepended some value a to the list constructed by recursively calling iterate with f a:
iterate :: (a -> a) -> a -> [a]
iterate f a = a : iterate f (f a)
Thanks to lazy evaluation, only that portion of the constructed list necessary to compute the value of my function will be evaluated.

Also note that you can find concise definitions for the range of basic Haskell functions in the report's Standard Prelude.
Reading through this list of straightforward definitions that essentially bootstrap a rich library out of raw primitives can be very educational and eye-opening in terms of providing a window onto the "haskell way".
I remember a very early aha moment on reading: data Bool = False | True.

Related

Variable scope in a higher-order lambda function

In working through a solution to the 8 Queens problem, a person used the following line of code:
sameDiag try qs = any (\(colDist,q) -> abs (try - q) == colDist) $ zip [1..] qs
try is an an item; qs is a list of the same items.
Can someone explain how colDist and q in the lambda function get bound to anything?
How did try and q used in the body of lambda function find their way into the same scope?
To the degree this is a Haskell idiom, what problem does this design approach help solve?
The function any is a higher-order function that takes 2 arguments:
the 1st argument is of type a -> Bool, i.e. a function from a to Bool
the 2nd argument is of type [a], i.e. a list of items of type a;
i.e. the 1st argument is a function that takes any element from the list passed as the 2nd argument, and returns a Bool based on that element. (well it can take any values of type a, not just the ones in that list, but it's quite obviously certain that any won't be invoking it with some arbitrary values of a but the ones from the list.)
You can then simplify thinking about the original snippet by doing a slight refactoring:
sameDiag :: Int -> [Int] -> Bool
sameDiag try qs = any f xs
where
xs = zip [1..] qs
f = (\(colDist, q) -> abs (try - q) == colDist)
which can be transformed into
sameDiag :: Int -> [Int] -> Bool
sameDiag try qs = any f xs
where
xs = zip [1..] qs
f (colDist, q) = abs (try - q) == colDist)
which in turn can be transformed into
sameDiag :: Int -> [Int] -> Bool
sameDiag try qs = any f xs
where
xs = zip [1..] qs
f pair = abs (try - q) == colDist) where (colDist, q) = pair
(Note that sameDiag could also have a more general type Integral a => a -> [a] -> Bool rather than the current monomorphic one)
— so how does the pair in f pair = ... get bound to a value? well, simple: it's just a function; whoever calls it must pass along a value for the pair argument. — when calling any with the first argument set to f, it's the invocation of the function any who's doing the calling of f, with individual elements of the list xs passed in as values of the argument pair.
and, since the contents of xs is a list of pairs, it's OK to pass an individual pair from this list to f as f expects it to be just that.
EDIT: a further explanation of any to address the asker's comment:
Is this a fair synthesis? This approach to designing a higher-order function allows the invoking code to change how f behaves AND invoke the higher-order function with a list that requires additional processing prior to being used to invoke f for every element in the list. Encapsulating the list processing (in this case with zip) seems the right thing to do, but is the intent of this additional processing really clear in the original one-liner above?
There's really no additional processing done by any prior to invoking f. There is just very minimalistic bookkeeping in addition to simply iterating through the passed in list xs: invoking f on the elements during the iteration, and immediately breaking the iteration and returning True the first time f returns True for any list element.
Most of the behavior of any is "implicit" though in that it's taken care of by Haskell's lazy evaluation, basic language semantics as well as existing functions, which any is composed of (well at least my version of it below, any' — I haven't taken a look at the built-in Prelude version of any yet but I'm sure it's not much different; just probably more heavily optimised).
In fact, any is simple it's almost trivial to re-implement it with a one liner on a GHCi prompt:
Prelude> let any' f xs = or (map f xs)
let's see now what GHC computes as its type:
Prelude> :t any'
any' :: (a -> Bool) -> [a] -> Bool
— same as the built-in any. So let's give it some trial runs:
Prelude> any' odd [1, 2, 3] -- any odd values in the list?
True
Prelude> any' even [1, 3] -- any even ones?
False
Prelude> let adult = (>=18)
Prelude> any' adult [17, 17, 16, 15, 17, 18]
— see how you can sometimes write code that almost looks like English with higher-order functions?
zip :: [a] -> [b] -> [(a,b)] takes two lists and joins them into pairs, dropping any remaining at the end.
any :: (a -> Bool) -> [a] -> Bool takes a function and a list of as and then returns True if any of the values returned true or not.
So colDist and q are the first and second elements of the pairs in the list made by zip [1..] qs, and they are bound when they are applied to the pair by any.
q is only bound within the body of the lambda function - this is the same as with lambda calculus. Since try was bound before in the function definition, it is still available in this inner scope. If you think of lambda calculus, the term \x.\y.x+y makes sense, despite the x and the y being bound at different times.
As for the design approach, this approach is much cleaner than trying to iterate or recurse through the list manually. It seems quite clear in its intentions to me (with respect to the larger codebase it comes from).

Get elements with odd length in a Haskell list of strings

I have a list of strings in Haskell and I need to get those elements with odd length in another list. How can this be done using higher order functions like foldr, foldl, foldr1, foldl1, filter, map, and so on? I will very much appreciate your help. Can list comprehension be used in this case?
It seems that you are aware that filter exists (since you've mentioned), but perhaps are uncertain how it works. If you're trying to extract a specific subset of a list, this seems to be the right path. If you look at its type-signature, you'll find it's pretty straight-forward:
(a -> Bool) -> [a] -> [a]
That is, it takes a function that returns True or False (i.e. true to contain in the new set, false otherwise) and produces a new list. Similarly, Haskell provides a function called odd in Prelude. It's signature looks as follows:
Integral a => a -> Bool
That is, it can take any Integral type and returns True if it is odd, false otherwise.
Now, let's consider a solution:
filter odd [1..10]
This will extract all the odd numbers between [1,10].
I noticed you mentioned list comprehensions. You probably do not want to use this if you are already given a list and you are simply filtering it. However, a list comprehension would be a perfectly acceptable solution:
[x | x <- [1..10], odd x]
In general, list comprehensions are used to express the generation of lists with more complicated constraints.
Now, to actually answer your question. Since we know we can filter numbers, and if we're using Hoogle searching for the following type (notice that String is simply [Char]):
[a] -> Int
You will see a length function. With some function composition, we can quickly see how to create a function which filters odd length. In summary, we have odd which is type Int -> Bool (in this case) and we have length which is [a] -> Int or-- specifically-- String -> Int. Our solution now looks like this:
filter (odd . length) ["abc","def","eh","123","hm","even"]
Here ya go.
getOddOnes = filter . flip (foldr (const (. not)) id) $ False
Note: if you turn this in for your homework, you'd best be prepared to explain it!

Functional Programming-Style Map Function that adds elements?

I know and love my filter, map and reduce, which happen to be part of more and more languages that are not really purely functional.
I found myself needing a similar function though: something like map, but instead of one to one it would be one to many.
I.e. one element of the original list might be mapped to multiple elements in the target list.
Is there already something like this out there or do I have to roll my own?
This is exactly what >>= specialized to lists does.
> [1..6] >>= \x -> take (x `mod` 3) [1..]
[1,1,2,1,1,2]
It's concatenating together the results of
> map (\x -> take (x `mod` 3) [1..]) [1..6]
[[1],[1,2],[],[1],[1,2],[]]
You do not have to roll your own. There are many relevant functions here, but I'll highlight three.
First of all, there is the concat function, which already comes in the Prelude (the standard library that's loaded by default). What this function does, when applied to a list of lists, is return the list that contains concatenated contents of the sublists.
EXERCISE: Write your own version of concat :: [[a]] -> [a].
So using concat together with map, you could write this function:
concatMap :: (a -> [b]) -> [a] -> [b]
concatMap f = concat . map f
...except that you don't actually need to write it, because it's such a common pattern that the Prelude already has it (at a more general type than what I show here—the library version takes any Foldable, not just lists).
Finally, there is also the Monad instance for list, which can be defined this way:
instance Monad [] where
return a = [a]
as >>= f = concatMap f as
So the >>= operator (the centerpiece of the Monad class), when working with lists, is exactly the same thing as concatMap.
EXERCISE: Skim through the documentation of the Data.List module. Figure out how to import the module into your code and play around with some of the functions.

Would the ability to detect cyclic lists in Haskell break any properties of the language?

In Haskell, some lists are cyclic:
ones = 1 : ones
Others are not:
nums = [1..]
And then there are things like this:
more_ones = f 1 where f x = x : f x
This denotes the same value as ones, and certainly that value is a repeating sequence. But whether it's represented in memory as a cyclic data structure is doubtful. (An implementation could do so, but this answer explains that "it's unlikely that this will happen in practice".)
Suppose we take a Haskell implementation and hack into it a built-in function isCycle :: [a] -> Bool that examines the structure of the in-memory representation of the argument. It returns True if the list is physically cyclic and False if the argument is of finite length. Otherwise, it will fail to terminate. (I imagine "hacking it in" because it's impossible to write that function in Haskell.)
Would the existence of this function break any interesting properties of the language?
Would the existence of this function break any interesting properties of the language?
Yes it would. It would break referential transparency (see also the Wikipedia article). A Haskell expression can be always replaced by its value. In other words, it depends only on the passed arguments and nothing else. If we had
isCycle :: [a] -> Bool
as you propose, expressions using it would not satisfy this property any more. They could depend on the internal memory representation of values. In consequence, other laws would be violated. For example the identity law for Functor
fmap id === id
would not hold any more: You'd be able to distinguish between ones and fmap id ones, as the latter would be acyclic. And compiler optimizations such as applying the above law would not longer preserve program properties.
However another question would be having function
isCycleIO :: [a] -> IO Bool
as IO actions are allowed to examine and change anything.
A pure solution could be to have a data type that internally distinguishes the two:
import qualified Data.Foldable as F
data SmartList a = Cyclic [a] | Acyclic [a]
instance Functor SmartList where
fmap f (Cyclic xs) = Cyclic (map f xs)
fmap f (Acyclic xs) = Acyclic (map f xs)
instance F.Foldable SmartList where
foldr f z (Acyclic xs) = F.foldr f z xs
foldr f _ (Cyclic xs) = let r = F.foldr f r xs in r
Of course it wouldn't be able to recognize if a generic list is cyclic or not, but for many operations it'd be possible to preserve the knowledge of having Cyclic values.
In the general case, no you can't identify a cyclic list. However if the list is being generated by an unfold operation then you can. Data.List contains this:
unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
The first argument is a function that takes a "state" argument of type "b" and may return an element of the list and a new state. The second argument is the initial state. "Nothing" means the list ends.
If the state ever recurs then the list will repeat from the point of the last state. So if we instead use a different unfold function that returns a list of (a, b) pairs we can inspect the state corresponding to each element. If the same state is seen twice then the list is cyclic. Of course this assumes that the state is an instance of Eq or something.

Implementing a peeking iterator in Haskell

I'm porting some code to Haskell that extensively uses the concept of
a peeking iterator. It essentially wraps a collection and provides two
functions, "next" and "peek". The "next" function advances the
iterator and returns the head element, while the "peek" function
returns the head element without advancing the iterator. What would be
an elegant way to translate this concept to Haskell? My best idea so
far is to basically use the State monad to keep track of the current
position of the iterator. Is there a cleaner way?
(I posted this on beginners# too, but didn't get any answers)
The idea of a side-effecting iterator is antithetical to the Haskell Way. You could certainly whip up a monad, but at that point you're using Haskell as (to quote Simon PJ) the world's finest imperative language.
Without knowing more about the code you're trying to port, I can't give very specific advice, but here are my general thoughts:
Implement your iteration using some kind of fold.
The function that you pass to your fold operation should be composed of other functions. Probably a composition of zero or more 'peeking' operations plus one 'nexting' operation.
If your fold expects something of type a -> b -> a, your peek and next versions probably both have this type, and you compose them like this:
peek_then_next :: (a -> b -> a) -> (a -> b -> a) -> (a -> b -> a)
peek_then_next peek next = next'
where next' a b = let a' = peek a b
in next a' b
You'll see that both the peek and next arguments look at the same b, but the peek accumulates information into a' which is then seen by the next operation.
You compose as many of these as you like, then pass the composition to foldl or something similar.
Usually in Haskell, instead of an iterator, you would compute an infinite list (typically generated by a recursive function). Instead of "getting elements out of" the iterator, you simply iterate down the list (typically using a recursive function, or a fold or map or something), and look at the elements in the list as you see fit. Because Haskell is lazy, it only computes values as you need them.
I think you should implement your task using a recursive function that takes the infinite list. To "peek", simply look at the first element of the list. (You can "peek" as many elements down past the current "head" of the list as you want, simply by indexing the list.) To "advance" the iterator, simply recursively call yourself with the tail of the list.
type Iterator a = [a]
peek :: Iterator a -> a
peek = head
next :: Iterator a -> Iterator a
next = tail
What you describe sounds like Haskell's regular old built-in singly-linked List. Perhaps even a zipper.
You can do exactly what you want in Haskell, but be warned that these are heavy guns:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
class Iterator as a | as -> a where
peek :: as -> a
next :: as -> (as, a)
--sample implementation
instance Iterator [a] a where
peek as = head as
next as = (tail as, head as)
--sample use
main = print $ next $ [3,4]
--([4],3)
Of course the Iterator doesn't change, it has to give back a new version of it (pretty similar to the random number generator), but I think something "mutable" would be overkill here.
That said, I think you should really use more idiomatic ways to do what you want in Haskell. Maybe you should look how the Reader monad works: http://learnyouahaskell.com/for-a-few-monads-more#reader

Resources