Q:

Retrieve strings from Matrix

I'm stuck with my homework task, somebody help, please..
Here is the task:
Find all possible partitions of string into words of some dictionary
And here is how I'm trying to do it:
I use dynamical programming concept to fill matrix and then I'm stuck with how to retrieve data from it
-- Task5_2
retrieve :: [[Int]] -> [String] -> Int -> Int -> Int -> [[String]]
retrieve matrix dict i j size
    | i >= size || j >= size = []
    | index /= 0 = [(dict !! index)]:(retrieve matrix dict (i + sizeOfWord) (i + sizeOfWord) size) ++ retrieve matrix dict i (next matrix i j) size
    where index = (matrix !! i !! j) - 1; sizeOfWord = length (dict !! index)

next matrix i j
    | j >= (length matrix) = j
    | matrix !! i !! j > 0 = j
    | otherwise = next matrix i (j + 1)

getPartitionMatrix :: String -> [String] -> [[Int]]
getPartitionMatrix text dict = [[ indiceOfWord (getWord text i j) dict 1  | j <- [1..(length text)]] | i <- [1..(length text)]]

--------------------------
getWord :: String -> Int -> Int -> String
getWord text from to = map fst $ filter (\a -> (snd a) >= from && (snd a) <= to) $ zip text [1..]

indiceOfWord :: String -> [String] -> Int -> Int
indiceOfWord _ [] _ = 0
indiceOfWord word (x:xs) n
    | word == x  = n
    | otherwise = indiceOfWord word xs (n + 1)

-- TESTS
dictionary = ["la", "a", "laa", "l"]
string = "laa"
matr = getPartitionMatrix string dictionary
test = retrieve matr dictionary 0 0 (length string)

A:

Here is a code that do what you ask for. It doesn't work exactly like your solution but should work as fast if (and only if) both our dictionary lookup were improved to use tries as would be reasonable. As it is I think it may be a bit faster than your solution :
module Partitions (partitions) where
import Data.Array
import Data.List

data Branches a = Empty | B [([a],Branches a)] deriving (Show)

isEmpty Empty = True
isEmpty _     = False

flatten :: Branches a -> [ [ [a] ] ]
flatten Empty  = []
flatten (B []) = [[]]
flatten (B ps) = concatMap (\(word, bs) -> ...) ps

type Dictionary a = [[a]]

partitions :: (Ord a) => Dictionary a -> [a] -> [ [ [a] ] ]
partitions dict xs = flatten (parts ! 0)
    where 
      parts = listArray (0,length xs) $ zipWith (\i ys -> starting i ys) [0..] (tails xs)
      starting _ [] = B []
      starting i ys 
          | null words = ...
          | otherwise  = ...
          where 
            words = filter (`isPrefixOf` ys) $ dict
            go word = (word, parts ! (i + length word))

It works like this : At each position of the string, it search all possible words starting from there in the dictionary and evaluates to a Branches, that is either a dead-end (Empty) or a list of pairs of a word and all possible continuations after it, discarding those words that can't be continued.
Dynamic programming enter the picture to record every possibilities starting from a given index in a lazy array. Note that the knot is tied : we compute parts by using starting, which uses parts to lookup which continuations are possible from a given index. This only works because we only lookup indices after the one starting is computing and starting don't use parts for the last index.
To retrieve the list of partitions from this Branches datatype is analogous to the listing of all path in a tree.
EDIT : I removed some crucial parts of the solution in order to let the questioner search for himself. Though that shouldn't be too hard to complete with some thinking. I'll probably put them back with a somewhat cleaned up version later.

