Reputation: 2967
I'm new to Haskell, I've looked around for an answer to the below but had no luck.
Why doesn't this code compile?
newtype Name = Name String deriving (Show, Read)
newtype Age = Age Int deriving (Show, Read)
newtype Height = Height Int deriving (Show, Read)
data User = Person Name Age Height deriving (Show, Read)
data Characteristics a b c = Characteristics a b c
exampleFunction :: Characteristics a b c -> User
exampleFunction (Characteristics a b c) = (Person (Name a) (Age b) (Height c))
Error:
"Couldn't match expected type ‘String’ with actual type ‘a’,‘a’ is a rigid type, variable bound by the type signature"
However, this compiles just fine:
exampleFunction :: String -> Int -> Int -> User
exampleFunction a b c = (Person (Name a) (Age b) (Height c))
I realize there's simpler ways of doing the above, but I'm just testing the different uses of custom data types.
Update:
My inclination is that the compiler doesn't like 'exampleFunction ::Characteristics a b c' because its not type safe. i.e. I'm providing no guarantee of: a == Name String, b == Age Int, c == Height Int.
Upvotes: 1
Views: 1593
Reputation: 532538
exampleFunction
is too general. You are claiming it can take a Characteristics a b c
value for any types a
, b
, and c
. However, the value of type a
is passed to Name
, which can only take a value of type String
. The solution is to be specific about what types the characteristics can actually be.
exampleFunction :: Characteristics String Int Int -> User
exampleFunction (Characteristics a b c) = (Person (Name a) (Age b) (Height c))
Consider, though, that you may not even need newtype
s here; simple type aliases may suffice.
type Name = String
type Age = Int
type Height = Int
type Characteristics = (,,)
exampleFunction :: Characteristics Name Age Height -> User
exampleFunction (Charatersics n a h) = Person n a h
Upvotes: 6
Reputation: 3093
Try this:
exampleFunction :: Characteristics String Int Int -> User
exampleFunction (Characteristics a b c) = (Person (Name a) (Age b) (Height c))
The reason this works, and yours does not, is that Name, Age and Height require specific types where your example function took completely generic arguments.
The a,b and c in this line of your example defines the type of the arguments, not the name of them.
exampleFunction :: Characteristics a b c
Upvotes: 2