2017-02-08 24 views
1

Предисловие: обучение ATS с веб-сайта ATS.Разрешение ошибки типа ATS

При попытке вытащить запись из списка, как только я попытаюсь ссылаться на переменную записи, я получаю ошибку типа на x4.a ниже.

Так почему же это не удается - х4 не знает, что у него есть запись?

typedef 
abc1_rec = '{a=int, b=int, c=char} 
typedef 
abc2_rec = '{a=int, b=char, c=string} 

val x1 = '{a=1,b=3,c='A'} : abc1_rec  // boxed record 
val x2 = '{a=1,b='B',c="CAT"} : abc2_rec // boxed record 
val a1 = x2.a        // =1 
val x3 = (x2 :: x1 :: list_nil())   // concat list x2 + x1 + nil 
val x4 = x3.head()       // record x2 

val x5 = x4.a  // error - [a] cannot be found 

/TMP/patsopt_tcats_lu0auT: 1440 (линия = 77, офф = 12) - 1442 (линия = 77, офф = 14): ошибка (3): [а] не может быть найдено: тип [S2EVar (779)] равен , который должен быть тирек (запись). patsopt (TRANS3): есть ошибки [1] . Выход (АТС): неперехваченное исключение: _2home_2hwxi_2Research_2ATS_2dPostiats_2src_2pats_error_2esats__FatalErrorExn (1025)

ответ

1

Примечание x1 и x2 имеют различные типы. Их нельзя поместить в тот же список . В этом случае тип для x3 представляет собой список (X, 2) для некоторого T, который считается подтепом как abc1_rec, так и abc2_rec; x4 имеет тип T, а x4.a дает вам ошибку типа, потому что typechecker не может сделать вывод о том, что T является типом записи.

+0

Для этого вы можете просто написать 'val x3 = $ list {abs1_rec} (x2, x1)' –

+0

Или вы можете написать 'val x3 = list_cons (x2, list_cons (x1, list_nil {abs1_rec}())' –

+0

Спасибо, что помогает. Если я использую один и тот же тип «abc1_rec», то val x3 = (x2 :: x1 :: list_nil()) дает мне список (abc1_rec, 2)? Where :: redefining list_cons. – Pezhead9000