我是Haskell的新手,我已经四处寻找下面的答案,但没有运气。
为什么这段代码不能编译?
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))
错误:
"Couldn't match expected type ‘String’ with actual type ‘a’,‘a’ is a rigid type, variable bound by the type signature"
但是,编译得很好:
exampleFunction :: String -> Int -> Int -> User
exampleFunction a b c = (Person (Name a) (Age b) (Height c))
我意识到上面有更简单的方法,但我只是测试自定义数据类型的不同用途。
更新
我倾向于编译器不喜欢'exampleFunction :: Characteristics a b c',因为它不是类型安全的。即我不保证:a == Name String,b == Age Int,c == Height Int。
答案 0 :(得分:6)
exampleFunction
过于笼统。您声称任何类型Characteristics a b c
,a
和b
可能需要c
值。但是,a
类型的值会传递给Name
,而仅的值为String
。解决方案是具体说明特征的实际类型。
exampleFunction :: Characteristics String Int Int -> User
exampleFunction (Characteristics a b c) = (Person (Name a) (Age b) (Height c))
但请考虑一下,你甚至可能不需要newtype
;简单类型别名就足够了。
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
答案 1 :(得分:2)
试试这个:
exampleFunction :: Characteristics String Int Int -> User
exampleFunction (Characteristics a b c) = (Person (Name a) (Age b) (Height c))
这是有效的,而你的不是,Name,Age和Height需要特定的类型,你的示例函数采用完全通用的参数。
示例的这一行中的a,b和c定义了参数的类型,而不是它们的名称。
exampleFunction :: Characteristics a b c