Code that exercises type inference

余生长醉 提交于 2019-12-03 20:31:28

My general strategy is actually to approach it from the opposite direction -- ensure that it rejects incorrect things!

That said, here are some standard "confirmation" tests I usually use:

The eager fix point combinator (unashamedly stolen from here):

datatype 'a t = T of 'a t -> 'a

val y = fn f => (fn (T x) => (f (fn a => x (T x) a)))
               (T (fn (T x) => (f (fn a => x (T x) a))))

Obvious mutual recursion:

fun f x = g (f x)
and g x = f (g x)

Check out those deeply nested let expressions too:

val a = let
   val b = let 
      val c = let
         val d = let
            val e = let
               val f = let
                  val g = let
                     val h = fn x => x + 1
                  in h end
               in g end
            in f end
         in e end
      in d end
   in c end
in b end

Deeply nested higher order functions!

fun f g h i j k l m n = 
   fn x => fn y => fn z => x o g o h o i o j o k o l o m o n o x o y o z

I don't know if you have to have the value restriction in order to incorporate mutable references. If so, see what happens:

fun map' f [] = []
  | map' f (h::t) = f h :: map' f t

fun rev' [] = []
  | rev' (h::t) = rev' t @ [h]

val x = map' rev'

You might need to implement map and rev in the standard way :)

Then with actual references lying around (stolen from here):

val stack =
let val stk = ref [] in
  {push = fn x => stk := x :: !stk,
   pop  = fn () => stk := tl (!stk),
   top  = fn () => hd (!stk)}
end

Hope these help in some way. Make sure to try to build a set of regression tests you can re-run in some automatic fashion to ensure that all of your type inference behaves correctly through all changes you make :)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!