do
len <- hFileSize h
bu...">

パヌト2/3。 HaskellのICFPC 2009に理想的なVMコンパむラヌであり、コメントを広めおいたす

ここから始めたしょう。

これで、1぀の呜什だけでなく、ファむル党䜓をデコヌドする方法がわかりたした。

readMyFile = withBinaryFile "bin4.obf" ReadMode $ \ h -> do <br>
len <- hFileSize h<br>
buf <- mallocBytes $ fromInteger len<br>
hGetBuf h buf $ fromInteger len<br>
return (len, buf)<br>
これは基本的にファむルで機胜するため、必須の芁玠です。 withBinaryFileはファむルを開き、指定された「ナヌザヌ」関数を実行しおハンドルを枡し、ファむルを閉じお、ナヌザヌ関数が返したものを返したす。 ここでは、$蚘号の埌に、1぀のパラメヌタヌhハンドルからを持぀「ナヌザヌ定矩」関数を蚘述したした。 この関数は、ファむルサむズを受け取り、バッファを割り圓お、バッファに読み取り、バッファ自䜓ずその長さバむト単䜍を返したす。 ここでの「ナヌザヌ関数」には名前がなく、次のように始たるこずに泚意しおください。



\h -> function_body --

次は、バッファから呜什ずデヌタワヌドを取埗する機胜です。 バッファぞの珟圚のポむンタ必芁なバむト数だけシフト枈みがここに枡され、呜什むンデックスが枡されたす。 仕様から、奇数-奇数むンデックスを芚えおおり、オペコヌドずデヌタワヌドもそうです。 ぀たり、呜什はれロバむトから始たり、次に8番目から始たり、デヌタワヌド浮動、それぞれ4番目から始たり、れロから始たりたす。

instruction :: Ptr a -> Int -> IO (Word32,Double)<br>
instruction ptr i = do <br>
let (iaddr,daddr) = if i `mod` 2 /= O then ( O , 4 ) else ( 8 , O ) -- instruction/data <br>
instr <- peek (plusPtr ptr iaddr) :: IO Word32 -- <br>
dta <- peek (plusPtr ptr daddr) :: IO Double -- <br>
return (instr, dta)<br>
操䜜が「䞍均等に」数孊的に聞こえるこずに泚意しおください "/ ="。
次に、バッファヌ党䜓で「サむクル」を実行し、ペアのリスト指瀺が䞎えられたすを返したす。
ast = mapM ( \ i -> instruction (plusPtr buf $ i * 12 ) i) [ O .. nframes - 1 ]<br>
ここでは倚くのこずが起こりたす。 たず、マップ関数など特に、mapMは次のように機胜したす。リストの1぀の芁玠を倉換する「ナヌザヌ関数」が提䟛され、リスト自䜓がそれに枡されたす。次に、mapはこのナヌザヌ関数をそれぞれに適甚したすリストの芁玠であり、この関数の倀から新しいリストを圢成したす。 マップルヌプは内郚のどこかにありたす詳现は説明したせん。

let q = map (\h -> h * 2) [1,2,3,4,5]

[2,4,6,8,10]を返したす。これは兞型的な䟋です。 入力の問題にはむンデックスがありれロから最埌たで、出力には各むンデックスで「呜什」関数を呌び出した結果のリストがありたす。 すぐに理解するのは難しいこずもありたすが、その時が来たした-pythonずrubyはこの方向に進んでおり、それらず共に別の蚀語矀もちろん、そこにない蚀語からが動いおいたす。

ast = mapM ( \ i -> instruction (plusPtr buf $ i * 12 ) i) [ O .. nframes - 1 ]<br>

mapMに戻るず、枡された関数には、2番目の匕数ずしお0、1などが順に枡される呜什呌び出しが含たれたす。最初の匕数ずしお、反埩ごずに12バむトのオフセットを持぀バッファヌが枡されたす1オペコヌド+ 1デヌタワヌド= 12バむト。 plusPtrは、指定されたバむト数から離れた新しいポむンタヌを圢成したす。

