Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Hm. Let's forget about types for a moment.</p> <p>Let's say you have two functions:</p> <pre><code>import qualified Data.IntMap as IM a :: Int -&gt; Float a x = fromInteger (x * x) / 2 l :: Int -&gt; String l x = fromMaybe "" $ IM.lookup x im where im = IM.fromList -- etc... </code></pre> <p>Say there exists some value <code>n :: Int</code> that you care about. Given only the value of <code>a n</code>, how do you find the value of <code>l n</code>? You don't, of course. </p> <p>How is this relevant? Well, the type of <code>myLength</code> is <code>A a -&gt; Int</code>, where <code>A a</code> is the result of applying the "type function" <code>A</code> to some type <code>a</code>. However, <code>myLength</code> being part of a type class, the class parameter <code>a</code> is used to select which implementation of <code>myLength</code> to use. So, given a value of <em>some specific type <code>B</code></em>, applying <code>myLength</code> to it gives a type of <code>B -&gt; Int</code>, where <code>B ~ A a</code> and you need to know the <code>a</code> in order to look up the implementation of <code>myLength</code>. Given only the value of <code>A a</code>, how do you find the value of <code>a</code>? You don't, of course.</p> <p>You could reasonably object that in your code here, the function <code>A</code> <em>is</em> invertible, unlike the <code>a</code> function in my earlier example. This is true, but the compiler can't do anything with that because of the <em>open world</em> assumption where type classes are involved; your module could, in theory, be imported by another module that defines its own instance, e.g.:</p> <pre><code>instance C Bool where type A Bool = [String] </code></pre> <p>Silly? Yes. Valid code? Also yes.</p> <p>In many cases, the use of constructors in Haskell serves to create <em>trivially injective functions</em>: The constructor introduces a new entity that is defined only and uniquely by the arguments it's given, making it simple to recover the original values. This is precisely the difference between the two versions of your code; the data family makes the type function invertible by defining a new, distinct type for each argument.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload