いくつかのコードがあるとします:
let listB = [ 1; 2; 3 ]
Lisp 記法を使用して、このリストに対してcar
andを実行するにはどうすればよいですか? cadr
短所は知ってい::
ます。
またはスキームで、first
そしてrest
?
いくつかのコードがあるとします:
let listB = [ 1; 2; 3 ]
Lisp 記法を使用して、このリストに対してcar
andを実行するにはどうすればよいですか? cadr
短所は知ってい::
ます。
またはスキームで、first
そしてrest
?
List.hd と List.tl は必要なことを行いますが、F# では、通常、リストはパターン マッチングを使用して分解されます。たとえば、次の関数では、 x は関数に渡されるリストの先頭に一致し、 xs は末尾に一致します。
let list = [1;2;3]
let rec f = function
| [] -> 1
| (x::xs) -> x * (f xs)
f list;
List.head : 空でないリスト(リストの先頭)の最初の要素を返します。
List.tail : 最初の(リストの末尾または残り)を除く、空でないリストのすべての要素を返します。
例 ( F# インタラクティブ コンソールを使用):
> let sample = [1;2;3;4];;
val sample : int list
> List.head sample;;
val it : int = 1
> List.tail sample;;
val it : int list = [2; 3; 4]
私はsimonukに同意する必要があります。CMS が述べたように、hd
とtl
は正しい機能ですが、それ以上の議論があります。
パターン マッチングを使用すると、コンパイラの機能を利用して、見逃した可能性のある (基本) ケース (リストが空の場合など) をキャッチできます。その例外を確実にキャッチまたはスローし続けることはできますが、そうする必要はなく、その期待が頻繁に発生しない場合はバグが発生する可能性があります。そのため、パターン マッチングを活用する習慣を身につけることが、プログラミングの良い実践になります。すべての意図と目的のために、hd
/を呼び出すときに適用される実際の関数tl
はパターンに一致します。実際、ocaml では失敗です。
let hd = function [] -> failwith "hd" | a::l -> a
let tl = function [] -> failwith "tl" | a::l -> l
例として、例外/失敗を使用する代わりに、以下を使用する方が満足できる場合がありますoptions
。
> let car = function | hd::tl -> Some hd | _ -> None
> let cdr = function | hd::[] -> None | hd :: tl -> Some tl | _ -> None
また、何にでも合わせて使うのは慎重に_
。別のタイプを追加することを決定した場合、バリアント タイプではさらに問題が発生します... おっと!