TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Bottom Type in F#

55 pointsby adelarsqover 4 years ago

8 comments

tegeekover 4 years ago
One of the remarkable property of ML languages is algebraic data types and then type systems. Look here<p>type Bottom = private Bottom of Bottom<p>Modeling any kind of data is intuitive and simple. This is why ML languages (F#, oCamel etc.) shines in industries where you&#x27;ve complex data like Finance. Reading any F# code is like reading a novel. It starts with modeling of data and small functions. Then these small functions and data evolves into bigger features. File by file you keep moving upwards. For example if you are writing a Json parser in F#, you start with Modeling Json data first. And here it is<p>type JsonValue = | String of string | Number of decimal | Float of float | Record of properties:(string * JsonValue)[] | Array of elements:JsonValue[] | Boolean of bool | Null<p>Then everything starts from here.
评论 #24568254 未加载
评论 #24565138 未加载
GolDDranksover 4 years ago
Bottom types get difficult in presence of statically dispatched type classes &#x2F; traits. Even though the bottom type doesn&#x27;t have values, because it is an existing type you can still define traits on it. You could plausibly define any existing trait on it, or none at all, because it&#x27;s logically consistent the either way: because the values don&#x27;t exist, you can&#x27;t actually call the trait methods so any trivial implementation (such as method that panics &#x2F; throws and exception when called) will do. You won&#x27;t get logical contradiction because you can&#x27;t call it.<p>But then you get the difficulty of, which actual traits should that type implement? That&#x27;s a hard decision to make, and it&#x27;s the reason why Rust doesn&#x27;t yet have a first class bottom type.
评论 #24565060 未加载
mlexover 4 years ago
Swift has Never, which is the return type of functions that don&#x27;t terminate, such as fatalError().<p><a href="https:&#x2F;&#x2F;developer.apple.com&#x2F;documentation&#x2F;swift&#x2F;never" rel="nofollow">https:&#x2F;&#x2F;developer.apple.com&#x2F;documentation&#x2F;swift&#x2F;never</a><p>It&#x27;s currently not implemented as a bottom type in the sense that it&#x27;s not the subtype of all types (discussed in <a href="https:&#x2F;&#x2F;nshipster.com&#x2F;never&#x2F;" rel="nofollow">https:&#x2F;&#x2F;nshipster.com&#x2F;never&#x2F;</a>).
评论 #24567470 未加载
asibover 4 years ago
Interestingly, if you read the article [0] linked in the reddit post referred to in this blog post, the author points out that the Haskell version of the bottom type has a problem - you can construct an inhabitant. Pulling out the relevant section of code:<p><pre><code> fix :: (a -&gt; a) -&gt; a -- defined in Data.Function fix f = let x = f x in x -- least fixed point of f false :: Void false = fix (id :: Void -&gt; Void) </code></pre> Since you can find an inhabitant of Void, you can therefore create an inhabitant of any type, so you can prove any proposition:<p><pre><code> inhabitant :: a inhabitant = fix id </code></pre> I don&#x27;t know if this is only really a problem if you were trying to use Haskell as a theorem prover. It might be the case that in practice, you&#x27;re unlikely to run into this inconsistency. I think [1] provides a bit more discussion regarding this.<p>[0]: <a href="https:&#x2F;&#x2F;gciruelos.com&#x2F;propositions-as-types.html" rel="nofollow">https:&#x2F;&#x2F;gciruelos.com&#x2F;propositions-as-types.html</a> [1]: <a href="https:&#x2F;&#x2F;frenchy64.github.io&#x2F;2018&#x2F;04&#x2F;07&#x2F;unsoundness-in-untyped-types.html" rel="nofollow">https:&#x2F;&#x2F;frenchy64.github.io&#x2F;2018&#x2F;04&#x2F;07&#x2F;unsoundness-in-untype...</a><p>EDIT: Just found this [2] which describes the above problem in type theory language.<p>[2]: <a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;System_U#Girard&#x27;s_paradox" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;System_U#Girard&#x27;s_paradox</a>
评论 #24564820 未加载
评论 #24564736 未加载
评论 #24564671 未加载
评论 #24567567 未加载
slaymaker1907over 4 years ago
Rust actually has a type like this in addition to a bottom type (which is !). It is the Infallible type which is an enum type (a sum type) with no variants and is thus not constructible. It&#x27;s purpose is to indicate that an operation always succeeds when that operation returns a Result type. But defining it that way, the compiler can use this information to remove error checks. While it doesn&#x27;t implement every trait automatically, I found it to be pretty easy to implement every trait I cared about since the it just had to typecheck and not do anything useful.
评论 #24565209 未加载
评论 #24566354 未加载
karmakazeover 4 years ago
Some discussion about a rejected suggestion for a bottom type and a local hack:<p><pre><code> type Bottom = private Bottom of Bottom </code></pre> which unfortunately<p>&gt; [...] subtype of all types. My bottom type does not have this property.
whateveracctover 4 years ago
I&#x27;ve never liked this &quot;spinny&quot; way if defining Void<p>I prefer<p>data Void = Void { absurd :: (forall a. a) }
xupybdover 4 years ago
This is probably a dumb question but isn&#x27;t this just null by another name?
评论 #24564883 未加载
评论 #24564688 未加载
评论 #24564628 未加载
评论 #24564565 未加载