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
Nothing
type) 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).¬¬T
is not equivalent toT
.T => ¬¬T
but 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
). IfT
is inhabited thenT => Nothing
is not inhabited (otherwiseNothing
would be inhabited). IfT => Nothing
is inhabited thenT
is not (again, otherwiseNothing
would be inhabited). That's the reason to define¬T = T => Nothing
.When non-termination is considered, this means that every type
T
is lifted to typeT'
consisting of elements ofT
and bottom value⊥
(divergence, not to be confused with bottom type).