Haskell building a list of tuples - haskell

I am trying to build a list of tuples. Input is a list of tuples [([char], int1, int2), ...] and the output is the list of tuples such that [([char], int1, int2, (int1/int2)), ...]. I know that this code below is wrong because I think it is building a list of lists of tuples [[(),(),(),()], [(),(),(),()]].
Code:
{- take a list of labels, values, and weights and return list of labels and fractions -}
fraclist [] = []
fraclist x = [ (y,r,q,z) : y <- first (head x) | r <- scnd (head x) | q <- last (head x) | z <- r/q ] : fraclist tail x
{- helper func to get values from tuples -}
frst (a,b,c) = a
scnd (a,b,c) = b
last (a,b,c) = c
How might I get the proper output form as described? Also, how might I output the list of tuples ordered such that the z's are in descending order?

This code doesn't compile (syntax errors), but after fixing that (I'd recommend reading up on the syntax of list comprehensions (','s vs. '|'s)) and making some other changes:
used a list comprehension, which takes care of the base case and the mapping over the list -- so I was able to eliminate fraclist [] = [] and the head/tail/: business
used pattern matching to pull the values out of the input tuples -- this is often much easier to read than using functions to take apart values
added an explicit type signature for documentation purposes
here's what I think you meant:
fraclist :: (Integral t1) => [(t, t1, t1)] -> [(t, t1, t1, t1)]
fraclist xs = [(x, y, z, div y z) | (x, y, z) <- xs]
I'll leave the sorting to you.

I think you want just
fraclist xs = [(y,r,q, r `quot` q) | (y,r,q) <- xs]
(Note: I used quot instead of (/) since you named the components int1, int2.)
A variant not using list comprehensions is
fraclist = map (\(y,r,q) -> (y,r,q, r `quot` q))
Your code doesn't compile, in such cases it is better to post the error message so people can see at one glance what the probable cause is.
You get a parse erro on the first <- in
fraclist x = [ (y,r,q,z) : y <- first (head x) | r <- scnd (head x) | q <- last (head x) | z <- r/q ] : fraclist tail x
because the expression (y,r,q,z) : y <- first (head x) before the first | separating the generated expressions from the generator expressions isn't well-formed. I think it's just a typo and you meant to use | instead of (:) there too.
Then you have several | separators in your list comprehension, which is not valid without the ParallelListComp extension. However, the code doesn't look like a parallel list comprehension is really what you attempt here, since all three values are drawn from the same list. Finally, the last part | z <- r/q is again not well-formed, since r/q is not a list from which elements can be drawn in a list comprehension. You probably intended let z = r/q there.

