fibs :: [Int]
fibs = 0 : 1 : [ a + b | (a, b) <- zip fibs (tail fibs)]
これにより、フィボナッチ数列が生成されます。
警備員の行動を理解しています :
, zip
そして tail
、でもわからない <-
。ここで何をしているの?
回答:
回答№1の13賛成のおかげで、私はコメントを答えにしました。
あなたが見るものは警備員ではありませんが、 リストの理解。まず第一に、それを表現する方法として考えてくださいA = {x | x要素N}は、次の行に沿ったものを意味します。セットAは、すべての自然数のセットです。リスト内包表記では [x | x <- [1..] ]
.
数値に制約を使用することもできます。 [x | x <- [1..], x `mod` 2 == 0 ]
その他多くのこと。
リストの理解度、さらにはhaskellリソースに関するStackOverflowの質問までカバーする、たくさんの良いhaskell turorialsがあります。
回答№2の10
唯一のトリッキーなことは zip fibs (tail fibs)
. zip
引数ごとにペアごとのリストを作成します。したがって、次のような2つのリストがある場合:
[ 1, 2, 3, 4 ]
[ "a", "b", "c", "d" ]
それらを圧縮すると、次のようになります。
[ (1,"a"), (2,"b"), (3,"c"), (4,"d") ]
左矢印(破壊パターンへの割り当て)は、ペアになった要素を抽出するだけなので、それらを一緒に追加できます。圧縮される2つのリストは次のとおりです。 fibs
そして (tail fibs)
-言い換えれば、フィボナッチ数列1要素のフィボナッチ数列オフセット。 Haskellは遅延評価されるため、多くの要素が必要な場合でもリストを計算できます。これはzipにも当てはまります。
回答№3の場合は3
広げてみましょう。
zip
2つのリストの内容からペアを作成します。だから最初のペア zip fibs (tail fibs)
私たちに与えます (0, 1)
、合計は1です。したがって、リストは [0,1,1]
。これでリスト内の3つの要素がわかったので、リストの理解を続けて、リストから次のアイテムを取得し、テールから次のアイテムを取得できます。 (1,1)
—一緒に追加して、2にします。次に、次のペアを取得します。 (1,2)
、シーケンス3の次の番号を作成します。これは、理解が常に十分なアイテムを提供するため、無限に継続できます。
答え№4の2
関数型プログラミングの利点の1つは、数式を数学の問題のように手動で評価できることです。
fibs = 0 : 1 : [ a + b | (a, b) <- zip fibs (tail fibs)]
= 0 : 1 : [ a + b | (a, b) <- zip [0, 1, ??] (tail [0, 1, ??])]
ここに ??
まだ評価されていない部分です。続行するときに記入します。
= 0 : 1 : [ a + b | (a, b) <- zip [0, 1, ??] [1, ??])]
= 0 : 1 : [ a + b | (a, b) <- (0, 1) : zip [1, ??] [??]]
私は評価を排除していることに注意してください zip
その定義はここでは示されておらず、詳細は現在の質問と実際には密接な関係がないためです。これは、数字の各ペアが作成されることを示すために使用する表記法です zip
リストの理解によって消費されます。
= 0 : 1 : 0+1 : [ a + b | (a, b) <- zip [1, ??] [??]]
= 0 : 1 : 1 : [ a + b | (a, b) <- zip [1, ??] [??]]
これで、次の要素が ??
〜です 1
:
= 0 : 1 : 1 : [ a + b | (a, b) <- zip [1, 1, ??] [1, ??]]
= 0 : 1 : 1 : [ a + b | (a, b) <- (1, 1) : zip [1, ??] [??]]
= 0 : 1 : 1 : 1+1 : [ a + b | (a, b) <- zip [1, ??] [??]]
= 0 : 1 : 1 : 2 : [ a + b | (a, b) <- zip [1, ??] [??]]
そして次の要素は2です:
= 0 : 1 : 1 : 2 : [ a + b | (a, b) <- zip [1, 2, ??] [2, ??]]
すすぎ、繰り返します。
回答№5の場合は1
括弧内のリストの理解:
[ a + b | (a, b) <- zip fibs (tail fibs)]
変数aとbの結果から得られる出力(a + b)を含むリストを返します
zip fibs (tail fibs)
答え№6の場合は1
価値があるものについては、次のバージョンの方がわかりやすいと思います。
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
回答№7は0
このストリーム図を定義します
.----->>------->>----.
/
/ /
/
<---- 0 <---- 1 ---<<--- (+)
/
/
*---->>------*
それはそれ自体から新しい入力を引き出します生成されますが、常に生成ポイントの前の1つと2つの位置によって、シーケンスへの2つの「バックポインター」をそのまま維持します。これは定義に反映されます fibs = 0:1:[ a+b | a <- fibs | b <- tail fibs]
、並列リスト内包表記(:set -XParallelListComp
等。)。
最後のもののみを使用するため 二 要素、それは同等です
map fst . iterate ((a, b) -> (b, a+b)) $ (0,1)
回答№8の場合は-1
そうでなければ、パーサーは(a、b)に何が入るかをどのようにして知るのでしょうか?
編集:ViralShahのおかげで、私はこれを少しグノミックにします。 「<-」は、右側の「zip fibs(テールfibs)」から左側の「(a、b)」にペアのリストを割り当てるようにパーサーに指示します。
答え№9の場合-1
私はまだ理解していません。この答えが好きです: https://stackoverflow.com/a/42183415/246387 (から コード見習い)。
しかし、私はこの行からどのように理解していない:
= 0 : 1 : 1 : [ a + b | (a, b) <- zip [1, ??] [??]]
これに移動します:
= 0 : 1 : 1 : [ a + b | (a, b) <- zip [1, 1, ??] [1, ??]]
そして、これに加えて、私は私を悩ます何かがあります:
どうやって使えますか fib
私が持っていない場合、リスト内包表記内 fib
まったく(そうだと思われるが、確かに私は間違っている」 fib
まだ計算されていません。 (等号の左側)で(等号の)右側で計算されるのを「待機」します。