2016-08-26 10 views
3

foldrという用語で、プリミティブ再帰を定義しようとしています(A tutorial on the universality and expressiveness on foldの章4.1を参照)。ここでパターンマッチングと解体の厳密性

は、定義上で以下head $ simpleRecursive (\x xs acc -> x:xs) [] [1..]

のために停止しません。しかし、それ

simpleRecursive f v xs = fst $ foldr g (v,[]) xs 
    where 
    g x (acc, xs) = (f x xs acc,x:xs) 

で初めての試みであり、ほぼ同様の定義が異なる結果を考えると

simpleRecursive f v xs = fst $ foldr g (v,[]) xs 
    where 
    g x r = let (acc,xs) = r 
      in (f x xs acc,x:xs) 

を停止定義であり、それはなぜ違いますか?それはHaskellのパターンがどのように一致するかと関係がありますか?

+1

に相当します。 – chepner

答えて

3

二つの機能の間の決定的な違いは、

g x (acc, xs) = (f x xs acc, x:xs) 

ではないのに対し、

g x r = let (acc, xs) = r 
     in (f x xs acc, x:xs) 

でタプルコンストラクタ上にパターンマッチが、反論できないということです。言い換えれば、gの最初の定義は、問題を修正 `G`の定義に移動するので、

おそらくxs``とスコープの問題に関連し
g x ~(acc, xs) = (f x xs acc, x:xs) 
+0

問題は、一致しないr(acc、xs)があることを意味しますか? –

+0

(v、[])はrが常に(acc、xs)の形式であることを確認していませんか? –

+0

いいえ、それ以降の関数への再帰呼び出しは '(v、[])'に渡されず、 'g'によって返されるものはすべて渡されるためです。 – Cactus

関連する問題