Code explanation
I'm a beginner, I'd like someone to help me understand a few lines of code
My questions are:
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?
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]
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
.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.
Maybe String
is a type that indicates the value may be aString
, or it may beNothing
. In C, this is kind of like having a string, but giving anull
instead - except in Haskell, the information is put in the type, and if you omitted theMaybe
, you would not be allowed to useNothing
. There is a better explanation at Wikibooks.- 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
Char
s (a String), and the second is a list of 2-tuples of aChar
and aMaybe String
. The last "argument" is really the return type. Look up currying for more information. - No, that is a possibly invalid definition of the function (depending on the type of
terminalRules
andvarRules
). For that matter,t
andp
aren't even used in your definition; it isterminalRules
andvarRules
being used instead. (++)
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 P
s). The function then returns something of type [Delta]
(or a list of Delta
s). T
is a list of Char
s, 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
精彩评论