Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <ul> <li>The "Cons" value constructor has a single type parameter.</li> </ul> </blockquote> <p>Nope: you've already parametrized it when you declared <code>data List a</code>. One effective property of this is that if I have a Nil :: List Int, I can't interchange it with a Nil :: List Char.</p> <blockquote> <ul> <li>If you use the "Cons" value constructor, there are 2 fields which must be provided. The first required field is an instance of List. The second required field is an instance of a.</li> </ul> </blockquote> <p>You've got it swapped: the first required field is an instance of a, the second field is an instance of List.</p> <p><a href="http://book.realworldhaskell.org/read/defining-types-streamlining-functions.html" rel="nofollow noreferrer">This chapter of Real World Haskell</a> may be of interest.</p> <blockquote> <p>Thanks. That is the chapter I'm on right now. So ... when the code says "Cons a (List a)", I thought the "Cons a" part of that was stating that the Cons value constructor was parameterised. They haven't yet covered the syntax for parameterised types, so I guessed that the syntax must require re-stating "a" if you intend to use a. But you're saying that's not necessary? And therefore that's not what that "a" means?</p> </blockquote> <p>Nope. Once we declare a parameter in our type, we get to reuse it otherwise to say "that type should be used there." It's a little bit like an <code>a -&gt; b -&gt; a</code> type signature: a is parameterizing the type, but then I have to use the same a as the return value.</p> <blockquote> <p>OK, but this is confusing. It seems that the first "a" means "the first field is an instance of a",</p> </blockquote> <p>Nope, that is <em>not</em> true. It just means that the data type parametrizes over some type a.</p> <blockquote> <p>and it ALSO means "the first field has the same value as the value they passed in for a". In other words, it specifies type AND value.</p> </blockquote> <p>No, that is also not true.</p> <p>Here's an instructive example, the syntax of which you may or may not have seen before:</p> <pre>foo :: Num a => a -> a</pre> <p>This is a fairly standard signature for a function that takes a number and does something to it and gives you another number. What I actually mean by "a number" in Haskell-speak, though, is some arbitrary type "a" that implements the "Num" class.</p> <p>Thus, this parses to the English:</p> <blockquote> <p>Let a indicate a type implementing the Num typeclass, then the signature of this method is one parameter with the type a, and the return value of the type a</p> </blockquote> <p>Something similar happens with data.</p> <p>It also occurs to me that the instance of List in the specification of Cons is also confusing you: be really careful when parsing that: whereas Cons is specifying a constructor, which is basically a pattern that Haskell is going to wrap the data into, (List a) looks like a constructor but is actually simply a type, like Int or Double. a is a type, NOT a value in any sense of the term.</p> <p><strong>Edit:</strong> In response to the most recent edit.</p> <p>I think a dissection is first called for. Then I'll deal with your questions point by point.</p> <p>Haskell data constructors are a little weird, because you define the constructor signature, and you don't have to make any other scaffolding. Datatypes in Haskell don't have any notion of member variable. (Note: there's an alternate syntax that this way of thinking is more amenable to, but let's ignore that for now).</p> <p>Another thing is that Haskell code is dense; its type signature are like that to. So expect to see the same symbol reused in different contexts. Type inferencing also plays a big role here.</p> <p>So, back to your type:</p> <pre>data List a = Cons a (List a) | Nil</pre> <p>I chunk this into several pieces:</p> <pre>data <b>List a</b></pre> <p>This defines the name of the type, and any parameterized types that it will have later on. Note that you will only see this show up in other type signatures.</p> <pre><b>Cons</b> a (List a) | <b>Nil</b></pre> <p>This is the name of the data constructor. <b>This IS NOT a type</b>. We can, however, pattern match for it, ala:</p> <pre>foo :: List a -> Bool foo Nil = True</pre> <p>Notice how List a is the type in the signature, and Nil is both the data constructor and the "thing" we pattern match for.</p> <pre>Cons <b>a (List a)</b></pre> <p>These are the types of the values we slot into the constructor. Cons has two entries, one is of type a, and one is of type List a.</p> <blockquote> <p>So my question is, why does "a" in the first field mean "the type of this field is 'a' and the value of this field is 'a'", while "a" in the second field means only "the type of this field is 'List of a'"?</p> </blockquote> <p>Simple: don't think of it as us specifying the type; think of it has Haskell is inferencing the type out of it. So, for our intents and purposes, we're simply sticking a 0 in there, and a Nil in the second section. Then, Haskell looks at our code and thinks:</p> <ul> <li>Hmm, I wonder what the type of Cons 0 Nil is</li> <li>Well, Cons is a data constructor for List a. I wonder what the type of List a is</li> <li>Well, a is used in the first parameter, so since the first parameter is an Int (another simplification; 0 is actually a weird thing that is typeclassed as Num), so that's mean a is a Num</li> <li>Hey, well, that also means that the type of Nil is List Int, even though there's nothing there that would actually say that</li> </ul> <p>(Note, that's not actually how it's implemented. Haskell can do a lot of weird things while inferencing types, which is partially why the error messages suck.)</p>
    singulars
    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