Я пытаюсь представить выражения с помощью семейств типов, но, похоже, не могу понять, как написать ограничения, которые мне нужны, и я начинаю чувствовать, что это просто невозможно. Вот мой код:
class Evaluable c where
type Return c :: *
evaluate :: c -> Return c
data Negate n = Negate n
instance (Evaluable n, Return n ~ Int) => Evaluable (Negate n) where
type Return (Negate n) = Return n
evaluate (Negate n) = negate (evaluate n)
Все это хорошо компилируется, но не выражает в точности того, что я хочу. В ограничениях Negate
экземпляра Evaluable
я говорю, что возвращаемый тип выражения внутри Negate
должен быть Int
(с Return n ~ Int
), чтобы я мог вызвать отрицание для него, но это слишком ограничительно. На самом деле возвращаемый тип должен быть только экземпляром класса типа Num
, который имеет функцию negate
. Таким образом, Double
s, Integer
s или любой другой экземпляр Num
также может быть инвертирован, а не только Int
s. Но я не могу просто написать
Return n ~ Num
вместо этого, потому что Num
- это класс типа, а Return n
- это тип. Я тоже не могу поставить
Num (Return n)
вместо этого, потому что Return n
- это тип, а не переменная типа.
Возможно ли то, что я пытаюсь сделать с Haskell? Если нет, так должно быть, или я неправильно понимаю какую-то теорию, стоящую за этим? Я чувствую, что Java могла бы добавить подобное ограничение. Дайте мне знать, если этот вопрос будет более ясным.
Изменить: Спасибо, ребята, ответы помогают и достигают того, о чем я подозревал. Похоже, что средство проверки типов не может справиться с тем, что я хотел бы сделать без UndecidableInstances, поэтому мой вопрос: действительно ли то, что я хотел бы выразить, действительно неразрешимо? Это для компилятора Haskell, но так ли вообще? т.е. может ли вообще существовать ограничение, которое означает «проверьте, что Return n является экземпляром Num», которое разрешается более продвинутой проверкой типов?
FlexibleContexts
или что-то еще в процессе проб и ошибок? потому что я совершенно уверен, что это так - небольшое примечание по возможно ли это даже с битом Haskell. - person Erik Kaplun   schedule 07.10.2015