Partition a set in Haskell - haskell

I'm trying to write a Haskell program that could return the partition set of a user defined set. The partition of a set S is defined as a set of nonempty, pairwise disjoint subsets of S whose union is S. So, [1,2,3] returns [[[2],[3,1]],[[2,1],[3]],[[3,2,1]],[[1],[3,2]],[[1],[2],[3]]]. I think I can utilize a different program I wrote a while ago that finds the cartesian product from two sets. So, [1,2,3] ['a', 'b'] returns [(1,'a'),(1,'b'),(2,'a'),(2,'b'),(3,'a'),(3,'b')]. However, I'm not sure quite how. I think it would require recursion though, if this can even be adapted properly. Here is the subset code:
type Set a = [a]
isElement :: Eq a => a -> [a] -> Bool
isElement x [] = False
isElement x (y:ys) = if(x==y) then True else isElement x ys
subset :: Eq a => Set a -> Set a -> Bool
subset [] xs = True
subset (y:ys) xs = if(isElement y xs == True)
then do subset ys xs
else do False

The idea is that in order to find all partitions of set X ∪ {x}, we find parritions of X first. Then add x to each of them in every possible way (that is, add x to the first element of a partition, add x to the second element etc) and take a union of the result.
Here's a rather straightforward implementation:
partitions :: [a] -> [[[a]]]
partitions [] = [[]]
partitions (x:xs) = expand x $ partitions xs where
expand :: a -> [[[a]]] -> [[[a]]]
expand x ys = concatMap (extend x) ys
extend :: a -> [[a]] -> [[[a]]]
extend x [] = [[[x]]]
extend x (y:ys) = ((x:y):ys) : map (y:) (extend x ys)
Demo:
https://ideone.com/ClYOoQ

Pseudocode for one recursive algorithm:
If |S| = 1
Return ∅
Otherwise
For each nonempty proper subset X ⊂ S
Let Y = S - X
Add {X, Y} to R
For each Z in {partitionSet(X)}
Add Z ∪ {Y} to R.
Return R
Since “adding” elements to a list isn’t a very functional idiom, you would want to do those steps with a concatMap or a list comprehension. You might also build R as an accumulating parameter to a tail-recursive function, or as a union of the return values of each step. The proper subsets function is in the Haskell standard library as Data.List.subsequences.
If you have a total ordering on all proper subsets of S, you can use symmetry-breaking to add only partitions that are unique up to permutation. That is, if X > Y, you could add only {X,Y} and not {Y,X}, and only {X,Y,Z} and not {Y,X,Z}. Be careful that you still sub-partition every set in your partition exactly once!
This finds only partition sets of S, if ⋃Z = X and X ∪ Y = S, the union of all sets in Z and Y is S, it returns only sets of nonempty proper subsets of S, and every partition and subpartition is a set difference, hence pairwise disjoint.
Any partition set of cardinality two has the form {X, S-X}, and the algorithm finds it because it tries every possible X. Any partition set of cardinality i>2 has the form {a_1, a_2, ..., a_i}, where {a_1, a_2} is a partition set of {a_1 ⋃ a_2} and {{a_1 ⋃ a_2}, ..., a_i} is a partition set of cardinality i-1, and will be found when subpartitioning the parent node of the search tree. Therefore, by induction, the algorithm finds all partition sets of S.

Lately, I was playing again with set partitions and haskell. Even though it might be not the fastest and nicest solution it does the job. I found out that using Data.List and the List Monad greatly reduces the amount of code and extents the readability.
Asking myself if there is a neat way to replace foldl by foldr?
Anyway, here is my solution:
module Main where
import Data.List
main :: IO ()
main = print $ allPart 5
insertFront :: Integer -> [[Integer]] -> [[Integer]]
insertFront k (h:t) = [k:h]++t
insertFront k _ = [[k]]
add :: Integer -> [[Integer]] -> [[[Integer]]]
add k part=zipWith (++) (inits part) (map (insertFront k) (tails part))
allPart k = foldl (>>=) [[]] [add i | i<-[1..k]]
I'm also wondering if there is some very short substitute for insertFront using some of the haskell libraries.

Related

Haskell delete largest number from a list

