Statically typed language: a language that does not allow you to change the type of a variable at run-time.
That's not the definition of statically typed. Statically typed means that type checking (and type inference) happens before runtime. The opposite is dynamic typing, where type checking happens at runtime.
It is perfectly possible to design a statically typed language in which either identifiers can change types or types can change.
Type safety: type safety means that you are not allowed to mix incompatible data types.
For example, you cannot assign a
float to an
int, and you cannot assign an
int to a function pointer, and you cannot add a user-defined object to an
int (unless you use operator overloading), etc.
There is no universally accepted definition of type safety. Yours is a very sensible one.
Back to my question, let's say that there is an interpreted statically typed language,
There is no such thing as an interpreted statically typed language, simply because there is no such thing as an interpreted language, period. Interpretation and compilation are traits of the, well, interpreter or compiler (duh!), i.e. the implementation, not the language. Every language can be implemented with an interpreter and every language can be implemented with a compiler. In fact, many languages have both interpreted and compiled implementations. For example, Haskell has several compiled implementations (Ghc, Jhc, Yhc, Lhv) and an interpreted implementation (Hugs). ECMAScript has pure compiled implementations (V8), and hybrid mixed-mode implementations (e.g. SpiderMonkey AOT-compiles ECMAScript to SpiderMonkey bytecode, then both compiles and interprets this bytecode)
Saying that a language is an "interpreted language" is not just wrong, it is even more than wrong, it is simply non-sensical. The idea of "language" and the idea of "interpretation" live on two different levels of abstraction. If English were a typed language, "interpreted language" would be a type error.
in such a language I can write code that assigns a
float to an
int, but when this code is executed, a (run-time) type error will occur.
You are inconsistent with yourself here.
You say "statically typed" means "does not allow to change the type of a variable", which means you can not write such code. But now you say that you can write such code in a statically typed language.
But if you can write such code, then by your own definition, it is not statically typed. And if it is statically typed, then by your own definition, you cannot write such code.
So, it's not surprising that you get a contradiction, because you are contradicting yourself.
Is such a language considered to be type safe, or are type safe languages can only be statically typed and compiled, and so type errors must be caught at the compilation stage?
Whether or not type safe languages can only be statically typed or not really only depends on how you define "type safe". Another common definition of "type safe" is that you cannot subvert the type system. Ruby is dynamically typed, but it is usually described as type safe. On the other hand, C is statically typed but nobody would describe it as type safe.
As for whether a type safe language can only be compiled, I already explained above that compilation is an implementation detail, it is not a property of the language itself.