指定したスケルトンでは、pipe
引数を 1 つだけ取ります。pipe() の型から、この引数には typeがあり、 type の値を返すことになっていることが('a -> 'a) list -> 'a list
わかります。('a -> 'a) list
('a -> 'a)
の型List.fold_left
は の形式になり('b -> 'c -> 'b) -> 'b -> 'c list -> 'b
ました。しかし、あなたはそれを知っています:
type の値を返す必要がある'a -> 'a
ため、ここ'b
でインスタンス化されます('a -> 'a)
3 番目の引数の型('a -> 'a) list
は であるため、ここに配置'c list
さ('a -> 'a) list
れます。再び'c
でインスタンス化され('a -> 'a)
ます。
特殊なタイプで使用すると結論付けることができますList.fold_left
(はい、一口です)。
(('a -> 'a) -> ('a -> 'a) -> ('a -> 'a)) -> ('a -> 'a) -> ('a -> 'a) list -> ('a -> 'a)
簡単に言うと、パイプが関数を返さなければならず、関数のリストを取る場合、それbase
自体が関数であるf
必要があり、2 つの関数を取り、関数を返さなければなりません。
どの関数にする必要base
がありますか? が空のリストのbase
場合は が返されるため、 に期待される動作が必要です。fs
base
pipe []
両方のタイプのとの 2 つの関数をどのようf a x
に組み合わせて、単一の関数を返す必要がありますか? ここで答えを出させてもらいます。しかし、次の等式を保持したいという直感は次のとおりです。a
x
'a -> 'a
'a -> 'a
f (パイプ [f1; f2]) f3 = パイプ [f1; f2; f3]
(これは だけでなく、どのリストにも当てはまります[f1; f2]
が、この例で十分です)。と の意味の関係を理解するpipe [f1; f2]
とpipe [f1; f2; f3]
、結合関数 を定義できるようになりますf
。
次の別のスケルトンから始めて、非常にpipe
異なる方法で関数を記述できたことに注意してください。
let pipe fs x =
let f a x = failwith "to be implemented" in
let base = failwith "to be implemented" in
List.fold_left f base fs
この場合、は typeとpipe
type の 2 つの引数を取り、返される値全体は型(関数ではなく値) である必要があります。は関数 ( ) と値 ( ) を受け取り、値を返します。これは単なる値です (どちらを選択できますか?)。('a -> 'a) list
'a
'a
f
'a -> 'a
'a
base
この 2 番目のアプローチは少し抽象度が低いので少し簡単だと思いますが、教師が最初のスケルトンを使用するように頼んだ場合、関数の操作と、関数を構築する関数の構築について教えてくれるからでしょう。