[Haskell-beginners] Finite self-referential list hangs.

Dean Herington heringtonlacey at mindspring.com
Sat Mar 17 20:18:38 CET 2012


At 5:32 PM +0000 3/17/12, tcollin371 wrote:
>I am trying to generate a search tree for a logic puzzle using a 
>list that generates itself by using earlier states to derive later 
>states.  The search tree is finite, but when it reaches the end, it 
>hangs and while the list doesn't grow, it doesn't finish.
>
>I've boiled the problem down to a much simpler list as follows:
>
>tryThis :: [Int]
>tryThis = 3 : [ x | x <- tryThis' tryThis]
>   where
>     tryThis' :: [Int] -> [Int]
>     tryThis' [] = []
>     tryThis' (x : xs) = result' x ++ tryThis' xs
>       where
>         result' :: Int -> [Int]
>         result' 3 = [2, 2, 2]
>         result' 2 = [1, 1]
>         result' 1 = [0]
>         result' 0 = []
>
>When I load this into GHCi and type tryThis, it prints a list of all 
>of the numbers I would expect, then hangs.  Does the self-generating 
>technique not work with finite lists?  Shouldn't tryThis' just 
>generate a final empty list that would terminate this?  How can this 
>be written to successfully terminate?

As you observed, tryThis' doesn't know to terminate because its xs 
never becomes [], even at (what you know is) the end.  You need to 
program a termination check that doesn't need to look into the 
future.  Here's one way (probably not the best):

tryThis2 :: [Int]
tryThis2 = 3 : [ x | x <- tryThis' 1 0 tryThis2]
   where
     tryThis' :: Int -> Int -> [Int] -> [Int]
     tryThis' n m _ | m == n = []
     tryThis' n m (x : xs) = let gen = result' x in gen ++ tryThis' (n 
+ length gen) (m + 1) xs
       where
         result' :: Int -> [Int]
         result' 3 = [2, 2, 2]
         result' 2 = [1, 1]
         result' 1 = [0]
         result' 0 = []



More information about the Beginners mailing list