それがサむクル党䜓です。 その結果、「フラット」オペコヌドのリストがありたすフラットは、仕様に埓っお1察1に倉換されるため。

[(Add 0 77 66, 0.0), (Sub 1 0 102, 0.0), ...]

぀たり、セル77ず66を远加し、結果を0にしたす。次に、セル0の内容からセル102の内容を枛算し、結果を1 ...に眮きた​​す。 これが私たちのコヌドです。 そしお、ここにデヌタがありたすセル0で0.0、最初の0.0など。

この時点で、アセンブラヌであっおも、どの蚀語でも䞍完党なコヌドを停止しお生成できたす結局、タスク仕様からの操䜜はそれに近い。 これを行うには、各フラット操䜜の文字列目的の蚀語に翻蚳を远加し、ルヌプでコヌドを提䟛する必芁がありたす。 しかし、それは逐語的に実行されるため、ゆっくりず退屈になりたす。

なぜ遅いのですか 1回だけ䜿甚されるいく぀かの結果のメモリぞの曞き蟌み操䜜があり、実際には、レゞスタたたはスタックのどこかに保存されるこずがありたすC / Haskell / Javaコンパむラなどがこれらの詳现を実行したす ASTを代衚し、「Haskell」は「䜕でも」ずしお機胜したす。 たた、くしゃみごずに構造フィヌルドにレコヌドを生成する堎合、そこからむンベントリを䜜成するコンパむラはありたせんが、メモリには1぀のレコヌドしかありたせん。

したがっお、「メモリ」セルがどのカテゎリに分類されるかを分析したす。

1定数読み取り専甚、曞き蟌み䞍可
2実メモリヌ曞き蟌みの前に読み取り、読み取りよりも遅く曞き蟌みたす
3䞀時倉数曞き蟌み、次に耇数の読み取り
4ワンタむム倉数曞き蟌み、次に読み取り。 カッコ付きの匏に入りたす。

誰がメモリセルを読み曞きするかを理解するには、次のセクションで各呜什の動䜜を説明する必芁がありたす䞀郚の呜什はメモリのみを読み取りメモリからポヌトぞの出力、他の呜什は曞き蟌みのみポヌトからメモリぞ、ほずんどの読み取りず曞き蟌み算術、条件付き。

各呜什の動䜜-読み取るもの消費するものに぀いお説明したす。

consumesData (Add _ r1 r2) = [r1,r2]<br>
consumesData (Sub _ r1 r2) = [r1,r2]<br>
consumesData (Mul _ r1 r2) = [r1,r2]<br>
consumesData (Div _ r1 r2) = [r1,r2]<br>
consumesData (Output r1 r2) = [r2]<br>
consumesData (If _ condr1 _ r1 r2) = [condr1,r1,r2]<br>
consumesData (Sqrt _ r2) = [r2]<br>
consumesData (Copy _ r2) = [r2]<br>
consumesData _ = []<br>
埌者の堎合、䞋線は「残りすべお」を意味し、最初の堎合は、匕数のコンストラクタのこの堎所にあるものに興味がないこずを意味したす。 ご芧のずおり、ここでもパタヌンマッチングが䜿甚されおいたす。

同様に、各操䜜の蚘述生成に関する動䜜を説明したす。
producesData (Add addr _ _) = [addr]<br>
producesData (Sub addr _ _) = [addr]<br>
producesData (Mul addr _ _) = [addr]<br>
producesData (Div addr _ _ ) = [addr]<br>
producesData (If _ _ addr _ _) = [addr]<br>
producesData (Input addr _) = [addr]<br>
producesData (Copy addr _) = [addr]<br>
producesData (Sqrt addr _ ) = [addr]<br>
producesData _ = []<br>
ポヌトに関しお各呜什が䜕を行うか-読み蟌むポヌトを説明したす。
readsPort (Input _ port) = [port]<br>
readsPort _ = []<br>
そしお、蚘録は圌女が曞いたポヌトです
writesPort (Output r1 _) = [r1]<br>
writesPort _ = []<br>
さらに、蚘録を短くするために著者の癖
cmap = concatMap<br>
concatMapは䜕をしたすか mapず同じですが、concatを実行したす。 Concatは「リストを1レベル接着したす」。 小さな䟋

concat [ "hello" , "africa" ] = "helloafrica" <br>
concat [[ 1 , 2 , 3 , 4 ],[ 5 , 6 , 7 , 8 ]] = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ]<br>
concat [[]] = []<br>
<br>
map ( \ i -> [ 1 .. i]) [ 1 .. 5 ] = [[ 1 ],[ 1 , 2 ],[ 1 , 2 , 3 ],[ 1 , 2 , 3 , 4 ],[ 1 , 2 , 3 , 4 , 5 ]]<br>
concatMap ( \ i -> [ 1 .. i]) [ 1 .. 5 ] = [ 1 , 1 , 2 , 1 , 2 , 3 , 1 , 2 , 3 , 4 , 1 , 2 , 3 , 4 , 5 ]<br>


今、最も恐ろしい最倧の䜜品
produceCode ast dta = <br>
let <br>
inports = cmap readsPort ast :: [Int]<br>
outports = cmap writesPort ast :: [Int]<br>
readPort / writesportを各オペコヌドに適甚し、すべおのリストを1぀のリストに連結したす。 したがっお、䞀般的に入力ポヌトず出力ポヌトのリストを取埗したした。
-- consumes,produces,outputs to port [(memory/port ref,op address)] lookup tables <br>
consumes = cmap ( \ (d,a) -> consumesData d `zip` [a,a .. ] ) (ast `zip` [ O.. ]) :: [(Int,Int)]<br>
produces = cmap ( \ (d,a) -> producesData d `zip` [a,a .. ] ) (ast `zip` [ O.. ])<br>
outputsPort = cmap ( \ (d,a) -> writesPort d `zip` [a,a .. ] ) (ast `zip` [ O.. ])<br>
ここでは、次の質問をするこずができるいく぀かのルックアップテヌブルリファレンスブックを䜜成したした。

指定したアドレスに曞き蟌む呜什はどのアドレスにありたすか 䞀般的に、質問は愚かです。したがっお、タスクの定矩により、この呜什はアドレスNにありたすが、私は今それを実珟したした
指定されたセルを読み取る呜什のアドレスは䜕ですか
指定されたポヌトに曞き蟌む呜什はどのアドレスですか

Haskellでは、プリミティブルックアップテヌブルはペアキヌ、倀のリストです。 ここには、指定されたキヌのすべおの倀を怜玢しおリストを返す関数がありたす。 ここにありたす

-- op address that reads/writes given mem/port <br>
reads m = map snd $ filter ((m == ) . fst) consumes :: [Int]<br>
writes m = map snd $ filter ((m == ) . fst) (produces) :: [Int]<br>
outputs m = map snd $ filter ((m == ) . fst) outputsPort :: [Int]<br>
それらは、指定されたメモリ䜍眮を読み取るか、指定されたポヌトに曞き蟌む、たたは曞き蟌むアドレスのリストを単に返したす。 仕組み
reads m = map snd $ filter ((m == ) . fst) consumes^M<br>
文字通り、2番目の芁玠を取埗し、最初に指定されたmに等しい最初の芁玠を消費者ディレクトリ以前に蚈算から陀倖したす。 どのように機胜したすか

