For some languages with a static type system the compiler is able to infer the types, however sometimes there's ambiguity (even with input) unless the user gives the type manually:

Motivation 1: Haskell

Consider the following Haskell example:

f xs = do
  x <-randomRIO (toEnum 0, toEnum 1) -- random Enum-type
  return $ map (x==) xs              -- check for each input if it's equal

Now calling it with f [False,True] succeeds because the type-checker can tell the type of the input - namely [Bool].

However, calling it with an empty list f [] won't work because the compiler has no idea what kind of list it is.

Now we could call it with f ([] :: [Bool]) explicitly giving the compiler the type and it would work. Or even worse (byte-wise) we could just give the function f a type: f :: [Bool] -> IO [Bool].

Motivation 2: Rust

A similar scenario could cause troubles in Rust, consider:

let f = |l| { l };  // identity function

Again calling it with f(vec!(101)) won't cause any trouble.

However calling it with an empty vector f(vec!()) will error.

Again we could solve it by using a typed input:

let v : Vec<i32> = Vec::new(); f(v)

Try it online!

Or we give the closure a type: |l : Vec<i32>| { l };


Often these issues arise with empty lists/vectors etc. - my questions are:

  • Can we assume that the inputs carry a type (like [] :: [Bool] or let v : Vec<i32> = Vec::new() in the examples above?
  • Can we assume that there is an implicit annotation (in case the challenge specifies sth. along the lines "given a list of integers")?

If none of these are answered with yes, can we work out a system to count bytes for giving the input a type (eg. in Haskell this is shorter), so something like:

  • the function is 67 bytes
  • annotating costs: ::[Bool] 8 bytes

Total byte count is 65 bytes, or something else?



Browse other questions tagged .