I am trying to figure out how to create a recursive function that will find the largest element in the list and delete it then return the list. This is what i have so far but the problem is that every time i run it it returns the list without any of the values that are assigned to x.
deleteMax :: (Ord a) => [a] -> [a]
deleteMax [] = []
deleteMax [x] = []
deleteMax (x:y:xs)
|x == y = y: deleteMax xs
|x >= y = y: deleteMax xs
|x < y = x: deleteMax xs
This is not your answer
So you are a beginner and as such would like the simple solution of "how do I find the largest element in a list" followed by "how do I remove (one of the) largest element(s) in the list". This isn't that answer but it is me avoiding a long comment while also giving you something to come back to in 3 months.
The Lazy Way
One solution, which #n.m. and I were sparring about in comments, is to tie the knot (Googleable term). In this method you only need one logical pass over the list. In this case it is basically a trick to hide the pass that constructs the result list.
The idea is that during your pass over the list you do both tasks of 1. Compute the maximum element and 2. Compare with the maximum element and construct the list. There is nothing here that requires a monad but it can be easiest to see as part of a state monad:
deleteMaxState :: (Ord a) => [a] -> [a]
deleteMaxState [] = []
First we handle the base cases so we have a candidate 'maximum' (x) for our recursive operation.
deleteMaxState xs#(fstElem:_) =
let (r,(m,_)) = runState (go xs) (fstElem, notMax m)
notMax mx v = if (mx > v) then (v:) else id
go [] = return []
go (x:xs) =
do (curr,f) <- get
when (x > curr) (put (x,f))
f x <$> go xs
in r
In the loopwe track two values the first, curr, is the largest observed value by this point in our traversal of the list. The second value, f, is the trick - it is (a function including) the maximum value provided to the computation after the traversal has completed.
The magic is all here:
(r,(m,_)) = runState (go xs) (fstElem, m)
The left element of the result state (m,_) was our running maximum. Once the traversal ends we use that value - it becomes the right element (fstElem, m) and thus represents the maximum of the whole list.
We can use f to create thunks that populate portions of the list or just in-line construct our list as a bunch of unevaluated cons computations.
Making this one iota simpler, we can remove the higher-order function f and just have a number (untested):
deleteMaxState xs#(fstElem:_) =
let (r,(m,_)) = runState (go xs) (fstElem, m)
go [] = return []
go (x:xs) =
do (curr,theMax) <- get
when (x > curr) (put (x,theMax))
((if x >= theMax then Nothing else Just x) :) <$> go xs
in catMaybes r
Now we can see the second pass pretty explicitly not just as an unevaluated set of "some computation involving max, consed on the result" but as an actual pass via catMaybes.
The tying of the knot allows the programmer to write one logical traversal. This can be nice since it requires only one pattern match and recursive call per constructor of the list elements but at the cost of reasoning about evaluation order.

Divide and conquer: Merge sort

I'm fairly new to Haskell and don't understand the following divide and conquer construct:
{- trivial solve split combine input/output-}
dc :: (a -> Bool) -> (a -> b) -> (a -> [a]) -> ([b] -> b) -> a -> b
dc trivial solve split combine = x
where
x y = if trivial y then solve y
else (\_ z -> combine z) y (map x (split y))
Now I need to implement a merge-sort function based on this construct. I tried to implement some functions but I'm pretty sure that's not how it should work:
trivial :: (Ord a, Num a) => [a] -> Bool
trivial [] = True
trivial (x:[]) = True
trivial (x:x':xs) = if x<=x' then trivial (x':xs) else False
split :: [a] -> [[a]]
split (x:[]) = [[x]]
split (x:xs) = [x] : split xs
combine :: [[a]] -> [a]
combine [[]] = []
combine ([]:ys) = combine ys
combine ((x:xs):ys) = x : combine (xs:ys)
So how does the construct above work ? What does "x" and "y" stand for ? What should "trivial" and "solve" (and split/combine) do ?
So, the signature of dc can be read as "this function takes 4 arguments and returns a function from a to b". In the definition, this function is called x. x is defined in the where clause, as:
x y = if trivial y then solve y
else (\_ z -> combine z) y (map x (split y))
You could add a type signature for x:
x :: a -> b
The definition of x (which is the function that performs your actual divide and conquer computation) is somewhat obfuscated, but can be read as:
If x is a trivial case, just solve it
Otherwise, split it, divide-and-conquer it (with x), then combine the result.
Note: It could be written a bit more clearly as:
x y = if trivial y then solve y
else (combine . map x . split) y
This function does all the recursivity you need, so your functions don't need to care about that. Your functions should be:
trivial: True if the problem can be solved with solve in this case. For the merge sort, the trivial case is the list that contains only one item.
solve: solves the trivial case. For the merge sort, it's just the identity (since it's just a one item list).
split: split the big problem into smaller problems (which will be done many times, until they are trivial. For the merge sort, it's just about splitting the list in half.
combine: takes a list of stuff that were previously splitted, and combine them. For the merge sort, that's where the merging magic happens :)
Note: the merge sort algorithm can be a bit different from what I mentioned. For example, a sorted list can also be a trivial case.

Linking in tree structures

Upon working with long strings now, I came across a rather big problem in creating suffix trees in Haskell.
Some constructing algorithms (as this version of Ukkonen's algorithm) require establishing links between nodes. These links "point" on a node in the tree. In imperative languages, such as Java, C#, etc. this is no problem because of reference types.
Are there ways of emulating this behaviour in Haskell? Or is there a completely different alternative?
You can use a value that isn't determined until the result of a computation in the construction of data in the computation by tying a recursive knot.
The following computation builds a list of values that each hold the total number of items in the list even though the total is computed by the same function that's building the list. The let binding in zipCount passes one of the results of zipWithAndCount as the first argument to zipWithAndCount.
zipCount :: [a] -> [(a, Int)]
zipCount xs =
let (count, zipped) = zipWithAndCount count xs
in zipped
zipWithAndCount :: Num n => b -> [a] -> (n, [(a, b)])
zipWithAndCount y [] = (0, [])
zipWithAndCount y (x:xs) =
let (count', zipped') = zipWithAndCount y xs
in (count' + 1, (x, y):zipped')
Running this example makes a list where each item holds the count of the total items in the list
> zipCount ['a'..'e']
[('a',5),('b',5),('c',5),('d',5),('e',5)]
This idea can be applied to Ukkonen's algorithm by passing in the #s that aren't known until the entire result is known.
The general idea of recursively passing a result into a function is called a least fixed point, and is implemented in Data.Function by
fix :: (a -> a) -> a
fix f = let x = f x in x
We can write zipCount in points-free style in terms of zipWithAndCount and fix.
import Data.Function
zipCount :: [a] -> [(a, Int)]
zipCount = snd . fix . (. fst) . flip zipWithAndCount

How do you efficiently find a union of a list of lists of values in haskell?

Since a code example is worth a thousand words I'll start with that:
testList = [1,2,2,3,4,5]
testSet = map sumMapper $ tails testList
where sumMapper [] = []
sumMapper (a:b) = sumMap a b
sumMap a b = map (+ a) b
This code takes a list and adds up all the elements to get the sum of all of them (I'd also be interested in efficiency of this). The output of testSet is:
[[3,3,4,5,6],[4,5,6,7],[5,6,7],[7,8],[9],[],[]]
I would like to find the union of these lists (to make it into a set) but I feel that:
whatIWant = foldl1 union testSet
will have bad performance (the real lists will be thousands of elements long).
Is this the correct solution or am I missing something obvious?
You might want to try
nub $ concat theListOfLists
In the version using union, the code to cut out duplicates will get run many times. Here it only is run once.
It will only execute the code to pull out the unique values once.
There is also a Data.Set library, you could alternatively use
import Data.Set
S.fromList $ concat theListOfLists
The important point is that the code (here and above) that pulls out duplicates only gets run on the full list once, rather than over and over again.
edit- Rein mentions below that nub is O(n^2), so you should avoid the first solution above in favor of something O(n log n), as Data.Set.fromList should be. As others have mentioned in the comments, you need something that enforces Ord a to get the proper complexity O(n log n), and Data.Set does, nub does not.
I will leave the two solutions (poor performance and good performance) because I think the resulting discussion was useful.
If you're using elements that are members of the Ord typeclass, as in your example, you can use Data.Set:
import qualified Data.Set as Set
whatYouWant = foldl' (Set.union . Set.fromList) Set.empty testSet
This has the advantage of taking space proportional to the size of the largest sublist rather than to the size of the entire concatenated list as does the Set.fromList . concat solution. The strict foldl' also prevents buildup of unevaluated thunks, preventing O(n) stack and heap space usage.
Generally speaking, an Ord constraint allows more efficient algorithms than an Eq constraint because it allows you to build a tree. This is also the reason that nub is O(n^2): the more efficient algorithm requires Ord rather than just Eq.
Since union is an associative operation (a+(b+c)==(a+b)+c), you can use tree-shaped folding for a logarithmic advantage in time complexity:
_U [] = []
_U (xs:t) = union xs (_U (pairs t))
pairs (xs:ys:t) = union xs ys : pairs t
pairs t = t
Of course Data.List.union itself is O(n2) in general, but if your testList is ordered non-decreasing, all the lists will be too, and you can use a linear ordUnion instead of the union, for a solution which is linearithmic overall and shouldn't leak space:
ordUnion :: (Ord a) => [a] -> [a] -> [a]
ordUnion a [] = a
ordUnion [] b = b
ordUnion (x:xs) (y:ys) = case compare x y of
LT -> x : ordUnion xs (y:ys)
EQ -> x : ordUnion xs ys
GT -> y : ordUnion (x:xs) ys
To prevent duplicates which might slip through, one more function is needed to process _U's output—a linear ordNub :: (Ord a) => [a] -> [a], with an obvious implementation.
Using the left-preferential (\(x:xs) ys -> x:ordUnion xs ys) could be even more productive overall (force smaller portions of the input at each given moment):
g testList = ordNub . _U $ [map (+ a) b | (a:b) <- tails testList]
where
_U [] = []
_U ((x:xs):t) = x : ordUnion xs (_U (pairs t))
pairs ((x:xs):ys:t) = (x : ordUnion xs ys) : pairs t
pairs t = t
see also:
data-ordlist package
even less forcing "implicit heap" by apfelmus
Tree-like folds

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