フィルタヌ関数は、「ナヌザヌ関数」m ==。fstずリストを入力ずしお受け取りたす。 リストから各項目の入力にカスタム関数が枡され、TrueたたはFalseが返されたす。 このリストから、結果に応じお、芁玠が結果のリストに含たれるかどうかが決たりたす。 したがっお、小さなリストが残っおいたす。 このリストは、map関数の2番目の匕数です「$」挔算子に぀いおは前に説明したずおり。 次に、マップはsnd関数をリストの各芁玠に適甚し、結果のリストを圢成したす。

怜蚎されおいないもの。 snd / fst関数は、ペアの2番目たたは1番目の芁玠をそれぞれ返したす。぀たり、ペアの分解に関䞎し、簡単に蚀えば、2番目たたは1番目の芁玠を噛みたす。

fst (1,2) = 1
snd (1,2) = 2
fst ("Hello", 2+2) = "Hello"
snd ("Hello", 2+2) = 4

そしお今、Haskellの興味深い点の1぀は、関数の構成です。 䟋を考えおみたしょう

fx = sin (cos (sqrt (x))), - :
fx = sin $ cos $ sqrt x

ここで、脳を動かしお、「x」が垞に機胜の肉挜き噚を通過するこずを確認したす。最初にsqrt、次にcos、次に眪です。 確かに、関数fxのグラフを䜜成するこずは可胜であり、グラフを䜜成するこずが可胜であるため、これらの3぀の関数のアプリケヌションのシヌケンスは同じ結果を䞎える1぀の関数に察応するため、数孊者だけが別の名前を付けたせんでした!!! 正匏な思考を持぀人々を蚱しおください。

ここで、枡された関数をプロットするHaskell関数があるずしたす。䟋えば

plot :: (Double -> Double) -> Double -> Double -> IO() ( IO () void, : plot Double Double, Double ( ), void)
plot sin 0 6.28 -- sin 0 6.28
plot cos 0 3.14 -- , , .

ここで、sin関数たたはcos関数をそのたた枡すこずがわかりたす。匕数は、グラフの䜜成䞭に䜜成された人に枡されたす。 名前が発明されおいない機胜の完党な肉挜き噚をどのように枡すこずができたすか

そのような肉挜き噚を説明する緊急の必芁性がありたす。 したがっお

fun1 = sin -- 1
fun2 = sin . cos . sqrt -- , -

次に、䞍完党なアプリケヌションに぀いお説明したす。 ここに、たずえば环乗法などの2぀の匕数を取る関数がありたす。
pow 2 3 = 8 --
pow2:
pow2 = pow 2

必芁な2぀の匕数のうち1぀の匕数だけを枡したしたが、だれも私たちを止めおscりたせんでした pow2関数のタむプは䜕ですか 非垞に簡単です。圌女は別のDouble匕数を必芁ずし、それを远加し、この匕数でpow関数を呌び出したす。2぀は既に存圚したす

pow2 4 = 16
Haskellのタむプを蚘述する衚蚘も倩井から取られたものではないこずがわかりたした。手を芋おください

pow :: Double -> Double -> Double -- double, double, double
pow2 :: Double -> Double -- double, double

たた、pow2はpow関数に1぀の匕数を指定するこずで取埗されたため、1぀の匕数をpowに远加するず新しい関数が䜜成されるず結論付けるこずができたす

pow :: Double -> (Double -> Double) -- .

したがっお、必芁に応じお括匧を右偎に远加できたすが、意味は同じです。 たた、これからも続きたす。

pow 2 3 =pow 23、぀たり、最初に関数を生成しおから、欠萜しおいる匕数を远加したす関数をトリプルに適甚したす。

矊に戻りたしょう。
reads m = map snd $ filter ((m == ) . fst) consumes<br>
フィルタには関数がありたすm ==。 fst。 ここでは、ポむント組成ず郚分的な適甚を芳察したすm ==。 これはm ==です。これは、入力で1぀の匕数を受け取り、等号の右偎に代入する関数です。 m ==関数は、匕数をmず比范した結果を返したす。 mが5の堎合、m ==5はTrueを返したす。

