Здесь сценарий: я написал код с сигнатурой типа, и жалобы GHC не смогли вывести x ~ y для некоторых x
и y
. Обычно вы можете бросить GHC в кость и просто добавить изоморфизм к функциональным ограничениям, но это плохая идея по нескольким причинам:
- Он не подчеркивает понимание кода.
- В результате вы можете ограничить 5 ограничениями, которых было бы достаточно (например, если 5 подразумевается еще одним конкретным ограничением)
- Вы можете в конечном итоге с фиктивными ограничениями, если вы сделали что-то неправильно или если GHC бесполезен
Я просто провел несколько часов, сражаясь с футляром 3. Я играю с syntactic-2.0
, и я пытался определить независимую от домена версия share
, похожая на версию, определенную в NanoFeldspar.hs
.
У меня было это:
{-# 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
и GHC could not deduce (Internal a) ~ (Internal b)
, что, конечно же, не то, что я собирался сделать. Так что либо я написал код, который я не собирался (который требовал ограничения), либо GHC хотел этого ограничения из-за некоторых других ограничений, которые я написал.
Оказывается, мне нужно добавить (Syntactic a, Syntactic b, Syntactic (a->b))
в список ограничений, ни один из которых не подразумевает (Internal a) ~ (Internal b)
. Я в основном наткнулся на правильные ограничения; У меня до сих пор нет систематического способа найти их.
Мои вопросы:
- Почему GHC предложила это ограничение? Нигде в синтаксисе есть ограничение
Internal a ~ Internal b
, поэтому, где GHC вытащил это из? - В целом, какие методы можно использовать для отслеживания происхождения ограничения, которое, по мнению GHC, ему необходимо? Даже для ограничений, которые я могу обнаружить сам, мой подход по сути грубым, заставляя оскорбительный путь, физически записывая рекурсивные ограничения. Этот подход в основном сводится к бесконечной кроличьей дыре ограничений и представляет собой наименее эффективный метод, который я могу себе представить.