Bir tür imzası ile bazı kodlar yazdım ve GHC bazıları için x ~ y anlamak olamazdı yakınır: İşte senaryo x
ve y
. Genellikle GHC'ye bir kemik atabilir ve fonksiyon kısıtlamalarına izomorfizmi ekleyebilirsiniz, ancak bu birkaç nedenden dolayı kötü bir fikirdir:
- Kodun anlaşılmasını vurgulamaz.
- Birinin yeterli olacağı 5 kısıtlama ile karşılaşabilirsiniz (örneğin, 5'in bir başka kısıtlamayla ima edilmesi halinde)
- Yanlış bir şey yaptıysanız veya GHC yardımcı olmuyorsa sahte kısıtlamalarla karşılaşabilirsiniz.
Vaka 3 ile mücadele etmek için sadece birkaç saat geçirdim syntactic-2.0
ve ile tanımlanan versiyona share
benzer şekilde, alandan bağımsız bir versiyon tanımlamaya çalışıyordum NanoFeldspar.hs
.
Bu vardı:
{-# LANGUAGE GADTs, FlexibleContexts, TypeOperators #-}
import Data.Syntactic
-- Based on NanoFeldspar.hs
data Let a where
Let :: Let (a :-> (a -> b) :-> Full b)
share :: (Let :<: sup,
Domain a ~ sup,
Domain b ~ sup,
SyntacticN (a -> (a -> b) -> b) fi)
=> a -> (a -> b) -> a
share = sugarSym Let
ve GHC could not deduce (Internal a) ~ (Internal b)
, ki bu kesinlikle benim istediğim şey değildi. Yani ya ben (bu kısıtlama gerekli) niyetinde değildi bazı kod yazmıştı, ya da GHC ben yazmıştı diğer bazı kısıtlamalar nedeniyle bu kısıtlama istedi.
(Syntactic a, Syntactic b, Syntactic (a->b))
Kısıtlama listesine eklemem gerektiği ortaya çıktı , hiçbiri ima etmedi (Internal a) ~ (Internal b)
. Temel olarak doğru kısıtlamalarla karşılaştım; Onları bulmak için hala sistematik bir yolum yok.
Sorularım:
- GHC bu kısıtlamayı neden önerdi? Sözdizimsel olarak hiçbir yerde bir kısıtlama yoktur
Internal a ~ Internal b
, öyleyse GHC bunu nereden çekti? - Genel olarak, GHC'nin ihtiyaç duyduğuna inandığı bir kısıtlamanın kökenini izlemek için hangi teknikler kullanılabilir? Hatta kısıtlamaları için bunu yapabilirsiniz kendimi keşfetmek, yaklaşımım esasen fiziksel olarak özyinelemeli kısıtlamaları yazarak kusurlu yolunu zorlayarak kaba edilir. Bu yaklaşım temelde sınırların sonsuz bir tavşan deliğinden aşağı iniyor ve hayal edebileceğim en az verimli yöntemle ilgili.
a
ve b
bağlı - bağlamınızın dışındaki tür imzasına bakın - a -> (a -> b) -> a
değil a -> (a -> b) -> b
. Belki de budur? Kısıt çözücülerle geçişli eşitliği her yerde etkileyebilirler , ancak hatalar genellikle kısıtlamanın indüklendiği yere "yakın" bir konum gösterir. @Jozefg olsa da bu iyi olurdu - belki de nereden geldiğini göstermek için etiketler ya da başka bir şeyle kısıtlamalar ek açıklama? : s