Skip to content

Instantly share code, notes, and snippets.

View calebh's full-sized avatar

Caleb Helbling calebh

View GitHub Profile
type BaseTyCon = TyConNumber
| TyConBool
| TyConUnit
| TyConList
| TyConFun
| TyConTuple
| TyConUserDefined of string
type TyCon = TyCon of BaseTyCon * Kind
type Kind = Star | KFun of Kind * Kind
let rec kindStack numTyArgs =
match numTyArgs with
| 0 -> Star
| n -> KFun (Star, kindStack (n - 1))
let tNumber = TConExpr (TyCon (TyConNumber, Star))
let tBool = TConExpr (TyCon (TyConBool, Star))
let tUnit = TConExpr (TyCon (TyConUnit, Star))
let tArrow = TConExpr (TyCon (TyConFun, KFun (Star, KFun (Star, Star))))
let baseTyConString b =
match b with
| TyConNumber -> "Number"
| TyConBool -> "Bool"
| TyConUnit -> "()"
| TyConUserDefined name -> name
| _ -> sprintf "%A" b
let parens s = sprintf "(%s)" s
let rec tysubst theta t =
match t with
| TVarExpr u ->
match Map.tryFind u theta with
| Some t' -> t'
| None -> t
| TApExpr (l, r) ->
TApExpr (tysubst theta l, tysubst theta r)
| _ ->
t
type ErrorMessage = Lazy<string>
type Constraint = Equal of TyExpr * TyExpr * ErrorMessage
| And of Constraint * Constraint
| Trivial
let (=~=) q1 q2 err = Equal (q1, q2, err)
let (&&&) c1 c2 = And (c1, c2)
let rec conjoinConstraints cc =
exception TypeError of string
// Some useful extensions to F#'s map module
module Map =
let keys m = m |> Map.toSeq |> Seq.map fst |> Set.ofSeq
let fromKeys f keys =
Seq.fold (fun accum k -> Map.add k (f k) accum) Map.empty keys
let singleton key value =
[<EntryPoint>]
let main argv =
let solveAndCatch con =
try
printf "%A\n\n" (solve con)
with
| TypeError s ->
printf "%s" s
let t1 = tTuple [freshtyvar () |> TVarExpr; tNumber]
let t2 = tTuple [tUnit; freshtyvar () |> TVarExpr]
map
[(TyVar ("t1",Star), TConExpr (TyCon (TyConUnit,Star)));
(TyVar ("t2",Star), TConExpr (TyCon (TyConNumber,Star)))]
Type error: The types () and Number are not equal.
Clearly unit isn't the same type as a number
myconcat xs ys = xs ++ ys
greet = myconcat "Hello "