2016-09-22 4 views
1

Я новичок в Haskell, я искал ответ на нижеследующий, но не повезло.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)) 

Я понимаю, что есть более простые способы сделать выше, но я просто тестирования различных видов использования пользовательские типы данных.

Update:

Моя склонность является то, что компилятор не нравится 'exampleFunction :: Характеристики A B C', потому что его не типобезопасен. то есть я не гарантирую: a == Имя строки, b == Возраст, c == Высота Int.

ответ

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 S здесь; простых псевдонимов типа может быть достаточно.

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 
+0

Спасибо, я просто обновил свой вопрос в то же время с почти так: р –

2

Попробуйте это:

exampleFunction :: Characteristics String Int Int -> User 
exampleFunction (Characteristics a b c) = (Person (Name a) (Age b) (Height c)) 

Причина это работает, и у вас нет, что имя, возраст и высота требуют определенных типов, где ваш пример функции взяли полностью общие аргументы.

A, b и c в этой строке вашего примера определяют тип аргументов, а не их имя.

exampleFunction :: Characteristics a b c 
+0

Это не объясняет ошибку, просто хлопает вниз компилятор :-) – jarandaf

+0

добавлены некоторые пояснения –

Смежные вопросы