Следующая программа типа проверок и составляет:Оценка в AST (как GADT) со стрелками, как атомарные значения
import Control.Arrow
data Ns = Na | Nb | Nc | Nd deriving Show
data Net a where
Uni :: a -> Net a
Serial :: Net a -> Net a -> Net a
Branch :: Show a => Net a -> Net (Net a, Net a)
deriving instance Show a => Show (Net a)
eval :: (Arrow a) => Net c -> a b (Net c)
eval (Uni m) = arr (const (Uni m))
eval (Serial m n) = eval m >>> eval n
--eval (Branch m) = eval m &&& eval m
example = Serial (Serial (Uni Na) (Uni Nb)) (Serial (Uni Nc) (Uni Nd))
main = do
putStrLn $ show (app (eval example, Na))
Однако, когда я пытаюсь добавить случай для eval (Branch m)
, тип проверки бомбы вне. Что-то типа
Arrow a => a b (Net d)
ожидается, но, конечно, как у меня есть это
Arrow a => a b (c',c'')
Кто-нибудь есть предложение о том, как писать eval (Branch m)
?
EDIT Я
В ответ на @sabauma замечания, я думаю, тип подписи для eval
будет меняться, но я не уверен, что это должно быть.
EDIT II
Вот пример того, что должно произойти:
branch = Branch example
app (eval branch, Na)
должен дать,
Uni (Uni Na,Uni Na)
Это то, что делает @sabauma «s предложение.
Вы уверены, что опубликованные типы кода? Даже когда последний комментарий был прокомментирован, я все еще получаю ошибку типа, связанную с подписью, которую вы положили на 'eval'. GHC указывает тип 'eval :: Arrow a => Net a -> a (Net a) (Net a)'. – sabauma
@sabauma Я исправил объявление типа для 'eval'. По крайней мере, изменили его на то, как я это сделал, прежде чем пытаться добавить 'eval (Branch m)' – lafras
. Вы должны обязательно добавить некоторые примеры с ожидаемыми результатами или дополнительные объяснения по семантике.Очень сложно догадаться, что именно «eval» должен делать точно, учитывая предоставленную вами информацию. – phg