-- File: Helpers.hs
-- Date: 15-Nov-2008
-- Version: 1.0
--
-- Copyright (C) 2008 Jan Gosmann <jan@hyper-world.de>
--
-- See: http://www.hyper-world.de
--
-- Description: This file provides a data structure to represent arithmetic
--              expressions.

module Helpers where

--------------------------------------------------------------------------------
-- Permutations
--------------------------------------------------------------------------------

-- This function is used to generate permutations and returns all permutations
-- of a given list.
-- Arguments:
--   - The first argument is only used internally and should be set to [] in the
--     first call. In this argument the function builds up a single permutation
--     during recursive calls.
--   - The second arguemtn is also only used internally and should be set to []
--     in the first call. During the iteration over the elements of the list
--     the function will store the already used elements in this argument.
--   - The list of which all permutations should be build.
perm :: [a] -> [a] -> [a] -> [[a]]
perm current [] [] = [current]  -- All elements were chosen, return the final
                                -- permutation.
perm current part1 [] = []      -- We iterated over all elements once.
perm current part1 (chosen:part2) =
  (perm (chosen:current) [] (part1 ++ part2))
  ++ (perm current (chosen:part1) part2)  

-- This is a wrapper function for perm. It returns all permutations for a given
-- list.
-- Arguments:
--   - List of which the permutations should be returned.
permutations :: [a] -> [[a]]
permutations a = map reverse (perm [] [] a)

--------------------------------------------------------------------------------
-- More list functions
--------------------------------------------------------------------------------

-- Returns true if an element can be found in a list, otherwise false.
-- Arguments:
--   - Element to find.
--   - List to search in.
contains :: Eq a => a -> [a] -> Bool
contains a []     = False
contains a (x:xs) = if a == x then True else contains a xs

-- Removes every element which occurs more than once. As example for [3,5,3,7,5]
-- this function would return [3,5,7].
-- Arguments:
--   - List to process.
remdups :: Eq a => [a] -> [a]
remdups []     = []
remdups (x:xs) = if contains x xs then remdups xs else x : remdups xs

--------------------------------------------------------------------------------
-- Output functions
--------------------------------------------------------------------------------

-- This function prints the elements of a list in single lines.
-- Arguments:
--   - List to print.
printLongList :: Show a => [a] -> IO()
printLongList (a:[]) = putStr (show a)
printLongList (a:list) = do (putStrLn (show a))
                            (printLongList list)

