Задний план:
Я делаю проект перевода кода, который требует от меня создания имен переменных. Ни одно из имен, которые я генерирую, не должно дублировать друг друга.
Я действительно расстроен, так как это было бы глупо просто и элегантно с функцией генератора Python.
Что я пробовал:
То, как я делал это раньше, заключалось в том, чтобы передавать переменную счетчика вниз через рекурсивные вызовы моего кода перевода и передавать (возможно, увеличенный) счетчик обратно в возвращаемое значение практически каждой функции.
Это было действительно запутанно: к каждой из этих функций добавлялся дополнительный параметр для отслеживания; и что еще хуже, это заставило меня работать с беспорядочными возвращаемыми значениями кортежа, где в противном случае у меня было бы простое унарное возвращаемое значение.
За короткое время работы с Haskell я так и не освоился с монадами, но у меня было подозрение, что я могу использовать оболочку для монады State
для имитации глобальной переменной-счетчика. После 3 дней безделья, пытаясь найти монады и создать свою собственную, а затем пытаясь изменить чужие монады, чтобы сгенерировать нужные мне значения, я, наконец, смирился с прямым использованием чужой высокоуровневой монады (возможно, с небольшими изменениями.)
Моя проблема сейчас:
Я определил MonadSupply и MonadUnique в виде пары модулей, которые, вероятно, обеспечивают простой интерфейс, который мне нужен. К сожалению, я не могу понять, как их использовать.
В частности, в документации по модулю MonadSupply
есть хороший пример использования:
runSupplyVars x = runSupply x vars
where vars = [replicate k ['a'..'z'] | k <- [1..]] >>= sequence
Похоже на то, что я хочу! Как только я получил модуль для компиляции, я проверил тип этой функции в интерпретаторе:
> :t runSupplyVars
runSupplyVars :: Supply [Char] a -> Identity (a, [[Char]])
Я пытался передать этой функции много (на несколько часов) разных вещей, но безуспешно. Я также попытался передать функцию некоторым другим функциям, чтобы посмотреть, неявно ли они предоставят нужные мне параметры. Пока не повезло.
Вопросы:
Может ли кто-нибудь привести пример использования этой функции runSupplyVars
?
Можно ли сделать с ним то, о чем я думаю? Я хочу иметь функцию, которую я могу вызывать из любого места в программе, которая будет предоставлять мне другое имя переменной или целое число при каждом вызове.