似乎可以在这里增加混乱的一件事是自由使用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 需要 astep :: a -> b -> b
和 a start :: b
。由于我们希望最终结果是 a [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
。那么什么是阶跃函数呢?从类型中,我们知道它必须采用 aNumber
和 a[Pair]
并产生 a [Pair]
。但是这些输入是什么意思?那么Number
输入将是list2
. [Pair]
输入将是“到目前为止折叠的结果” 。所以我们要使用我们的Number
, 并做一些事情来为它创建Pair
s ,然后将它们添加到迄今为止的结果上。这就是我的代码开始与你的不同的地方。
step a b = append (doSomething a) b
doSomething :: Number -> [Pair]
doSomething a = undefined
由于您使用 Racket 可能会定义doSomething
为匿名函数,这意味着list1
在范围内。(因为它在 Haskell 函数的 where 子句中,所以它在作用域内)。您可能会使用该列表来生成组合。
doSomething a = ... a ... list1 ...
实现doSomething
留给读者作为练习,翻译回 Racket 也是如此。请注意,我在这里定义的 Haskell 函数的类型签名combiner
,可以推广到[a] -> [b] -> [(a,b)]
.