今、私たちはすべおを右から巊に読みたす肉挜き噚があり、それが含むものが最初にfst関数に送られご存じのように、ペアから最初の芁玠を抜出したす、次にこの倀がm ==に送られたす。ブヌル倀を返したす。 したがっお、カップルa、bが肉挜き噚に入り、ブヌル倀が出おきたす。これはこのmに等しいでしょうか

ここで、曞き蟌みたたは読み取りされるセルぞのすべおの参照を遞択する必芁がありたす。そのため、次のこずから始めたす。

-- all memory references (including temporaries etc - from plain program) <br>
alldata = nub $ sort $ cmap consumesData ast ++ (map recast $ cmap producesData ast) :: [Int]<br>
ここで右から巊に読みたす「cmapproducesDataAstast」は、すべおの曞き蟌み可胜なセルのリストをアドレスのフラットリストの圢匏で返したす。同様に、consumsDataで発生したす。 。 基本的に、nubには゜ヌトされたリストは必芁ありたせんが、これは以前は知りたせんでした。

nub [1,2,1] = [1,2]
nub [2,1,2] = [2,1]

-- constants <br>
constants = filter ( \ m -> O == (length $ writes m)) alldata :: [Int]<br>
そしお、次のこずが起こりたした。誰も曞き蟌めないすべおのアドレスをすべおのデヌタから遞択したした。 そしお、それらはそれらからのみ読み取られるため、おそらく定数です。 ここにリストがありたす。

-- all persistent (optimized memory) <br>
persistents = filter ( \ m -> (head $ reads m) <= (head $ writes m)) (alldata \\ constants) :: [Int]<br>
そしお、ここでは、繰り返しの間に時々保存されるすべおの倉数を遞択したした。 これを行うには、すべおのデヌタを取埗し、そこから定数を枛算し操䜜\\-リストの違い、誰が最初に読み取り、誰が最初に曞き蟌むかを芋぀けたした。 あなたが圌らが曞く堎所の前で読むなら、圌らはそこに䜕かがあるず信じおいたす 前回から残りたした したがっお、この方法で、ブラックボックスのメモリである堎所のリストを䜜成し、読み取りおよび曞き蟌みに䜿甚できるようにしたした。

-- temporaries which are reused parts of expressions <br>
lets = filter ( \ m -> 1 < (length $ reads m)) (alldata \\ constants) \\ persistents :: [Int]<br>
これで、残りのデヌタからすべおのデヌタからこれたでに知っおいるすべおを差し匕いたため、耇数回読み取られたセルが芋぀かりたした。 これは氞続的なデヌタではないため陀倖、最初に蚈算されおから数回䜿甚されるのはおそらく䞀時倉数です。 䞀時倉数は同じ反埩内で䜿甚されたすが、それ以倖では必芁ありたせん。

-- expressions to inline (variables that are used 1 time) <br>
onerefs = filter ( \ m -> (length $ reads m) == 1 && (length $ writes m) == 1 ) <br>
((alldata \\ constants) \\ persistents) :: [Int]<br>
そしお、ここでは、䞀床曞き蟌たれおから1回読み取られる倉数を蚈算したした。 それらに぀いおは、䜕も開始せず、角括匧で囲たれた匏がそれらから圢成されたす。 ブラックボックスの䜜成者は、このようなクラスの倉数を必芁ずしおいたした。なぜなら、これらのクラスには䜎レベルの蚀語があり、高レベルの結果ではプロセッサのレゞスタに䜏んでいるからです。しかし、コンパむラは私たちの知らないずころでこれを凊理したす。

次に、ツリヌ操䜜操䜜䞭に読み取られるアドレスのみが曞き蟌たれるから、ツリヌのようなオペコヌド、぀たり接尟蟞Expを持぀ものに移動する必芁がありたす-それらは独自の皮類ぞのリンクを含み、ツリヌを圢成したす。 これを行うために、アドレス党䜓でツリヌ党䜓を生成する関数を蚘述したす。 再垰的になりたす。 定数が存圚するアドレスを圌女に䞎えれば、やるべきこずはあたりないからです。 そしお、他の2぀のセルを远加した結果が曞き蟌たれるアドレスを圌女に䞎えるず、他の2぀のOpを远加するOpを生成する必芁があり、それらはそこに定数であるか、突然乗算の結果がありたす...

-- geherates reference to the expression identified by given address, <br>
-- this excludes address where to store it, only value is obtained <br>
ref :: DestAddr -> Op<br>
ref a <br>
| elem a constants = Const (dta !! a)<br>
| elem a onerefs = geneval a<br>
| elem a lets = ReadVarExp a<br>
| elem a persistents = ReadExp a<br>
| otherwise = trace "oops1" $ undefined<br>
ここに、入力パラメヌタヌにいく぀かの前提条件が重ねられたref関数がありたす。そのような条件の構文は、瞊棒、条件、等号、関数の本䜓で、条件が真の堎合に満たされたす。 if ... elseif ... elseif ... else ... endifのような倧きなものです。 トレヌス "oops" $ undefinedで説明した最埌の゚ラヌ-゚ラヌを出力しトレヌス、プログラムを停止したす未定矩。

入力アドレスが定数に属しおいる堎合、定数ぞのアクセスを生成したす定数を衚すOpのみ。 Constコンストラクタヌパラメヌタヌによっお決定される定数は、単に指定されたアドレスのメモリ倀です。 dtaはすべおのメモリセルを順番に含むリストで、dfa !! aはリストのa番目の芁玠ぞのアクセスです。

入力アドレスがonerefsに属しおいる堎合メモリが1回曞き蟌たれ、次に1回読み取られる、他の2぀のopでツリヌノヌドを圢成する必芁がありたす括匧を䜿甚した操䜜。 Genevalが呌び出され以䞋で説明したす、単玔なOp2぀のメモリセルを远加し、結果を3番目に配眮から生成されたす他の2぀のOpを远加し、_in general_を返したす

同様に、䞀時倉数䞀床曞き蟌たれ、倚くが読み取られたすの読み取り、および入力ポヌトの読み取り甚。

geneval関数自䜓に぀いおは埌で説明したすが、パタヌンマッチングを䜿甚したす。 受信したアドレスから、リストastからフラットOpを遞択し、ツリヌに倉換したす。 奇劙なこずに、この関数は䞊蚘のようにrefを呌び出すため、関数は盞互に再垰的です。

-- turns plain code in tree code, converting memory refs to ops via "ref" <br>
geneval a = e $ ast !! a<br>
e (Add addr r1 r2) = AddExp (ref r1) (ref r2)<br>
e (Sub addr r1 r2) = SubExp (ref r1) (ref r2)<br>
e (Mul addr r1 r2) = MulExp (ref r1) (ref r2)<br>
e (Div addr r1 r2) = DivExp (ref r1) (ref r2)<br>
e (If cmdop cmdr addr r1 r2) = IfExp cmdop (ref cmdr) (ref r1) (ref r2)<br>
e (Input addr r1) = ReadPortExp r1<br>
e (Sqrt addr r1) = SqrtExp (ref r1)<br>
e (Copy addr r1) = ref r1<br>
e x = trace (show x) $ undefined<br>
Op Copyは、結果を元のアドレスに枡すこずを意味したす。 Add / Sub / Mul / Divコマンド-フラットからツリヌぞの逐語的な倉換。 入力はポヌトから読み取るように倉換されたす。 䞀時倉数たたは定数倉数からの読み取りは、䞊蚘でrefに倉換されたす。

次に、䞖代を曞きたす
retval = "module Vm where \n data VMState = VMState { " ++ <br>
(intercalate "," $ <br>
map (( "m" ++ ) . show) persistents ++ <br>
map (( "o" ++ ) . show) outports<br>
) ++ "::Double } \n " ++ <br>

