Кажется, что одна вещь, которая может добавить здесь путаницу, это либеральное использование list
. Я собираюсь начать подходить к вашей проблеме, используя нотацию Haskell для типов. ::
означает «имеет тип», а [Foo]
означает «список Foo».
list1 :: [Symbol]
list2 :: [Number]
type Pair = (Symbol, Number)
(combiner list1 list2) :: [Pair]
Теперь похоже, что вы хотите решить эту проблему с помощью foldr
over list2.
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr требует step :: a -> b -> b
и start :: b
. Поскольку мы хотим, чтобы конечный результат был [Pair]
, это означает, что b = [Pair]
. start
, вероятно, будет пустым списком. Поскольку list2 заполняет слот [a]
, это означает, что a = Number
. Поэтому для нашей задачи step :: Number -> [Pair] -> [Pair]
combiner :: [Symbol] -> [Number] -> [Pair]
combiner list1 list2 = foldr step start list2
where step :: Number -> [Pair] -> [Pair]
step a b = undefined
start = []
Пока это то же самое, что и foldr
, который вы написали, за исключением того, что я еще не определил step
. Так, какова функция шага? От типа мы знаем, что оно должно взять Number
и [Pair]
и произвести [Pair]
. Но что означают эти данные? Ну, вход Number
будет некоторым элементом list2
. И вход [Pair]
будет «результатом сгиба». Итак, мы хотим взять наши Number
и сделать что-то , чтобы создать для него Pair
, а затем наложить их на результат. Это Точка, в которой мой код начинает отличаться от вашего.
step a b = append (doSomething a) b
doSomething :: Number -> [Pair]
doSomething a = undefined
Поскольку вы, используя Racket, вероятно, определите doSomething
как анонимную функцию, это означает, что list1
находится в области видимости. (Так как он находится в предложении where функции в Haskell, он находится в области видимости). Вы, вероятно, будете использовать этот список для генерации комбинаций.
doSomething a = ... a ... list1 ...
Реализация doSomething
оставлена как упражнение для читателя, так же как и перевод обратно в Racket. Обратите внимание, что сигнатура типа для функции Haskell, которую я здесь определяю, combiner
, может быть обобщена до [a] -> [b] -> [(a,b)]
.