开发者

Code explanation

I'm a beginner, I'd like someone to help me understand a few lines of code

My questions are:

  1. Maybe String is an application of the constructor Maybe to the type String. What does it mean? Is there anything equivalent in the C language?

  2. Is this a function with three arguments?

    type T = [Char] 
    type P = (Char, Maybe String)
    type D开发者_运维问答elta = ((Maybe Char, Char), Maybe String)
    fromGtoM :: T -> [P] -> [Delta]
    
  3. is this a usage of the above mentioned function?

    fromGtoM t p =  terminalRules ++ varRules 
    

    I don't see why the function has three arguments but then only two are used: t, p.

  4. what does ++ mean ?

Sorry, for posting too many questions.

Thanks in advance.


I will attempt to answer your questions, but you really are better off reading a book/finding a tutorial.

  1. Maybe String is a type that indicates the value may be a String, or it may be Nothing. In C, this is kind of like having a string, but giving a null instead - except in Haskell, the information is put in the type, and if you omitted the Maybe, you would not be allowed to use Nothing. There is a better explanation at Wikibooks.
  2. No, this is a function of 2 arguments, or a function of 1 argument that returns a function of 1 argument. The first argument is a list of Chars (a String), and the second is a list of 2-tuples of a Char and a Maybe String. The last "argument" is really the return type. Look up currying for more information.
  3. No, that is a possibly invalid definition of the function (depending on the type of terminalRules and varRules). For that matter, t and p aren't even used in your definition; it is terminalRules and varRules being used instead.
  4. (++) is the list concatenation operator.


You've received good answers to your other questions, but I think your first question hasn't been fully answered.

Type constructors are something relatively foreign to other programming languages. Templated types in C++ are kind of similar, though they get unwieldy much faster. Also, templated types aren't as expressive. Type constructors are fully first-class. You can create types that are polymorphic in type constructors that will be applied to other values, as well as polymorphic in values applied to a type constructor.

data Maybe a = Nothing
             | Just a

This is approximately the definition of Maybe from the standard libraries. It has two value constructors. The first one, Nothing, takes no arguments. The second one, Just, takes a single argument of the same type as the Maybe is applied to. In haskell, lowercase types are always type variables. So the a in the Just a definition means "the type called a, in this context". In that context, a is defined to be an argument to the data type, since it also appears before the = in the data definition.

Part of Haskell's type system is interesting here. While Maybe is a valid type by itself, it's not a type that can have values. It isn't the right type of type to have values. This is a part of a concept called kinds, which I won't go into further here, but is really helpful for understanding Haskell code eventually.

Now, let's look at a slightly more sophisticated example, showing the difference between polymorphism in different types of types.

data DumbExample1 a = DumbExample1 (Maybe a) [a]

data DumbExample2 f = DumbExample2 (f Int) (f String)

The above dumb examples are definitions of new polymorphic data types. Each one defines a type with a value constructor with the same name as the type - DumbExample1 and DumbExample2. Both value constructors take two arguments, mostly to better illustrate them below.

-- v1 is an example of the polymorphism you can do with templates in C++

-- v1 is a DumbExample1 with the type variable a set to String
v1 :: DumbExample1 String

-- v1 is constructed with the Maybe field containing a string
--    and the list containing two more
v1 = DumbExample1 (Just "foo") ["bar", "baz"]


-- v2 is an example of the polymorphism you cannot easily do with templates in C++
--   (it might be possible to do something equivalent, but it would look a lot clumsier

-- v2 is a DumbExample2 with the type variable f set to Maybe
v2 :: DumExample2 Maybe

-- v2 is construced with the first field containing Just 5, and the second field not
--    containing any String at all
v2 = DumbExample2 (Just 5) Nothing

Haskell's type system is its best feature, by far. This is just barely scratching the surface of what it can do. But I hope this gives you a bit of a taste of why my answer to your first question is essentially "this isn't really a concept any mainstream language has". When you get further into Haskell, you'll discover that polymorphism of type constructors is used heavily to create expressive types.

(It's even used in the oh so terrifyingly named language construction - but actually so simple it takes a while to believe that's all there is to it - the Monad. Don't worry about Monads. They're simpler and less important than you think. Disregard this parenthetical note if the word scares you.)


1) Maybe is a way of saying you don't necessarily need it. You could have Nothing, or you could have Just something. Haskell is a typed language so it doesn't relate 100% to C. In C you could have a char* P = null, but null isn't really a string. In Haskell this would throw an error, because it's expecting a String if you say String. Take a look here for more detailed information: http://haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Data-Maybe.html

2) fromGtoM is a function with two arguments. The first argument is type T and the second is type [P] (or a list of Ps). The function then returns something of type [Delta] (or a list of Deltas). T is a list of Chars, and P is a tuple containing a Char and either Just a String, or Nothing. Finally, Delta is a tuple containing another tuple and a Maybe String. The inner tuple contains a Maybe Char and a Char. You could therefore have something like ((Nothing, 'a'), Just 'bcd') that would satisfy type Delta.

3) This is a definition of the usage of the function. If you call fromGtoM with two variables t and p, you will get terminalRules concatenated with varRules. Out of context it's hard to tell how exactly it's being used.

4) ++ is a list concatenation operator, so terminalRules and varRules are lists, but fromGtoM returns only one list. Here's a list of operators that might come in handy later. http://www.imada.sdu.dk/~rolf/Edu/DM22/F06/haskell-operatorer.pdf

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