У меня есть ADT, представляющий AST для простого языка:Преобразование нетипизированное AST для простого языка напечатанного в GADT
data UTerm = UTrue
| UFalse
| UIf UTerm UTerm UTerm
| UZero
| USucc UTerm
| UIsZero UTerm
Эта структура данных может представлять недопустимые термины, которые не следуют правилам типа языка, как UIsZero UFalse
, так что я хотел бы использовать GADT что навязывает а-typedness:
{-# LANGUAGE GADTs #-}
data TTerm a where
TTrue :: TTerm Bool
TFalse :: TTerm Bool
TIf :: TTerm Bool -> TTerm a -> TTerm a -> TTerm a
TZero :: TTerm Int
TSucc :: TTerm Int -> TTerm Int
TIsZero :: TTerm Int -> TTerm Bool
Моя проблема заключается в тип проверки UTerm и превратить его в Tterm. Мой первый мысль была UTerm -> Maybe (TTerm a)
, но это, конечно, не работает, потому что недействителен для всех a
s. Я даже не знаю, какой будет тип, потому что мы не знаем, будет ли a
Int или Bool. Тогда я думал, что я мог бы написать другой функции проверки типа для каждого из возможных значений a
:
import Control.Applicative
typecheckbool :: UTerm -> Maybe (TTerm Bool)
typecheckbool UTrue = Just TTrue
typecheckbool UFalse = Just TFalse
typecheckbool (UIsZero a) = TIsZero <$> typecheckint a
typecheckbool _ = Nothing
typecheckint :: UTerm -> Maybe (TTerm Int)
typecheckint UZero = Just TZero
typecheckint (USucc a) = TSucc <$> typecheckint a
typecheckint (UIf a b c) = TIf <$> typecheckbool a <*> typecheckint b <*> typecheckint c
typecheckint UTrue = Nothing
typecheckint UFalse = Nothing
typecheckint (UIsZero _) = Nothing
Это работает для некоторых случаев, для подмножества языка, где TIF требует его следствия и альтернативы являются Ints (Но TIf TTrue TFalse TTrue
на самом деле полностью действителен), и где мы знаем тип цели выражения, мы печатаем .
Какой способ конвертировать из UTerm в TTerm?
Кстати, вы, безусловно, можете добавить случай 'typecheckbool (UIf a b c)', чтобы обратиться к теме «Но TIf TTrue TFalse TTrue» на самом деле абсолютно справедливо ». –