なのログ

だから見てて下さい・・・俺の・・・変身

型システム入門を読んでいます(第3回)

読んでいます。

第4章 算術式のML実装
やっていきます。
前回→第2回
今回

型システム入門 −プログラミング言語と型の理論−

型システム入門 −プログラミング言語と型の理論−

  • 作者: Benjamin C. Pierce,住井英二郎,遠藤侑介,酒井政裕,今井敬吾,黒木裕介,今井宜洋,才川隆文,今井健男
  • 出版社/メーカー: オーム社
  • 発売日: 2013/03/26
  • メディア: 単行本(ソフトカバー)
  • クリック: 68回
  • この商品を含むブログ (11件) を見る

型無し算術式の実装

ええと、前回までで、
「とりあえず言語系が定義できたっぽいわ」
「まわりの話はなんか圏論っぽいシナリオに沿っとるんやな」

というかんじの認識になりました。(雑)
今回はそれを実装するフェイズです。
3章の内容を4章で実装。5章の内容を6章で実装。となります。

実装に先立って、
「こういう環境で作業するとエエで」
ということがこんな感じで↓書いてあったのですが、
f:id:nanoyatsu:20181009004124p:plain

注釈を見ますと、
f:id:nanoyatsu:20181009004220p:plain

f:id:nanoyatsu:20181009004224p:plain

f:id:nanoyatsu:20181009004227p:plain

F#しなきゃだよなあ????

よろしくどうぞF#、そういうわけで書きました↓

let printThrough arg =
    printfn "%A" arg
    arg

// 構文の定義そのまま
type term =
    | TmTrue
    | TmFalse
    | TmIf of term * term * term
    | TmZero
    | TmSucc of term
    | TmPred of term
    | TmIsZero of term

// 数値 nvのやつ
let rec isnumericval = function
    | TmZero -> true
    | TmSucc t1 -> isnumericval t1
    | _ -> false

// なんらかの値
let rec isval = function
    | TmTrue -> true
    | TmFalse -> true
    | t when isnumericval t -> true
    | _ -> false

// 例外の定義
exception NoRuleApplies

// 構文解析 すぐわからないときは再帰的に掘り下げ
let rec eval1 = function
    | TmIf(TmTrue,t2,_) -> t2
    | TmIf(TmFalse,_,t3) -> t3
    | TmIf(t1,t2,t3) ->
        let t1' = eval1 t1
        TmIf(t1',t2,t3)
    | TmSucc(t1) ->
        let t1' = eval1 t1
        TmSucc(t1')
    | TmPred(TmZero) -> TmZero
    | TmPred(TmSucc(nv1)) when (isnumericval nv1) -> nv1
    | TmPred(t1) ->
        let t1' = eval1  t1 
        TmPred(t1')
    | TmIsZero(TmZero) -> TmTrue
    | TmIsZero(TmSucc(nv1)) when (isnumericval nv1) -> TmFalse
    | TmIsZero(t1) ->
        let t1' = eval1 t1
        TmIsZero(t1')
    | _ -> raise NoRuleApplies

// 例外を拾う
let rec eval t =
    try let  t' = eval1 t
        eval t'
    with NoRuleApplies -> t

定義そのままです。
そして、冊子中にあるOCamlで書かれたものとほぼ一致。

「ホントにF#ってほとんどそのままOCamlとして読めるのな・・・」
となるなどしました。

それで、なんか動かしてみた話がこのあたり。
(ソースのバージョンが上のやつとちょっと違います)(eval1は同じ)

pred(succ())をちゃんと省略してくれてるなーとか、
isZero(0)がTRUEになってるなーとか。
(こいつMastodonの発言貼って済ませやがった)

ただ「あ、これで終わりだ??」となるところがあったりして、

このへんの変更も考えられるところだな~~と。

定義的にいらない機能だったりするのかもわからないんですけど、
この後にこの実装を使ったりもしなさそうなので遊べたら遊びたいですねというお気持ち。

まあその何かというと、
結構写経でできてしまったので何かしたさがわいたのでした。

今回はおわりです。
5章、クソムズくてハゲています。

また!