This commit is contained in:
Isaac Shoebottom 2025-02-19 11:43:31 -04:00
parent 665b4b7b32
commit 059a7c0c28

64
Labs/05.rkt Normal file
View File

@ -0,0 +1,64 @@
#lang plait
(define-type Exp
[strE (v : String)]
[numE (v : Number)]
[prodE (l : Exp) (r : Exp)])
(define-type Value
[numV (n : Number)]
[strV (s : String)])
(define-type Type
[numT]
[strT])
(define (times n str) (if (zero? n) "" (string-append str (times (sub1 n) str))))
(define (interp slang)
(type-case Exp slang
[(strE s) (strV s)]
[(numE n) (numV n)]
[(prodE l r)
(let ([l-v (interp l)]
[r-v (interp r)])
(cond
[(and (numV? l-v) (numV? r-v))
(numV (* (numV-n l-v) (numV-n r-v)))]
[(numV? l-v)
(strV (times (numV-n l-v) (strV-s r-v)))]
[(numV? r-v)
(strV (times (numV-n r-v) (strV-s l-v)))]
[else (error 'interp "type mismatch")]))]))
(test (interp (prodE (numE 6) (numE 7))) (numV 42))
(test (interp (prodE (numE 3) (strE "ha"))) (strV "hahaha"))
(test (interp (prodE (numE 2) (prodE (numE 2) (strE "ha")))) (strV "hahahaha"))
(test (interp (prodE (strE "hello") (numE 3))) (strV "hellohellohello"))
(test/exn (interp (prodE (strE "hello") (strE "world"))) "mismatch")
(define (typecheck exp)
(type-case Exp exp
[(strE v) (strT)]
[(numE v) (numT)]
[(prodE l r)
(let
([lt (typecheck l)]
[rt (typecheck r)])
(cond
[(and (numT? lt) (numT? rt)) lt]
[(numT? lt) rt]
[(numT? rt) lt]
[else (error 'typecheck "type mismatch")]))]))
(test (typecheck (numE 6)) (numT))
(test (typecheck (strE "hello")) (strT))
(test (typecheck (prodE (numE 6) (numE 7))) (numT))
(test (typecheck (prodE (numE 3) (prodE (numE 6) (numE 7)))) (numT))
(test (typecheck (prodE (numE 3) (strE "ha"))) (strT))
(test (typecheck (prodE (strE "hello") (numE 3))) (strT))
(test (typecheck (prodE (prodE (numE 3) (numE 6)) (numE 7))) (numT))
(test/exn (typecheck (prodE (strE "hello") (strE "world"))) "mismatch")
(test/exn (typecheck (prodE (prodE (numE 2) (strE "hello")) (strE "world"))) "mismatch")
(test/exn (typecheck (prodE (prodE (numE 2) (strE "hello")) (prodE (strE "world") (numE 3)))) "mismatch")
(test/exn (typecheck (prodE (strE "3") (prodE (numE 6) (strE "7")))) "mismatch")
(test/exn (typecheck (prodE (strE "3") (prodE (strE "6") (strE "7")))) "mismatch")