Question:
我按照您的提示做作業的第三題 可是當我寫這這樣的句子 e_i (Var v) s = fn Error => Error | (Normal s) => if((s v) = Init) then s else Error 或者是 e_i (Var v) s = case s of Error => Error | Normal => if((s v) = Init) then s else Error 或者是 e_i (Var v) s = case s of Error => Error | _ => if((s v) = Init) then s else Error 或者是 e_i (Var v) s = case s of Error => Error | Normal(s) => if((s v) = Init) then s else Error 均無法成功 請問像這種判斷 s(state) 為 Error 則回傳 Error 否則利用 s u(判斷某個變數是否已初始化過) 的 function 跟怎麼寫才對呢?
Answer:
運算式 e_i (Var v) s 的值應該只是 Init 或是 Uninit 。 也就是說 e_i 的型態應該是: iexpr -> state -> value 依此,你應該可以寫出 e_i 的定義。
Question:
我照您說的方式去改正, | e_i (Var v)(s:state) = (case s of Empty => Unint | => s v) 編譯常會出現錯誤訊息,說 s 並非是一個函數 hw2_3_back.sml:35.13-35.16 Error: operator is not a function [tycon mismatch] 這種錯誤的原因一直無法解決 另外就是 e_i (Var v) s 的值為甚麼只是 Init 或是 Uninit 。 一個 iexpr evaluate 後不是應該反應的是他的 state(error or normal) 如果 evaluate 出來的只是 Init/Unint, 是不是在語意上怪怪的 @@ 這樣變得 e_b 也必須連帶都是 Init/Uinit, 這樣的解釋是不是不大符合我們一般的思維?
Answer:
以下請參考。 e_i (Var v) s = (case s of Empty => Unint | Normal f => f v) 另外, e_i, e_b, c 三者的型態若是如下,應該很合適: val e_i = fn : iexpr -> state -> value val e_b = fn : bexpr -> state -> value val c = fn : prog -> state -> state
Question:
如何讓 SML/NJ 於執行時,輸出詳細的資訊(例如說:很長的串列或是很深的資料結構)?
Answer:
可以在程式的最前頭加上以下三行,讓編譯器列印多一點資訊: val _ = Control.Print.printDepth := 1000000 val _ = Control.Print.printLength := 1000000 val _ = Control.Print.stringDepth := 1000000
Question:
請問2.c小題,是用現有的prog,作出另一種while而不是用prog裡面定義的, 還是用prog寫出一支程式並有while即可,如果是後者的話, 請問可以自己額外定義function和在prog中額外加上其他的指令嗎?
Answer:
「用 prog 寫出一支程式」。 你可以自己再定義型態 iexpr, bexpr, prog 中新的 value constructors。 (這是你「加上其他的指令」的意思嗎?)不過同時你也要修訂函數 e_i, e_b, c 的定義囉! 不過這題只要求你延用現有的 iexpr, bexpr, prog 型態定義,來寫新的程式,就可以了。 是否要再「加上其他的指令」,完全看你的需要與興趣。
Question:
在老師先前回答同學問題時,提到 state 是個 function, 傳入變數名,就會傳出這個變數在此狀態下的值。 除此之外,這個 function 是否還有其他性質?假設 w 是個 uninitialised variable 那麼 - state "w"; 應該要回傳 uninit 還是 error 呢? error 是我們需要另行定義的狀態嗎? 題目的意思是否是寫出一個 While of bexpr * prog with output = {ok, error} 呢?
Answer:
在狀態 s 下,假設 w 是個 uninitialised 的 variable,那麼在這一題裡 (著重在 Nonstandard Semantics 的表示), 狀態 s 以傳回 uninit 為佳。 另外,此題狀態的型態,在 ML 下如何定義較方便,也是可以想一想。 或許可以這樣想: datatype value = Init | Uninit datatype state = Error | Normal of string -> value 那麼函數 e_b, e_i, 以及 c 的型態應該如何較合適?你如何製作? 這是一題「開放式」的作業,並沒有標準的答案,課本上這部份的講解,也不是很精確。 所以在作答上,以你的方式(精確的)製作出所要求的 Nonstandard Semantics 並說明清楚可以了。
Question:
對於這一次的題目沒有看的很了解,作業2標號2的a小題是要我們寫一個 modify 的 ML程式嗎?
Answer:
是的。
Question:
題目打modify s x a,是說類似fun modify (Int s)...會把原先x的值a換成s的意思嗎?
Answer:
s 是 state x 是變數名稱 a 是該變數新的值 modify s x a 要得到一個新的 state ,它和 s 的差別只在於變數 x 的地方。
Question:
b小題應該是把上面...的部分依照前面的定義用ML的語法填滿,那下面的 "so that functions..."是要我們再做什麼事呢?
Answer:
「ML的語法填滿」後,該三個函數的賦予 integer expressions, boolean expressions, 以及 While programs 該有的涵義。 也就是說,你的程式 c 使用來解釋 While program ex_4_5 (於狀態下 s0 之下) val s = c ex_4_5 s0 的確會求得該要有的新狀態 s (其中變數 x, y, z 的值,都是如課本所要求的)。
Question:
c小提是自行用ML寫一個while的function嗎?
Answer:
是的。使用資料型態 prog ,寫你自己的 While program (範例: ex_4_5)。
Question:
看了老師的提示和對照課本之後,仍然對a小題答案呈現的形式不甚了解, 課本定義modify是一個處理assignment的函數,可以在state s下把variable x對應到value a, 並變成新的狀態,而這題要我們寫一個modify的ML程式,如果只是要表達assignment的話, fun modify (x:int):int = x;但這題應該是要問state的變化,但state要怎麼用ML的語法呈現呢? 而且state是個會將variable對應到value的 function?若要用ML呈現的話,會是類似像int->int的形式嗎?
Answer:
state 的型態是(類同於)string -> int ,也就是說它是一個函數, 你給它一個變數名稱(型態為 string), 它會找出這個變數所對應的值(型態為 int)。 目前你說的 "fun modify (x:int):int = x;" 方向不對。 函數 modify 的型態應該是(類同於) (string -> int) -> string -> int -> (string -> int) , 其中第一個 (string -> int) 是第一個參數 s 的型態, 接下來的 string 是 x (變數)的型態, 接下來的 int 是 a (新的變數值)的型態, 然後的 (string -> int) 是函數值 (modify s x a) 的型態。 你只要照著課本上 modify 的定義,直接寫成 ML ,幾乎就對了。 提示: fun all0 x = 0 val s0 = modify all0 "z" 2 (以上節錄習題 c 小題的 all0 和 s0 這兩個狀態;它們意思與用法你清楚嗎?)
Question:
小題我寫下面的情況ML才能跑 fun e_i (Int i) = i | e_i (Plus (m , n)) = (e_i m) + (e_i n) | e_i (Minus (m , n)) = (e_i m) - (e_i n) | e_i (Times (m , n)) = (e_i m) * (e_i n) | e_i (Divide (m , n)) = (e_i m) div (e_i n); 若是用老師作業的形式(也就是多了s) fun e_i (Int i) s = i 這樣ML就不會過,是題目有問題還是我會錯意呢? 還有若把| e_i (Var v) = ...(我填入v);考慮進去,是不是加減乘除的函數都必須考慮m和n可能是variable的情況呢? 測試寫得對不對的方式是不是向下面的形式? e_i (Divide (Int 2 ,Int 3));
Answer:
提示: fun ... | e_i (Var v) s = s v | ...