これはばかげた仕事です
C を Haskell に直接変換するのはばかげています。以前に有料でやったことがありますが、スムーズに、または迅速に進みません。タスクを記述し、ターゲット言語で慣用的なスタイルで実装する方がはるかに優れています。アルゴリズムの英語の説明を提供すると、質の高い回答が得られる可能性が高くなります。
コンパイル可能なコードを投稿してください
質問を投稿するときは、コンパイルされていることを確認してください。
HaskellでCを書く方法ではなく、Haskellを学ぶ
特に、命令型から関数型、可変型から不変型、厳密型から遅延型、明示的なキャストから明示的なキャスト、手動で管理されたメモリからガベージ コレクトされたメモリなど、境界を越える場合は特にそうです。あなたはこれらすべての分断を越えています。
あなたの仕事が Haskell を学ぶことであるなら、あなたは間違ったところから始めています。あなたのタスクが Haskell で変更可能なベクトル/配列を学習することである場合は、ニュアンスを理解するために基礎をもっと知る必要があります。あなたの仕事が、配列のサポートが不十分であるために Haskell を罵倒することである場合、Roman がやって来て Vector パッケージを作成する前に、あなたは本当に簡単にそれをすることができたでしょう - これは私の言い方です: HaskellArray
の見た目だけを見ないでくださいsでVector
。
OK OK、解決策は何ですか?
Vector
配列にはパッケージを使用し、変更可能な操作にはモナドST
を使用します (最初の箇条書き):
import qualified Data.Vector.Unboxed.Mutable as M
import qualified Data.Vector.Unboxed as V
import Control.Monad.ST
import Control.Monad
メイン関数は 2 つのベクトルを取り、float を返します。配列への変更可能な参照を取得することから始めthaw
、単純な折り畳みを使用して、配列参照を反転できるようにします。
someFunc :: V.Vector Float -> V.Vector Float -> Float
someFunc arrA arrB = runST $ do
-- Obtain mutable copies of the arrays
mA <- V.thaw arrA
mB <- V.thaw arrB
(mA', mB') <- foldM op (mA, mB) [1..n-1] -- for(i = 1 ; i < n; i++)
M.read mA' 0
where
n = min (V.length arrA) (V.length arrB)
内側の for ループは に含まれていop
ます。配列から単純な読み取りを実行し、新しい値を書き込むだけです。タプルで 2 つの配列を返す必要があります。タプルは反復ごとに反転され、可変ポインター (2 番目のポイント) の同じセマンティクスが取得されます。
op (mA, mB) i = do
forM_ [0..n-i-1] $ \j -> do
v1 <- M.read mA j
v2 <- M.read mB (j+1)
M.write mB j (someFn i j v1 v2)
return (mB, mA)
3番目のポイントと一致して、内側のループ境界は外側のループに基づいて変化します。
実行可能なプログラムをコンパイルできるように、main を含めます。
someFn i j f1 f2 = f1 + fromIntegral i + fromIntegral j - f2
main = print $ someFunc (V.fromList [1..10]) (V.fromList [0..9])
これは教育目的のみです。私はこれをテストしていません。道徳的にはCと同じはずですが、ループで1つずれているか、その他の些細な違いがある可能性があります。