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)
Or we give the closure a type: |l : Vec<i32>| { l };
Questions
Often these issues arise with empty lists/vectors etc. - my questions are:
- Can we assume that the inputs carry a type (like
[] :: [Bool]
orlet 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?