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
   | ...

Valid XHTML 1.0 Strict