1

私は以前の関数型プログラミングのバックグラウンドなしでf#を学んでいます-進歩し始めていますが、これに固執しています。誰かが99のf#問題の問題9の解決策を理解するのを手伝ってくれませんか?それらはここで見つけることができます:[http://fssnip.net/an] [1]

基本的に、提供されたソリューションでパターンマッチングがどのように機能するかを理解していません。まず、xssとは何ですか?助けを応援します!

問題9:リスト要素の連続した複製をサブリストにパックします。リストに繰り返し要素が含まれている場合は、それらを別々のサブリストに配置する必要があります。

例:

パック['a'; 'a'; 'a'; 'a'; 'b'; 'c'; 'c'; 'a'; 'a'; 'd'; 'e'; 'e'; 'e'; 'e']

val it:char list list = [['a'; 'a'; 'a'; 'a']; ['b']; ['c'; 'c']; ['a'; 'a']; ['d']; ['e'; 'e'; 'e'; 'e']]

サンプルソリューション;

let pack xs = 
    let collect x = function
        | (y::xs)::xss when x = y -> (x::y::xs)::xss
        | xss -> [x]::xss
    List.foldBack collect xs []
4

2 に答える 2

1

(y::xs)::xssリストの(空ではない)リストに一致し、最初のサブリストの先頭と末尾でyあり、外側のリストの末尾です。、2番目のケースでは、リスト全体に一致します(空かどうか)。xsxssxss

foldBack('T -> 'State -> 'State) -> 'T list -> 'State -> 'State)アキュムレータ引数をリストに通し、後ろから前に移動します。

collectは「累積」関数であり、基本的に次のようになります。状態(最初は空のリスト)に少なくとも1つのサブリストが含まれ、これも空ではなく、現在の要素(x)がサブリストの先頭()と一致する場合は、次のようyに追加します。サブリスト。それ以外の場合は、。のみで構成されるx状態()の前に新しいサブリストを追加します。各サブリストは、隣接する等しい要素のグループです。xssx

于 2013-02-13T22:49:01.487 に答える
1

これを理解するには、まずリストがF#でどのように表されるかを理解することが重要です。F#リストは次のいずれかです。

  • []またはとして書かれた空のリスト
  • 値(ヘッド)の後に次のように記述された別のリスト(テール)が続くhead::tail

したがって、たとえば、[ 1; 2; 3 ]実際には1を含むリスト、2を含むリスト(など)、空のリストを作成していることになります。式は次のようにコンパイルされます。

1::(2::(3::[])) 

また、角かっこを省略して、とだけ書くことができます1::2::3::[]

パターンマッチングはまったく同じ構文を使用しますが、方向が逆です。リストを作成する代わりに、それらを分解します。したがって、パターンがある場合はx::xs、最初の要素を取得してそれを変数に割り当てx、残りのリストを変数に割り当てる必要があることを意味しますxs

このパターンは、リストのリスト(x::xs)::xssで機能するため、少し注意が必要です。これは、一致するリストの先頭もリストであることを意味します。次のより単純なバージョンにコードを書き直すことができます。

let pack xs = 
    let collect x = function
        | head::xss ->    // Decompose into first element (head) and the rest (tail)
          match head with
          | y::xs when x = y -> (x::y::xs)::xss
          | _ -> [x]::xss
        | xss -> [x]::xss
    List.foldBack collect xs []

これでコードに重複がありますが、collectテイクと別のパラメーターが(ヘッド/テールを取得するために)xその別のパラメーターと一致し、さらにを分解していることがわかります。head::xsshead

于 2013-02-13T22:58:50.583 に答える