2013-10-15 3 views
8

У меня есть следующий кодGHC жалуется, не исчерпывающих моделей, которые навязываются типа проверки

{-# LANGUAGE DataKinds, GADTs, TypeOperators #-} 

data Vect v a where 
    Nil :: Vect '[] a 
    Vec :: a -> Vect v a -> Vect (() ': v) a 

instance Eq a => Eq (Vect v a) where 
    (==) Nil Nil    = True 
    (Vec e0 v0) == (Vec e1 v1) = e0 == e1 && v0 == v1 

При компиляции или интерпретации с -Wall следующее предупреждение Дано:

Pattern match(es) are non-exhaustive 
In an equation for `==': 
    Patterns not matched: 
     Nil (Vec _ _) 
     (Vec _ _) Nil 

Обычно это следует ожидать. Обычно даже если я могу рассуждать о том, что мои шаблоны будут охватывать все возможные случаи, компилятор не знает, что без запуска кода. Однако исчерпываемость предоставленных шаблонов обеспечивается проверкой типа, которая выполняется во время компиляции. Добавление моделей, предложенных GHC дает время компиляции ошибки времени:

Couldn't match type '[] * with `(':) *() v1' 

Так что мой вопрос заключается в следующем: не GHC предупреждения просто не хорошо играть с расширениями GHC? Они должны знать друг друга? Является ли эта функциональность (предупреждения с учетом расширений) намеченной для будущей версии или есть некоторые технические ограничения для реализации этой функции?

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

+0

Почему вы не можете просто добавить '(==) _ _ = False'? – Satvik

+0

@ Сатвик: На самом деле это не так - это невозможно, и в некоторых случаях вы не сможете получить значение из ниоткуда (и вам не обязательно придумывать его в любом случае). – shachaf

+0

@shachaf Вы пытаетесь сказать, что только значение типа 'Vector '[] a' является' Nil'? Как насчет неопределенного? – Satvik

ответ

6

Это похоже на ошибку - вот немного простой вариант:

data Foo :: Bool -> * where 
    A :: Foo False 
    B :: Foo True 

hmm :: Foo b -> Foo b -> Bool 
hmm A A = False 
hmm B B = True 

Это также выглядит как это известная ошибка, или часть семьи известных ошибок - ближайший я мог бы найти в Несколько минут просмотра было #3927.

+0

Я думал, что это проблема с 'DataKinds'. Похоже, вам даже не нужна «DataKinds», чтобы иметь эту проблему, она вызвана исключительно «GADTs». – user2407038

+0

Да, это гораздо более общая проблема. – shachaf

+2

Я считаю, что http://ghc.haskell.org/trac/ghc/ticket/595 является основным билетом для этого. –