У меня есть следующая ошибка для cadr1
ниже, что имеет смысл
Не удалось вывести (BoolEq n ('Succ ('Succ n'0)) ~ 'True)
из контекста (BoolEq n ('Succ ('Succ n')) ~ 'True)
Переменная типа «n'0» неоднозначна
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
module DecidablePropositionalEquality where
data Nat = Zero | Succ Nat
data Vec :: * -> Nat -> * where
VNil :: Vec a Zero
VCons :: a -> Vec a n -> Vec a (Succ n)
type family Greater (a:: Nat) (b:: Nat) :: Bool where
Greater Zero Zero = True
Greater Zero (Succ x) = False
Greater (Succ x) Zero = True
Greater (Succ a) (Succ b) = Greater a b
op :: forall a n n'. (Greater n (Succ (Succ n')) ~ True) => Vec a n -> a
op v = undefined
Я не использую n'
на сайте определения, так что это неоднозначно.
Могу ли я в любом случае дать экзистенциальную количественную оценку этому n'
, чтобы ghc не пытался присвоить его какому-либо типу и потерпел неудачу, поскольку ничто не связывает его ни с чем?
В более общем смысле, как контролировать область действия этих переменных типа?
изменить: изменено для удаления семейства логических типов.
cadr1 :: forall a n'. Vec a (Succ (Succ n')) -> a
? - person chi   schedule 30.06.2017n'
был привязан к этому коду. и так как я не собираюсь ничего из него использовать, само его существование прекрасно. и это не должно быть «двусмысленным», если GHC не пытается присвоить его чему-то, выходящему за рамки его предполагаемой области применения. - person nicolas   schedule 30.06.2017n ~ Succ (Succ n')
— это совершенно хорошее ограничение, и оно не является двусмысленным. - person Benjamin Hodgson♦   schedule 30.06.2017AllowAmbiguousTypes
, параметр типаn'
совершенно бесполезен — типы стираются во время выполнения, поэтому нет абсолютно никакой возможности выполнять вычисления с ним внутри телаop
. Вам нужно ограничение класса типа дляn'
, или синглтон, хранящий его значение, или что-то в этом роде. Вы, вероятно, думаете о чем-то вроде вызова пользователя, например.op @5
и получить параметрическую функцию, которая всегда выдает вектор наименьшей длины7
; но с данным типом вы просто не смогли бы реализовать такую функцию. - person user2407038   schedule 01.07.2017