Skip to content

Instantly share code, notes, and snippets.

@noidi
Created December 9, 2014 09:50
Show Gist options
  • Save noidi/2ba18c56de56ddaa85f5 to your computer and use it in GitHub Desktop.
Save noidi/2ba18c56de56ddaa85f5 to your computer and use it in GitHub Desktop.
;; [09:46] < aphyr> hullo
;; [09:54] < aphyr> I'm trying to type an expression like [f g h], where (f (g (h nil))) is valid.
;; [09:55] < aphyr> e.g. something I could apply (comp) to
;; [09:55] < aphyr> But I'm having trouble figuring out how to enforce that each fn should take the next fn's output type
(ns cttest.core
(:require [clojure.core.typed :as t]))
(t/ann foo (t/All [a b c]
[[b -> c] [a -> b] [nil -> a] -> c]))
(defn foo [f g h]
(f (g (h nil))))
(t/ann int->str [Integer -> String])
(defn int->str [x]
(str x))
(t/ann str->maybe-int [String -> (t/Option Integer)])
(defn str->maybe-int [x]
(try
(Integer/parseInt x)
(catch NumberFormatException _
nil)))
(defn this-typechecks []
(foo str->maybe-int int->str (constantly 0)))
(comment
(defn but-this-fails []
;; g's return value does not match f's input
(foo int->str str->maybe-int (constantly "0")))
(defn and-so-does-this []
;; h's return type does not match g's input
(foo str->maybe-int int->str (constantly "foo"))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment