Shapeless encodes double negation like so
type ¬[T] = T => Nothing
type ¬¬[T] = ¬[¬[T]]
that is
(T => Nothing) => Nothing
Miles explains
...the bottom type (Scala’s
Nothingtype) maps to logical falsehood... negation of a typeA(I’ll write it as¬[A]) to have as it's values everything which isn’t an instance ofA
Nothing is also used to represent non-termination, that is, computation that cannot produce a value
def f[T](x: T): Nothing = f(x)
Applying this interpretation to (T => Nothing) => Nothing, it seems to mean:
( T => Nothing ) => Nothing
Assuming a value of type T, then the program does not terminate, hence it never produces a value.
Is this intuition correct? Are concepts of falsehood and non-termination equivalent? If so, why having a program that does not produce a value, which does not produce a value, means we have a value of T?
It doesn't. Logic arising from Curry–Howard correspondence is not classical but intuitionistic. There is no law of excluded middle
T ∨ ¬T(but there is double negation of the law of excluded middle).¬¬Tis not equivalent toT.T => ¬¬Tbut not¬¬T => T.No. Normally non-termination is ignored. According to Curry–Howard correspondence, statement is true when corresponding type is inhabited (i.e. there is a value (term without free variables) of this type) and false when the type is not inhabited.
Nothing(or bottom type⊥) is not inhabited (it corresponds tofalse). IfTis inhabited thenT => Nothingis not inhabited (otherwiseNothingwould be inhabited). IfT => Nothingis inhabited thenTis not (again, otherwiseNothingwould be inhabited). That's the reason to define¬T = T => Nothing.When non-termination is considered, this means that every type
Tis lifted to typeT'consisting of elements ofTand bottom value⊥(divergence, not to be confused with bottom type).