Вот мой совет:
- Просто реализуйте свой алгоритм в
самый простой возможный способ.
- Профиль.
- Оптимизация для скорости или использования памяти при необходимости.
Я очень быстро понял, что я недостаточно умен и / или не достаточно опытен, чтобы рассуждать о том, что будет делать GHC или как будет работать сборщик мусора. Иногда вещи, которые, я уверен, будут катастрофически неэффективными при работе с памятью, с первого раза и, реже, вещи, которые кажутся простыми, требуют много возражений с аннотациями строгости и т. Д.
Глава Real World Haskell по профилированию и оптимизации невероятно полезна, когда вы перейдете к шагам 2 и 3.
Например, вот очень простая реализация IDDFS, где f
расширяет дочерние элементы, p
- предикат поиска, а x
- отправная точка.
search :: (a -> [a]) -> (a -> Bool) -> a -> Bool
search f p x = any (\d -> searchTo f p d x) [1..]
where
searchTo f p d x
| d == 0 = False
| p x = True
| otherwise = any (searchTo f p $ d - 1) (f x)
Я проверил поиск "abbaaaaaacccaaaaabbaaccc"
с children x = [x ++ "a", x ++ "bb", x ++ "ccc"]
как f
. Это кажется достаточно быстрым и требует очень мало памяти (я думаю, линейно с глубиной). Почему бы сначала не попробовать что-то подобное, а затем перейти к более сложной структуре данных, если она недостаточно хороша?