ここで混乱を招く可能性があるのは、の自由な使用ですlist
。タイプにHaskell表記を使用して問題に取り組み始めます。::
「タイプあり」を[Foo]
意味し、「Fooのリスト」を意味します。
list1 :: [Symbol]
list2 :: [Number]
type Pair = (Symbol, Number)
(combiner list1 list2) :: [Pair]
foldr
これで、オーバーリスト2を使用してこの問題に取り組みたいようです。
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
タイプから、aとaを取り、[Pair]
を生成する必要があることがわかり[Pair]
ます。しかし、これらの入力はどういう意味ですか?さて、Number
入力はのいくつかの要素になりlist2
ます。そして、[Pair]
入力は「これまでのフォールドの結果」になります。だから、私たちは私たちを取り、Number
それのためにsを作成するために何かPair
をして、それからこれまでの結果にそれらを叩きつけたいと思うでしょう。これは、私のコードがあなたのコードと異なり始めるポイントです。
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)]
。