Here is a simple solution without list comprehension:
import Data.List
-- (string, int1, int2) -> (string int1, int2, (int1/int2))
fraclist list = map generateTuple list
where generateTuple (label, value, weight) = (label, value, weight, (value)/(weight))
sortFracListByValueWeightRatio list = sortBy sorter list
where sorter (_,_,_,d) (_,_,_,h) = if d > h then GT else LT
testList = [("first",3.0,4.0), ("second",4.0,7.0)]
Nothing fancy (I've only used haskell a week).
fraclist works by mapping the generateTuple function to the list. The generateTuple function simply returns a tuple of form (title, value, weight, value/weight). Map is a built in function which simply applies a given function to each element of the list.
The sortFracListByValueWeightRatio (sorry for the long name) uses the built in sortBy function (comes from Data.List), which sorts a given list using a custom function for comparing items. Sorter is my item comparer, and it simply compares the value/weight ratios and returns either GT or LT (Greater Than / Lower Than). Hence, the list items are compared using the custom comparer, and sorted based on its answer.
A significant improvement of readability would probably be to use types to describe the values instead of just tuples. Also I'm using doubles in the test list, but that is easy to change.

Related

How does listx2 = [x * 2 | x<- numberList] work?

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.

find element from list and put to front, while preserving order

Im trying to make a function that takes a list of colours and a specific colour as input. It will look through the list of colours until it finds the specific colour and put it in the front. I want to do this all while perserving the order of the rest of the numbers.
So for example:
putfront [] (red:blue:green:yellow:white:pink:orange:[]) yellow
returns
yellow:red:blue:green:white:pink:orange:[]
This is my attempt:
putfront::[Colour]->[Colour]->Colour-> [Colour]
putfront leftofcurrent (current:rightofcurrent) thecolour
|current==thecolour = thecolour:leftofcurrent:rightofcurrent
|otherwise= putfront (leftofcurrent:current:[]) rightofcurrent thecolour
But Haskell doesn't seem to be too happy with:
thecolour:leftofcurrent:rightofcurrent
and
(leftofcurrent:current:[])
saying:
Expected type: Pond_Ix
Actual type: [Pond_Ix]
What is wrong?
But Haskell doesn't seem to be too happy with:
thecolour:leftofcurrent:rightofcurrent
That's because leftofcurrent is a List. If you want to combine those lists, it needs to be:
(thecolour:leftofcurrent) ++ rightofcurrent
Likewise, (leftofcurrent:current:[]) is impossible because leftofcurrent is a List, but this is probably what you're after:
leftofcurrent ++ [current]
The cons operator : expects a single element on the left and a list on the right. But because of its fixity, you can chain them together so that a bunch of single items are separated by : and ended with a list. That is,
item1:item2:item3:[]
-- is the same as
item1:(item2:(item3:[]))
Also, your pattern matching is non-exhaustive. You need to handle the case where the second list parameter is empty.
putfront leftofcurrent [] thecolour = ...
I would write it as follows
putfront :: (Eq a) => a -> [a] -> [a]
putfront a x | a `elem` x = a: filter (not . (==a)) x
| otherwise = x
> putfront 4 [1..8]
[4,1,2,3,5,6,7,8]
you can recursively write it as well
putfront a x = bubble [] x
where bubble p [] = p
bubble p (s:ss) | a==s = a:p++ss
| otherwise = bubble (p++[s]) ss
> putfront 3 [1..5]
[3,1,2,4,5]
> putfront 7 [1..5]
[1,2,3,4,5]
I actually think that your best soln is to remove the item and put it at the front of the list, as you mention in the comment. Given that you don't like this, may I suggest the following
sortBy (\x y -> case (x, y) of (_, theColour) -> GT; (x, y) ->LT) listOfColours

How to shorten a Haskell implementation like this?

I have a function with a lot of guards that look like this:
function
| p `elem` [0,1,2,3,4,5,6] = [0,1,2,3,4,5,6]
| p `elem` [7,8,9,10,11,12,13] = [7,8,9,10,11,12,13]
| p `elem` [14,15,16,17,18,19,20] = [14,15,16,17,18,19,20]
| otherwise = []
I'm sure I can write this much shorter with Haskell. If not, then it's okay. I'm new to Haskell and I would love to become better at it by learning different approaches.
Perhaps using "map" may be a good start? But then, I'm not sure how to pass in those specific lists.
The values are not always contiguous.
What about simple bounds checks?
function p
| p < 0 = []
| p < 7 = [0..6]
| p < 14 = [7..13]
| p < 21 = [14..20]
| otherwise = []
It will be faster and for some applications use less memory.
If you don't want to perform a bounds check (but an element check), you can still use the shortened list notation.
Alternatively, you could construct a helper function that iterates over the lists:
helper (x:xs) p | elem p x = x
| otherwise = helper xs p
helper [] _ = []
function = helper [[0..6],[7..13],[14..20]]
Although this is actually longer, you can easily extend the function to use other lists. Note however that this function will be slower, since elem requires O(n) time whereas a bounds check takes O(1) time.
You can also - as is suggested in #jamshidh's answer construct a Data.Map which is a datastructure that guarantees O(log n) lookup time:
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Maybe(fromMaybe)
helper2 :: Ord a => [[a]] -> a -> [a]
helper2 lst p = fromMaybe [] $ Map.lookup p (Map.fromList $ concatMap (\x -> zip x (repeat x)) lst)
function = helper2 [[0..6],[7..13],[14..20]]
For this last piece, it generates (\x -> zip x (repeat x)) generates for a list tuples containing an element of the list e and the entire list l. For example:
Prelude> (\x -> zip x (repeat x)) [0..6]
[(0,[0,1,2,3,4,5,6]),(1,[0,1,2,3,4,5,6]),(2,[0,1,2,3,4,5,6]),(3,[0,1,2,3,4,5,6]),(4,[0,1,2,3,4,5,6]),(5,[0,1,2,3,4,5,6]),(6,[0,1,2,3,4,5,6])]
This works as follows: x unifies with a list, for instance [0,1,2,3,4,5,6], now we apply a zip function on [0,1,2,3,4,5,6] and on the infinite list [[0,1,2,3,4,5,6],[0,1,2,3,4,5,6],[0,1,2,3,4,5,6],....]. zip generates tuples as long as both lists feed elements, so it takes the first element from [0,1,..,6] and the first from [[0,1,..,6],[0,1,..,6],[0,1,..,6],...] so the resulting tuple is (0,[0..6]), next it takes the second element 1 from the list, and the second item from the repeat function, thus (1,[0..6]). It keeps doing this -- although lazily -- until one of the lists is exhausted which is the case for the first list.
You can use the list monad here.
func p = join $ do x <- [[1,3,5], [2,4,6], [7,8,9]]
guard $ p `elem` x
return x
The list of lists are the things you want to check against. The call to guard filters out the choices that don't succeed. As long as the candidate lists are disjoint, at most one will succeed. return x evaluates to either [] or [x] for one of the choices of x, so join
reduces [x] to [].
> func 1
[1,3,5]
> func 2
[2,4,6]
> func 7
[7,8,9]
> func 10
[]
As a list comprehension, it would look like
func p = join [x | x <-[[1,3,5],[2,4,6],[7,8,9]], p `elem` x]
First create the list of lists
lists = [[0,1,2,3,4,5,6], [7,8,9,10,11,12,13], [14,15,16,17,18,19,20]]
Then create a mapping from value to list
theMap = concat $ map (\x -> zip x (repeat x)) lists
This will give you what you need
> lookup 1
Just [0,1,2,3,4,5,6]
Note that the output is a Maybe, in the case you don't supply a value in any list.

How do i "put a restriction" on a list of permutations and subsequences of a list?

I'm really new to programming and Haskell in particular (so new that I actually don't know if this is a stupid question or not). But I was watching the lecture given by Eric Meijer (http://channel9.msdn.com/Series/C9-Lectures-Erik-Meijer-Functional-Programming-Fundamentals) and i was fascinated by the program written by Dr. Graham Hutton in lecture 11; The countdown problem.
My question is:
Is there a way of "filtering" the list of solutions by the length (number of elements), so that the list of solutions are restricted to the solutions that only uses (for example) three of the source numbers? In other words, I would like to change the question from "given the numbers [1,2,3,4,5,6,8,9] construct 18 using the operators..." to "given the numbers [..] which three numbers can be used to construct..."
In my futile attempts, I've been trying to put a kind restriction on his function subbags (which returns all permutations and subsequences of a list)
subbags :: [a] -> [[a]]
subbags xs = [zs | ys <- subs xs, zs <- perms ys]
So that I get all the permutations and subsequences that only contain three of the source numbers. Is this possible? If so, how?
Like I said, I have no idea if this is even a legitimate question - but I have gone from curious to obsessed, so any form of help or hint would be greatly appreciated!
The simplest way would be to just select from the candidates three times
[ (x, y, z) | x <- xs, y <- xs, z <- xs ]
although this assumes that repeat use of a single number is OK.
If it's not, we'll have to get smarter. In a simpler scenario we'd like to pick just two candidates:
[ (x, y) | x <- xs, y <- ys, aboveDiagonal (x, y) ]
in other words, if we think of this as a cartesian product turning a list into a grid of possibilities, we'd like to only consider the values "above the diagonal", where repeats don't happen. We can express this by zipping the coordinates along with the values
[ (x, y) | (i, x) <- zip [1..] xs
, (j, y) <- zip [1..] xs
, i < j
]
which can be extended back out to the n=3 scenario
[ (x, y, z) | (i, x) <- zip [1..] xs
, (j, y) <- zip [1..] xs
, (k, z) <- zip [1..] xs
, i < j
, j < k
]
Ultimately, however, this method is inefficient since it still has to scan through all of the possible pairs and then prune the repeats. We can be a bit smarter by only enumerating the above diagonal values to begin with. Returning to n=2 we'll write this as
choose2 :: [a] -> [(a, a)]
choose2 [] = []
choose2 (a:as) = map (a,) as ++ choose2 as
In other words, we pick first all of the pairs where the head of the list comes first and a value in the tail of the list comes second—this captures one edge of the upper triangle—and then we recurse by adding all of the upper diagonal values of the list of candidates sans the head.
This method can be straightforwardly extended to the n=3 case by using the n=2 case as a building block
choose3 :: [a] -> [(a, a, a)]
choose3 [] = []
choose3 (a:as) = map (\(y, z) -> (a, y, z)) (choose2 as) ++ choose3 as
which also provides a direct generalization to the fully general n dimensional solution
choose :: Int -> [a] -> [[a]]
choose 0 as = [[]] -- there's one way to choose 0 elements
choose _ [] = [] -- there are 0 ways to choose (n>0) elements of none
choose 1 as = map (:[]) as -- there are n ways to choose 1 element of n
choose n (a:as) = map (a:) (choose (n-1) as) ++ choose n as
I like this solution, which does not require the list elements to be an instance of Eq:
import Data.List (tails)
triples ls = [[x,y,z] | (x:xs) <- tails ls,
(y:ys) <- tails xs,
z <- ys]
This returns only subsequences, not permutations, though.

Dovetail iteration over infinite lists in Haskell

I want to iterate 2 (or 3) infinite lists and find the "smallest" pair that satisfies a condition, like so:
until pred [(a,b,c) | a<-as, b<-bs, c<-cs]
where pred (a,b,c) = a*a + b*b == c*c
as = [1..]
bs = [1..]
cs = [1..]
The above wouldn't get very far, as a == b == 1 throughout the run of the program.
Is there a nice way to dovetail the problem, e.g. build the infinite sequence [(1,1,1),(1,2,1),(2,1,1),(2,1,2),(2,2,1),(2,2,2),(2,2,3),(2,3,2),..] ?
Bonus: is it possible to generalize to n-tuples?
There's a monad for that, Omega.
Prelude> let as = each [1..]
Prelude> let x = liftA3 (,,) as as as
Prelude> let x' = mfilter (\(a,b,c) -> a*a + b*b == c*c) x
Prelude> take 10 $ runOmega x'
[(3,4,5),(4,3,5),(6,8,10),(8,6,10),(5,12,13),(12,5,13),(9,12,15),(12,9,15),(8,15,17),(15,8,17)]
Using it's applicative features, you can generalize to arbitrary tuples:
quadrupels = (,,,) <$> as <*> as <*> as <*> as -- or call it liftA4
But: this alone does not eliminate duplication, of course. It only gives you proper diagonalization. Maybe you could use monad comprehensions together with an approach like Thomas's, or just another mfilter pass (restricting to b /= c, in this case).
List comprehensions are great (and concise) ways to solve such problems. First, you know you want all combinations of (a,b,c) that might satisfy a^2 + b^2 = c^2 - a helpful observation is that (considering only positive numbers) it will always be the case that a <= c && b <= c.
To generate our list of candidates we can thus say c ranges from 1 to infinity while a and b range from one to c.
[(a,b,c) | c <- [1..], a <- [1..c], b <- [1..c]]
To get to the solution we just need to add your desired equation as a guard:
[(a,b,c) | c <- [1..], a <- [1..c], b <- [1..c], a*a+b*b == c*c]
This is inefficient, but the output is correct:
[(3,4,5),(4,3,5),(6,8,10),(8,6,10),(5,12,13),(12,5,13),(9,12,15)...
There are more principled methods than blind testing that can solve this problem.
{- It depends on what is "smallest". But here is a solution for a concept of "smallest" if tuples were compared first by their max. number and then by their total sum. (You can just copy and paste my whole answer into a file as I write the text in comments.)
We will need nub later. -}
import Data.List (nub)
{- Just for illustration: the easy case with 2-tuples. -}
-- all the two-tuples where 'snd' is 'n'
tuples n = [(i, n) | i <- [1..n]]
-- all the two-tuples where 'snd' is in '1..n'
tuplesUpTo n = concat [tuples i | i <- [1..n]]
{-
To get all results, you will need to insert the flip of each tuple into the stream. But let's do that later and generalize first.
Building tuples of arbitrary length is somewhat difficult, so we will work on lists. I call them 'kList's, if they have a length 'k'.
-}
-- just copied from the tuples case, only we need a base case for k=1 and
-- we can combine all results utilizing the list monad.
kLists 1 n = [[n]]
kLists k n = do
rest <- kLists (k-1) n
add <- [1..head rest]
return (add:rest)
-- same as above. all the klists with length k and max number of n
kListsUpTo k n = concat [kLists k i | i <- [1..n]]
-- we can do that unbounded as well, creating an infinite list.
kListsInf k = concat [kLists k i | i <- [1..]]
{-
The next step is rotating these lists around, because until now the largest number is always in the last place. So we just look at all rotations to get all the results. Using nub here is admittedly awkward, you can improve that. But without it, lists where all elements are the same are repeated k times.
-}
rotate n l = let (init, end) = splitAt n l
in end ++ init
rotations k l = nub [rotate i l | i <- [0..k-1]]
rotatedKListsInf k = concatMap (rotations k) $ kListsInf k
{- What remains is to convert these lists into tuples. This is a bit awkward, because every n-tuple is a separate type. But it's straightforward, of course. -}
kListToTuple2 [x,y] = (x,y)
kListToTuple3 [x,y,z] = (x,y,z)
kListToTuple4 [x,y,z,t] = (x,y,z,t)
kListToTuple5 [x,y,z,t,u] = (x,y,z,t,u)
kListToTuple6 [x,y,z,t,u,v] = (x,y,z,t,u,v)
{- Some tests:
*Main> take 30 . map kListToTuple2 $ rotatedKListsInf 2
[(1,1),(1,2),(2,1),(2,2),(1,3),(3,1),(2,3),(3,2),(3,3),(1,4),(4,1),(2,4),(4,2),(3,4),
(4,3),(4,4),(1,5),(5,1),(2,5),(5,2),(3,5),(5,3),(4,5),(5,4),(5,5),(1,6),(6,1),
(2,6), (6,2), (3,6)]
*Main> take 30 . map kListToTuple3 $ rotatedKListsInf 3
[(1,1,1),(1,1,2),(1,2,1),(2,1,1),(1,2,2),(2,2,1),(2,1,2),(2,2,2),(1,1,3),(1,3,1),
(3,1,1),(1,2,3),(2,3,1),(3,1,2),(2,2,3),(2,3,2),(3,2,2),(1,3,3),(3,3,1),(3,1,3),
(2,3,3),(3,3,2),(3,2,3),(3,3,3),(1,1,4),(1,4,1),(4,1,1),(1,2,4),(2,4,1),(4,1,2)]
Edit:
I realized there is a bug: Just rotating the ordered lists isn't enough of course. The solution must be somewhere along the lines of having
rest <- concat . map (rotations (k-1)) $ kLists (k-1) n
in kLists, but then some issues with repeated outputs arise. You can figure that out, I guess. ;-)
-}
It really depends on what you mean by "smallest", but I assume you want to find a tuple of numbers with respect to its maximal element - so (2,2) is less than (1,3) (while standard Haskell ordering is lexicographic).
There is package data-ordlist, which is aimed precisely at working with ordered lists. It's function mergeAll (and mergeAllBy) allows you to combine a 2-dimensional matrix ordered in each direction into an ordered list.
First let's create a desired comparing function on tuples:
import Data.List (find)
import Data.List.Ordered
compare2 :: (Ord a) => (a, a) -> (a, a) -> Ordering
compare2 x y = compare (max2 x, x) (max2 y, y)
where
max2 :: Ord a => (a, a) -> a
max2 (x, y) = max x y
Then using mergeAll we create a function that takes a comparator, a combining function (which must be monotonic in both arguments) and two sorted lists. It combines all possible elements from the two lists using the function and produces a result sorted list:
mergeWith :: (b -> b -> Ordering) -> (a -> a -> b) -> [a] -> [a] -> [b]
mergeWith cmp f xs ys = mergeAllBy cmp $ map (\x -> map (f x) xs) ys
With this function, it's very simple to produce tuples ordered according to their maximum:
incPairs :: [(Int,Int)]
incPairs = mergeWith compare2 (,) [1..] [1..]
Its first 10 elements are:
> take 10 incPairs
[(1,1),(1,2),(2,1),(2,2),(1,3),(2,3),(3,1),(3,2),(3,3),(1,4)]
and when we (for example) look for the first pair whose sum of squares is equal to 65:
find (\(x,y) -> x^2+y^2 == 65) incPairs
we get the correct result (4,7) (as opposed to (1,8) if lexicographic ordering were used).
This answer is for a more general problem for a unknown predicate. If the predicate is known, more efficient solutions are possible, like others have listed solutions based on knowledge that you don't need to iterate for all Ints for a given c.
When dealing with infinite lists, you need to perform breadth-first search for solution. The list comprehension only affords depth-first search, that is why you never arrive at a solution in your original code.
counters 0 xs = [[]]
counters n xs = concat $ foldr f [] gens where
gens = [[x:t | t <- counters (n-1) xs] | x <- xs]
f ys n = cat ys ([]:n)
cat (y:ys) (x:xs) = (y:x): cat ys xs
cat [] xs = xs
cat xs [] = [xs]
main = print $ take 10 $ filter p $ counters 3 [1..] where
p [a,b,c] = a*a + b*b == c*c
counters generates all possible counters for values from the specified range of digits, including a infinite range.
First, we obtain a list of generators of valid combinations of counters - for each permitted digit, combine it with all permitted combinations for counters of smaller size. This may result in a generator that produces a infinite number of combinations. So, we need to borrow from each generator evenly.
So gens is a list of generators. Think of this as a list of all counters starting with one digit: gens !! 0 is a list of all counters starting with 1, gens !! 1 is a list of all counters starting with 2, etc.
In order to borrow from each generator evenly, we could transpose the list of generators - that way we would get a list of first elements of the generators, followed by a list of second elements of the generators, etc.
Since the list of generators may be infinite, we cannot afford to transpose the list of generators, because we may never get to look at the second element of any generator (for a infinite number of digits we'd have a infinite number of generators). So, we enumerate the elements from the generators "diagonally" - take first element from the first generator; then take the second element from the first generator and the first from the second generator; then take the third element from the first generator, the second from the second, and the first element from the third generator, etc. This can be done by folding the list of generators with a function f, which zips together two lists - one list is the generator, the other is the already-zipped generators -, the beginning of one of them being offset by one step by adding []: to the head. This is almost zipWith (:) ys ([]:n) - the difference is that if n or ys is shorter than the other one, we don't drop the remainder of the other list. Note that folding with zipWith (:) ys n would be a transpose.
For this answer I will take "smallest" to refer to the sum of the numbers in the tuple.
To list all possible pairs in order, you can first list all of the pairs with a sum of 2, then all pairs with a sum of 3 and so on. In code
pairsWithSum n = [(i, n-i) | i <- [1..n-1]]
xs = concatMap pairsWithSum [2..]
Haskell doesn't have facilities for dealing with n-tuples without using Template Haskell, so to generalize this you will have to switch to lists.
ntuplesWithSum 1 s = [[s]]
ntuplesWithSum n s = concatMap (\i -> map (i:) (ntuplesWithSum (n-1) (s-i))) [1..s-n+1]
nums n = concatMap (ntuplesWithSum n) [n..]
Here's another solution, with probably another slightly different idea of "smallest". My order is just "all tuples with max element N come before all tuples with max element N+1". I wrote the versions for pairs and triples:
gen2_step :: Int -> [(Int, Int)]
gen2_step s = [(x, y) | x <- [1..s], y <- [1..s], (x == s || y == s)]
gen2 :: Int -> [(Int, Int)]
gen2 n = concatMap gen2_step [1..n]
gen2inf :: [(Int, Int)]
gen2inf = concatMap gen2_step [1..]
gen3_step :: Int -> [(Int, Int, Int)]
gen3_step s = [(x, y, z) | x <- [1..s], y <- [1..s], z <- [1..s], (x == s || y == s || z == s)]
gen3 :: Int -> [(Int, Int, Int)]
gen3 n = concatMap gen3_step [1..n]
gen3inf :: [(Int, Int, Int)]
gen3inf = concatMap gen3_step [1..]
You can't really generalize it to N-tuples, though as long as you stay homogeneous, you may be able to generalize it if you use arrays. But I don't want to tie my brain into that knot.
I think this is the simplest solution if "smallest" is defined as x+y+z because after you find your first solution in the space of Integral valued pythagorean triangles, your next solutions from the infinite list are bigger.
take 1 [(x,y,z) | y <- [1..], x <- [1..y], z <- [1..x], z*z + x*x == y*y]
-> [(4,5,3)]
It has the nice property that it returns each symmetrically unique solution only once. x and z are also infinite, because y is infinite.
This does not work, because the sequence for x never finishes, and thus you never get a value for y, not to mention z. The rightmost generator is the innermost loop.
take 1 [(z,y,x)|z <- [1..],y <- [1..],x <- [1..],x*x + y*y == z*z]
Sry, it's quite a while since I did haskell, so I'm going to describe it with words.
As I pointed out in my comment. It is not possible to find the smallest anything in an infinite list, since there could always be a smaller one.
What you can do is, have a stream based approach that takes the lists and returns a list with only 'valid' elements, i. e. where the condition is met. Lets call this function triangle
You can then compute the triangle list to some extent with take n (triangle ...) and from this n elements you can find the minium.

Resources