2012-02-02 12 views
3

現在、私はハスケルを悩ませています。ハスケル(一般的な関数型言語)についての私の知識はまだ低いですが、私はそれに取り組んでいます。 本当に私を悩ますのは、(私が思ったように)簡単な作業です:深さごとに1倍の折り畳みネストリストです。Haskell折りたたみネストリスト

fcalc = foldr (\x y -> (foldr (**) 1 x) * (foldr (**) 1 y)) [1.0, 1.0] [[2.0, 3.0], [4.0, 5.0]] 

何がすべきか:2^3 * 4^5ここで、^はラムダの内側の折り目によって行われます。残念ながら、それは動作しません。

Occurs check: cannot construct the infinite type: t0 = [t0] 
In the third argument of `foldr', namely `y' 

私は、指定された「無限型」エラーについて主に変数を使用していることを主に示しています。要素の代わりにリストでした。これは、私が外の折り畳み者の第2のパラームを問題として、しかし成功なしに考えさせた。 私はそれを得ることはありません。 :/

+1

まあ、私は疑問に思いますこれについて間違った方向に行くのではありません。まず、あなたは私の経験則の1つを破っています。問題を直接解決するために折り目を使用しないで、問題を解決するために中間的な抽象化を実装するために折り目を使用します。第二に、リストやネストされたリストが本当にあなたがしようとしているものの正しいデータ構造であるかどうか疑問です。私は、ある種の抽象構文木によってうまく機能している問題領域を扱っていると感じています。 –

答えて

4

あなたの問題は、あなたのアキュムレータのアキュムレータで計算をしようとしていることです、各要素でそれをやっている間。あなたが本当にしたいことはfoldrの各ステップの出力は、次のステップ(この場合は、例えばy変数)の第2引数として差し込まれ、

fcalc = foldr (\x y -> (foldr (**) 1 x) * y) 1 [[1.0, 1.0], [2.0, 3.0], [4.0, 5.0]] 

のようなものは覚えています。 foldrステップで数値が返されているので、y変数は既に数値であるため、その変数を折りたたむことはできません。

+0

ああ、こんなに間違った方法でどう思いますか...折りたたみの理解を訂正してくれてありがとう。 – Julian

1

ないあなたの質問への答えが、あなたの問題を解決する別の方法:

haskell> sum $ map ((**) <$> (!! 0) <*> (!! 1)) xs 
1032.0 

それとも、あなたはpointfreeに慣れていない場合:あなたが上がらない場合

haskell> sum $ map (\x -> let (a:b:_) = x in a ** b) xs 
1032.0 
+2

最初の2つの要素だけを見ているという事実をエンコードする場合は、代わりにタプルの使用に切り替えることもできます。 –

+0

確かに、コンパイル時にタプルであることがわかっている場合に限ります。 – missingfaktor

関連する問題