I am learning Haskell for a university course and i have a question about reducible expressions (redexes). I understand the concept yet I still have some questions that I can't seem to figure out on my own.
Lets say you would want to find all the reducible expressions in an expression, like this:
head (map (+1) (3:repeat 3))
In this expression an obvious redex would be map (+1) (3:repeat 3)) because it matches to the definition of map, so Haskell would "reduce" the expression and map would increment the 3 and 4:map (+1) (repeat 3). would be reduced next.
The question I have is:
Is head (map (+1) (3:repeat 3)) already a redex, before map is evaluated?
Because the "input" of head does not match the constructor of a list (which is what head is looking for), I am confused about whether it still is a redex because logically it can't get reduced yet, but the definitions online seem to be saying that it would be.
Haskell's evaluation is lazy: it proceeds by topmost leftmost redex strategy (at least conceptually): it reduces the leftmost among the topmost redexes.
Presumably head is defined as
head xs = case xs of (x:_) -> x
so then its application to whatever expression is indeed a redex -- an expression in need of reducing. Which proceeds according to the definition of head,
head (map (+1) (3:repeat 3))
=
case (map (+1) (3:repeat 3)) of (x:_) -> x
=
(or we could say that head itself is the topmost leftmost redex, which reduces to its definition, first; and if we'd written the above as ((\xs -> case xs of (x:_) -> x) (map (+1) (3:repeat 3))) we'd get to the same outcome, just a bit more tediously).
A primary forcing primitive is case. Now it needs to perform the pattern match, so it must find out the value of its scrutinee expression (only to the extent that the pattern match becomes possible). To do that it must now work according to the definition of map which is presumably
map f xs = case xs of { (x:ys) -> f x : map f ys
; [] -> [] }
so it becomes
case (map (+1) (3:repeat 3)) of (x:_) -> x
=
case (case (3:repeat 3) of
{ (x:ys ) -> (+1) x : map (+1) ys
; [] -> [] } )
of (x:_) -> x
=
At this point the inner case expression can be reduced,
case (let { x=3 ; ys=repeat 3} in
(+1) x : map (+1) ys )
of (x : _ ) -> x
=
and now the outer case's pattern matching becomes possible,
case (let { x=3 } in
(+1) x )
of (x ) -> x
=
let { x=3 } in
(+1) x
=
(+1) 3
=
4
Related
So I m watching a very basic Tutorial, and I m at list comprehension where this comes up:
listx2 = [x * 2 | x<- numberList]
with numberList being a list of numbers
So this takes every number in the list and duplicates it, so numberList = [1,2] results in [2,4].
But HOW does the whole Syntax come together?
I know that x * 2 is the doubleing, but the rest just doesn't make sense to me.
| is the "or" Symbol as far as I know,and what does it do there?
x <- numberList gives x a number from the list, but why does it take just a number? and why so nicely one after the other? There is no recursion or anything that tells it to do one element at a time...
I learn stuff by understanding it, so is that even possible here or do I just have to accept this as "thats how it goes" and memorize the pattern?
List comprehensions use their own special syntax, which is
[ e | q1, q2, ..., qn ]
The | is not an "or", it's part of the syntax, just as [ and ].
Each qi can be of the following forms.
x <- list chooses x from the list
condition is a boolean expression, which discards the xs chosen before if the condition is false
let y = expression defines variable y accordingly
Finally, e is an expression which can involve all the variables defined in the qi, and which forms the elements in the resulting list.
What you see is syntactical sugar. So Haskell does not interpret the pipe (|) as a guard, etc. It sees the list comprehension as a whole.
This however does not mean that the <- are picked at random. Actually list comprehension maps nicely on the list monad. What you see is syntactical sugar for:
listx2 = do
x <- numberList
return x*2
Now a list type [] is actually a monad. It means that we have written:
listx2 = numberList >>= \x -> return (x*2)
Or even shorter:
listx2 = numberList >>= return . (*2)
Now the list monad is defined as:
instance Monad [] where
return x = [x]
xs >>= k = concat $ fmap k xs
So this means that it is equivalent to:
listx2 = numberList >>= return . (*2)
listx2 = concat (fmap (return . (*2)) numberList)
listx2 = concat (fmap (\x -> [2*x]) numberList)
Now for a list fmap is equal to map, so:
listx2 = concat $ map (\x -> [2*x]) numberList
listx2 = concatMap (\x -> [2*x]) numberList
so that means that for every element x in the numberList we will generate a singleton list [2*x] and concatenate all these singleton lists into the result.
I went through a post for this problem but I do not understand it. Could someone please explain it?
Q: Find every n-th element of the list in the form of a list start from the n-th element itself.
everyNth :: Int -> [t] -> [t]
everyNth elt = map snd . filter (\(lst,y) -> (mod lst elt) == 0) . zip [1..]
Also, please explain how pattern matching can be used for this problem. That is using
[]->[]
It's easy to use pattern matching to 'select every nth element' for particular cases of n:
every2nd (first:second:rest) = second : every2nd rest
every2nd _ = []
-- >>> every2nd [1..12]
-- [2,4,6,8,10,12]
every3rd (first:second:third:rest) = third : every3rd rest
every3rd _ = []
-- >>> every3rd [1..13]
-- [3,6,9,12]
every4th (first:second:third:fourth:rest) = fourth : every4th rest
every4th _ = []
-- >>> every4th [1..12]
-- [4,8,12]
For the general case, though, we're out of luck, at least with that particular approach. Patterns like those above will need some definite length to be definite patterns. The composed function you mention starts from the thought that we do know how to find every nth member of [1..], namely if it's a multiple of n
multiple n m = m `mod` n == 0
-- >>> filter (multiple 3) [1..12]
-- [3,6,9,12]
So the solution you are trying to understand zips [1..] with the list
index xs = zip [1..] xs
-- >>> index [1..5]
-- [(1,1),(2,2),(3,3),(4,4),(5,5)]
-- >>> index "hello"
-- [(1,'h'),(2,'e'),(3,'l'),(4,'l'),(5,'o')]
Then it filters out just those pairs whose first element is a multiple of n
every_nth_with_index n xs = filter (\(m,a) -> multiple n m) (index xs)
-- >>> every_nth_with_index 3 [1..12]
-- [(3,3),(6,6),(9,9),(12,12)]
-- >>> every_nth_with_index 3 "stackoverflow.com"
-- [(3,'a'),(6,'o'),(9,'r'),(12,'o'),(15,'c')]
Then it gets rid of the ancillary construction, leaving us with just the second element of each pair:
every_nth n xs = map snd (every_nth_with_index n xs)
-- >>> every_nth 3 [1..12]
-- [3,6,9,12]
-- >>> every_nth 3 "stackoverflow.com"
-- "aoroc"
Retracinging our steps we see that this is the same as
everyNth elt = map snd . filter (\(lst,y) -> (mod lst elt) == 0) . zip [1..]
The notorious fold fan strikes again.
everyNth n xs = foldr go (`seq` []) xs n where
go x r 0 = x : r (n - 1)
go _ r k = r (k - 1)
This is very similar to chepner's approach but it integrates the dropping into the recursion. Rewritten without the fold, it's pure pattern matching:
everyNth n = go n where
go k [] = k `seq` []
go 0 (x : xs) = x : go (n - 1) xs
go k (_ : xs) = go (k - 1) xs
With a little cheating, you can define everyNth using pattern matching. Really, we're abstracting out the part that makes pattern matching difficult, as pointed out in Michael's answer.
everyNth n lst = e (shorten lst)
where shorten = drop (n-1) -- here's the cheat
e [] = []
e (first:rest) = first : e (shorten rest)
If you have never seen Haskell before then this takes a bit of explaining.
everyNth :: Int -> [t] -> [t]
everyNth elt = map snd . filter (\(lst,y) -> (mod lst elt) == 0) . zip [1..]
First, note that the type has two arguments, but the definition has only one. This is because the value returned by everyNth is in fact another function. elt is the Int, and the expression in the second line creates a new function that does the job.
Second, note the "." operators. This is an operator that joins two functions together. It is defined like this:
(f . g) x = f (g x)
Here is an equivalent version of the definition with the second argument made explicit:
everyNth elt xs = map snd (filter (\(lst y) -> (mod lst elt) == 0) (zip xs))
When you see a bunch of functions in a chain linked by "." operators you need to read it from right to left. In my second version pay attention to the bracket nesting. zip [1..] xs is the inner-most expression, so it gets evaluated first. It turns a list like ["foo", "bar"] into [(1, "foo"),(2, "bar")]. Then this is filtered to find entries where the number is a multiple of elt. Finally the map snd strips the numbers back out to return just the required entries.
I just started using Haskell and wanted to write a function that, given a list, returns a list in which every 2nd element has been doubled.
So far I've come up with this:
double_2nd :: [Int] -> [Int]
double_2nd [] = []
double_2nd (x:xs) = x : (2 * head xs) : double_2nd (tail xs)
Which works but I was wondering how you guys would write that function. Is there a more common/better way or does this look about right?
That's not bad, modulo the fixes suggested. Once you get more familiar with the base library you'll likely avoid explicit recursion in favor of some higher level functions, for example, you could create a list of functions where every other one is *2 and apply (zip) that list of functions to your list of numbers:
double = zipWith ($) (cycle [id,(*2)])
You can avoid "empty list" exceptions with some smart pattern matching.
double2nd (x:y:xs) = x : 2 * y : double2nd xs
double2nd a = a
this is simply syntax sugar for the following
double2nd xss = case xss of
x:y:xs -> x : 2 * y : double2nd xs
a -> a
the pattern matching is done in order, so xs will be matched against the pattern x:y:xs first. Then if that fails, the catch-all pattern a will succeed.
A little bit of necromancy, but I think that this method worked out very well for me and want to share:
double2nd n = zipWith (*) n (cycle [1,2])
zipWith takes a function and then applies that function across matching items in two lists (first item to first item, second item to second item, etc). The function is multiplication, and the zipped list is an endless cycle of 1s and 2s. zipWith (and all the zip variants) stops at the end of the shorter list.
Try it on an odd-length list:
Prelude> double_2nd [1]
[1,*** Exception: Prelude.head: empty list
And you can see the problem with your code. The 'head' and 'tail' are never a good idea.
For odd-lists or double_2nd [x] you can always add
double_2nd (x:xs) | length xs == 0 = [x]
| otherwise = x : (2 * head xs) : double_2nd (tail xs)
Thanks.
Here's a foldr-based solution.
bar :: Num a => [a] -> [a]
bar xs = foldr (\ x r f g -> f x (r g f))
(\ _ _ -> [])
xs
(:)
((:) . (*2))
Testing:
> bar [1..9]
[1,4,3,8,5,12,7,16,9]
Trying to create a Haskell program that increments every number in a list by one.
module Add1List where
add1_list_comp :: [Integer] -> [Integer]
add1_list_comp [x] = [x + 1| x <- [x]]
It works when I call this add1_list_comp [3] ... it gives me [4]
But when I do add1_list_comp [3, 4, 5] ... it throws me an error saying
"non-exhaustive patterns in function add1_list_comp"
Any help would be much appreciated!
add1_list_comp = map succ
that simple
or, in your way
add1_list_comp xs = [x + 1| x <- xs]
the problem with your code is that
add1_list_comp [x]
does pattern match on list with single item, that's why it fails on list with several items.
I see that the question has been answered, but perhaps I can explain a bit more.
The argument of a function is pattern matched, and the general rules are
(x:xs)
x is the head of the list and xs is the tail of the list, and potentially empty list
[]
empty list
[x] or (x:[])
are the same which is a list with only one variable
and a name with no constructor such as "[]", ":", "(,)" around can match anything, so if you want to match a special case, you should put the special case in front of the general pattern.
length [] = 0
length [x] = 1
length (x : xs) = 1 + length xs
BTW, generally speaking, there will always be a higher order function when you want to do something with a list. for your case
add1 xs = map (+1) xs
is nicer and it took advantage of the built in library, and you can also do a point free version of it
add1 = map (+1)
Well actually since the topic states "Increment by One" without defining what type is going to be incremented by one, just for the sake of a visitor ended up here lets give a solution which would increment any functor by one, which of course includes the list type. So;
List functor
*Main> fmap (+1) [1,2,3]
[2,3,4]
Maybe functor (id applies to Nothing)
*Main> fmap (+1) (Just 1)
Just 2
Either functor (id applies to Left _)
*Main> fmap (+1) (Right 2)
Right 3
IO functor
*Main> fmap ((+1) . read) getLine
2017
2018
Currently I am doing something like this in my code:
--Generate a list of n 'Foo's
generateFoos n = [createFoo (show i) | i <- [1..n]]
-- Create a Foo with a given name
createFoo :: String -> Foo
I was wandering if there is a another way of doing this than creating a range [1..n] all the time...
I would say don't worry about it. "Creating the range [1..n]" isn't really going on here as a distinct step; that [1..n] desugars to enumFromTo 1 n and it's constructed lazily like everything else anyway. There's no hidden cost here one would need to eliminate.
Expanding on my comment above - the reason the map function arises naturally here is as follows.
In Haskell, list comprehensions are just syntactic sugar for do notation:
[ 2 * x | x <- [1..10] ]
is equivalent to
do { x <- [1..10]; return (2 * x) }
In turn, do notation is syntactic sugar for monadic binds - the above is equivalent to
[1..10] >>= \x -> return (2 * x)
This works because List is a monad. The code that makes List into a monad is (ignoring some irrelevant stuff)
instance Monad [] where
return x = [x]
xs >>= f = concat (map f xs)
so the call to >>= above is equivalent to
concat (map (\x -> return (2 * x)) [1..10])
which, if we replace the call to bind, is equivalent to
concat (map (\x -> [2 * x]) [1..10])
So we map the function \x -> [2 * x] over the list [1..10] and then call concat on the result. But since our function only every builds one element lists, we can skip out the call to concat and replace the code with
map (\x -> 2 * x) [1..10]
So it's natural that relatively simple list comprehensions can be turned into expressions that involve mapping a function over a range.
I prefer it that way:
generateFoos n = map (createFoo . show) [1..n]
Or are the ranges itself the problem? Then I'd recommend:
generateFoos n = map (createFoo . show) (enumFromTo 1 n)
No map, no range.
generateFoos n = unfoldr (doit (createFoo . show)) 1 where
doit f acc = if acc > n then Nothing else Just (f acc, acc + 1)
I do not guarantee any particular quality or property of this code though ;)