これにより、構造自䜓の説明を含むパヌツが生成されたした。 ここで、明らかに、++はリスト文字列を接着する挔算子であり、むンタヌカレヌトは耇数のリストを接着し、指定されたリストず亀互に䞊べたす読みたす区切りコンマを挿入したす。構造には、プレフィックスmメモリずoの接頭蟞が付いた出力ポヌト-出力ポヌト。 最埌に、Double型を指定し、改行を忘れないでください。

Double型ではなく、!! Double型を指定するず、レむゞヌフィヌルドではなくレむゞヌフィヌルドを持぀構造になりたす。 この研究では、すべおの出力ポヌトを蚈算するず、速床の差が20倍以䞊であるこずが瀺されおいたす前の投皿を参照。 さお、厳密性泚釈感嘆笊を眮き換えるかどうかは読者次第です。 「すべおの出力ポヌト」ず蚀ったのはなぜですか 遅延蚈算では、N回目の反埩埌にこの構造の倀を取埗し、たずえば、必芁なポヌトを1぀だけ芁求できるためです。 仕事の倧きな前線が開き始め、䞀時停止埌、蚈算された倀が来たすたずえば、

putStrLn $ "o10=" ++ (show $ o10 vmlast)


その埌、次のようになりたす。「o10 =」がコン゜ヌルに曞き蟌たれ、その埌䞀時停止し、倀が衚瀺されたす。 同じputStrLnを再床曞き蟌むず、遅延はもうなくなりたす。 蚈算された倀。 埌でo11を曞くように䟝頌するず、遅延は再び倧きくなりたすが、o10ずo11にはo10に぀いおすでに完党に蚈算されおおり、o11に぀いおは考慮されない可胜性が高いため、おそらくそれほど倧きくないでしょう。

"initState = VMState {" ++ <br>
(intercalate "," $ <br>
map ( \ a -> "m" ++ (show a) ++ "=" ++ (show $ dta !! (recast a))) persistents ++ <br>
map (( ++ "=O" ) . ( "o" ++ ) . show) outports<br>
) ++ "} \n " ++ <br>
ここで、ブラックボックスの状態の初期倀を䜜成する関数が生成されたした。 すべおのメモリは、適切な堎所dtaにあったバむナリの倀で初期化されたす。 すべおの出力ポヌトはれロに初期化されたす。 Haskellでは、構造の必須の初期化が必芁です。

"nextState x (" ++ (intercalate "," $ map (( "i" ++ ) . show) inports) ++ ")= \n let \n " ++ <br>
cmap ( \ a -> " t" ++ show a ++ "=(" ++ (ast2haskell "x" $ geneval a) ++ ") :: Double \n " ) lets ++ <br>
" in x { \n " ++ <br>
intercalate ", \n " (<br>
map ( \ a -> " m" ++ show a ++ "=" ++ (ast2haskell "x" $ geneval a)) persistents ++ <br>
map ( \ a -> " o" ++ show a ++ "=" ++ (ast2haskell "x" $ geneval $ head $ outputs a)) outports )<br>
++ "} \n " ;<br>
ここでは、最もボリュヌムのある郚分が生成されたす。 たず、入力パラメヌタヌのタプルが次のような圢匏で圢成されたすi10、i11、i60000、その埌、「let」が入り、すべおの䞀時非氞続倉数がプレフィックス「t」で入力されたす。 次に、各メンバヌの匏が蚘述される新しい構造が圢成されたすx {m20 = expr1、m25 = expr2 ...、o10 = exprN}。 初期化tおよびmの匏は、「tNN」、「iNN」、および「mNN x」を指したす。埌者は、前の反埩のメモリ倀を意味したす。

in retval -- .


゚ンディングが続きたす

Source: https://habr.com/ru/post/J70179/


All Articles