1

初めて Haskell で遊んでいます。

最初に十分に正確な結果を返す関数を作成しました。期待どおりに動作しますが、これにはジェネレーターを使用しています。このタスクでジェネレーターを交換するにはどうすればよいですか?

integrateWithPrecision precision =
    (take 1 $ preciseIntegrals precision) !! 0

preciseIntegrals :: Double -> [Double]
preciseIntegrals precision =
    [
        integrate (2 ^ power) pi | power <- [0..],
        enoughPowerForPrecision power precision
    ]
4

3 に答える 3

3

美しいuntil機能が使えます。ここにあります:

-- | @'until' p f@ yields the result of applying @f@ until @p@ holds.
until                   :: (a -> Bool) -> (a -> a) -> a -> a
until p f x | p x       =  x
            | otherwise =  until p f (f x)

したがって、次のように関数を記述できます。

integrateWithPrecision precision = integrate (2 ^ pow) pi
  where
    pow = until done succ 0
    done pow = enoughPowerForPrecision pow precision

あなたの場合、すべての反復を実行してから、結果を一度だけ計算します。ただしuntil、各ステップで結果を計算する必要がある場合でも役立ちます。(iter, result)タプルを使用resultして、最後に を抽出するだけsndです。

于 2013-09-29T20:51:33.377 に答える
1

要件を満たすものを取得するまで、より高い電力をチェックしたいようです。これはあなたができることです: 最初に十分なパワーを得るために関数を定義し、次にそれを使用して統合します。

find条件を満たすリストの最初の要素を取得します – 十分な力があるなど! 次に、fromJustそこから実際の値を取得する必要があります。ほとんどの場合、コードに含めるfromJustのはひどい考えであることに注意してください。ただし、この場合、リストは無限であるためfromJust、プログラムがクラッシュするずっと前に無限ループの問題が発生します。

enoughPower :: Double -> Int
enoughPower precision =
  fromJust $ find (flip enoughPowerForPrecision precision) [0..]

preciseIntegrals :: Double -> Double
preciseIntegrals precision = integrate (2^(enoughPower precision)) pi
于 2013-09-29T18:49:07.553 に答える
1

関数

\xs -> take 1 xs !! 0

と呼ばれるhead

head []     = error "Cannot take head of empty list"
head (x:xs) = x

空のリストを渡すとエラーがスローされる可能性があるため、その使用はやや安全ではありませんが、この場合、リストが空ではないことを確認できるため、問題ありません。


また、これらは特別な形式ではなく、遅延評価の単純な結果であるため、Haskell ではこれらの「ジェネレーター」とは呼ばない傾向があります。この場合、preciseIntegralsは「リスト内包表記」と呼ばれ[0..]、遅延生成されたリストにすぎません。

于 2013-09-29T18:26:35.560 に答える