私は非常に簡単な問題を解決してきました. からまでL
の自然数で構成された の長さのすべての減少するシーケンスの生成は、辞書式の順序です. しかし、私は非常に奇妙な問題に遭遇しました。見てみましょう:1
M
c :: (Ord a, Num a, Enum a) => a -> a -> [[a]]
c m 1 = map return [1..m]
c m l = do
n <- [l..m]
res <- c (n - 1) (l - 1)
return $ n:res
c' :: (Ord a, Num a, Enum a) => a -> a -> [[a]]
c' m = helper 1 m where
helper :: (Ord a, Num a, Enum a) => a -> a -> a -> [[a]]
helper a b 1 = map return [a..b]
helper a b l = do
n <- [a..b]
True <- return $ (l - 1 <= n)
res <- helper a (n - 1) (l - 1)
return (n:res)
したがって、明らかに、これらの 2 つの関数はまったく同じことを行います (いくつかのテストで確認しましたが、両方とも正しい結果が得られますc 100 98
) c' 100 98
。かかります:
[a..b]
なので、毎回生成するのはちょっと不安なのですが、ちょっと聞いてみたら、Haskell はすぐにパターンマッチするのではなく、遅延評価で遅延するのではないかという提案がありました。の大量の余分な呼び出しが発生しc'
ます。しかし、2 番目の理論は完全には成り立ちませんでした。GHCi コマンド プロンプトから直接コードにブレークポイントを設定し、 の値を監視しn
たところ、遅延パターン マッチングが当てはまらないことがわかりました。
問題は実際にはenumFromTo
機能にあるのでしょうか、それとも他の理由がありますか?