MyList実装 mapとfilterそしてfold F#
dojo/fsharp/MyList/Program.fs at main · tk3/dojo
今日はmapとfilterそしてfoldを実装した。 foldができたということで、これまで実装したlength、sum、reverseをfoldを使い実装し直した。foldを使うとこれまでのコードが短く書けて、汎用性が高い関数であることが分かった。
例えば、foldを使うことで、次のコードが
let sum list =
let rec loop acc currentList =
match currentList with
| Empty -> acc
| Cons(x, tail) -> loop (acc + x) tail
loop 0 list
次のように書ける。
fold (fun acc x -> acc + x) 0 list5
ただ、実装していて腑に落ちなかったことが一つ。F#の文法についてだ。
コンパイルNGのコード
110 let foldFilter f list =
111 let folded = fold (fun acc x ->
112 if f x then
113 Cons(x, acc)
114 else acc
115 ) Empty list
116
117 reverse folded
エラーメッセージはこちら
Program.fs(115,7): error FS0010: Unexpected identifier in binding. Expected incomplete structured construct at or before this point or other token.
Program.fs(111,5): error FS3118: Incomplete value or function definition. If this is in an expression, the body of the expression must be indented to the same column as the 'let' keyword.
コンパイルOKのコード
110 let foldFilter f list =
111 let folded =
112 fold (fun acc x ->
113 if f x then
114 Cons(x, acc)
115 else acc
116 ) Empty list
117
118 reverse folded
foldの開始位置を調整したコードになってる。エラーメッセージを読めばなんとなく示唆しているのだが、最初理解ができなかった。自分にとっては直感的には理解できず、しっかりとした理解には時間がかかりそうだ。
あと、インデントは単なる見た目ではなくスコープを表しているとのこと。しっかり理解すれば後は慣れかな。