
Hi all. I want to create the following polymorphic type (EnvItem) that we can apply two functions (envKey and envValue). I tried the following:
type Key = String
data EnvItem a = EnvItem (Key, a)
envKey :: EnvItem (Key, a) -> String envKey EnvItem (key, value) = key
envValue :: EnvValue(Key, a) -> a envValue EnvItem (key, value) = value
But this is resulting in the error: [Constructor "EnvItem" must have exactly 1 argument in pattern] I think this is a very basic problem, but I don't know what is wrong. Regards, Rodrigo.

On Aug 17, 2007, at 9:11 , rodrigo.bonifacio wrote:
envKey :: EnvItem (Key, a) -> String envKey EnvItem (key, value) = key
envValue :: EnvValue(Key, a) -> a envValue EnvItem (key, value) = value
But this is resulting in the error: [Constructor "EnvItem" must have exactly 1 argument in pattern]
You need to parenthesize the constructor. envValue (EnvItem (_,value)) = value (The _ indicates that you're not using that item, rather than giving it a name that won't be used.) Why do you need to do this? Because you can pass functions around, and a constructor is a function. But your type says you don't want a bare function there, so the compiler complains. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On 8/17/07, rodrigo.bonifacio
Hi all.
I want to create the following polymorphic type (EnvItem) that we can apply two functions (envKey and envValue). I tried the following:
type Key = String
data EnvItem a = EnvItem (Key, a)
envKey :: EnvItem (Key, a) -> String envKey EnvItem (key, value) = key
envValue :: EnvValue(Key, a) -> a envValue EnvItem (key, value) = value
But this is resulting in the error: [Constructor "EnvItem" must have exactly 1 argument in pattern]
I think this is a very basic problem, but I don't know what is wrong.
Regards,
Rodrigo.
By the way, I would suggest giving the data type and constructor different names: data EnvItem a = EI (Key, a) You do often see people use the same name for both, but that can be confusing since they are really two different things. The envKey function (for example) would now be written like this: envKey :: EnvItem a -> Key envKey (EI (key, _)) = key The difference between the parameter type (EnvItem a) and a pattern to match the shape of such a value (EI (key, _)) is now much clearer: whatever is on the left side of the data declaration is the type, and goes in type signatures; whatever is on the right side describes the shape of values of that type, and is used to construct or deconstruct (through pattern-matching) such values. This way it is much harder to make mistakes like (for example) putting EnvItem (Key, a) in the type signature instead of EnvItem a. -Brent

On 8/17/07, rodrigo.bonifacio
Hi all.
I want to create the following polymorphic type (EnvItem) that we can apply two functions (envKey and envValue). I tried the following:
type Key = String
data EnvItem a = EnvItem (Key, a)
envKey :: EnvItem (Key, a) -> String envKey EnvItem (key, value) = key
envValue :: EnvValue(Key, a) -> a envValue EnvItem (key, value) = value
But this is resulting in the error: [Constructor "EnvItem" must have exactly 1 argument in pattern]
I think this is a very basic problem, but I don't know what is wrong.
Regards,
Rodrigo.
In addition to what others have already said, I'd like to point out that you do not really need a tuple in your data item.
data EnvItem a = EI Key a
envKey :: EnvItem a -> Key envKey (EI key _) = key
envValue :: EnvValue a -> a envValue (EI _ value) = value
Also, you made a distinction between 'Key' and 'String', which is good. But then in 'envKey', you used 'String' in the signature instead of 'Key'.That's a little confusing, and also should you ever want to change the representation of 'Key', you would then have to change the signature of envKey. Just my two cents, Bryan
participants (4)
-
Brandon S. Allbery KF8NH
-
Brent Yorgey
-
Bryan Burgers
-
rodrigo.bonifacio