У меня есть проблема с функцией, которую я хочу сделать очень полиморфной. Я хотел бы интегрировать функции, аналитически или численно. При аналитическом анализе я предоставляю результат. В числовом случае я хотел бы использовать различные методы, на данный момент, процедуру tanhsinh от tanhsinh. Я также хочу узнать больше о гадцах, поэтому я попытался найти решение, используя их.GADT в полиморфной функции
До сих пор у меня есть следующий:
import qualified Data.VectorSpace as DV
import Numeric.Integration.TanhSinh
data IntegrationType a b where
MkAnalytic :: (DV.AdditiveGroup b) => (c -> b) -> c -> c -> IntegrationType Analytic b
MkNumeric :: NumericType -> IntegrationType Numeric [Result]
data Analytic = Analytic
data Numeric = Numeric
data Method = Trapez | Simpson
data IntBounds = Closed | NegInfPosInf | ZeroInf
data NumericType = MkSingleCoreTanhSinh IntBounds Method (Double -> Double) Double Double
| MkParallelTanhSinhExplicit IntBounds (Strategy [Double]) Method (Double -> Double) Double Double
| MkParallelTanhSinh IntBounds Method (Double -> Double) Double Double
integrate :: IntegrationType a b -> b
integrate (MkAnalytic f l h) = f h DV.^-^ f l
integrate (MkNumeric (MkSingleCoreTanhSinh Closed Trapez f l h)) = trap f l h
integrate (MkNumeric (MkSingleCoreTanhSinh Closed Simpson f l h)) = simpson f l h
Этот код компилируется, потому что я expicitly состояние в конструкторе MkNumeric, что переменные б типа
[Result]
Почему я должен это сделать ? Могу ли я не оставить переменный тип б, как в
data IntegrationType a b where
MkNumeric :: NumericType -> IntegrationType Numeric b
Когда я делаю это я получаю сообщение об ошибке:
Could not deduce (b ~ [Result]) from the context (a ~ Numeric) bound by a pattern with constructor MkNumeric :: forall b. NumericType -> IntegrationType Numeric b, in an equation for `integrate' at test-classes-new-programm.hs:139:12-64 `b' is a rigid type variable bound by the type signature for integrate :: IntegrationType a b -> b at test-classes-new-programm.hs:137:14 Relevant bindings include integrate :: IntegrationType a b -> b (bound at test-classes-new-programm.hs:138:1) In the expression: trap f l h In an equation for `integrate': integrate (MkNumeric (MkSingleCoreTanhSinh Closed Trapez f l h)) = trap f l h
Хорошо, я могу это понять. Но что, если я хочу не только вернуть «[Результат]», но, возможно, также пару таких результатов, как «([Результат], [Результат])». В принципе, я хочу иметь возможность возвращать набор типов с помощью моей функции «интегрировать». Это то, что, как я думал, было бы возможным, просто произнеся «MkNumeric :: NumericType -> IntegrationType Numeric b' – TheMADMAN
@TheMADMAN, большой вопрос - это то, что вы можете сделать с результатами после их появления. В полностью зависимом от типизации языке вы можете заставить тип результата зависать произвольными способами по входным значениям, но использование результата требует подтверждения того, что он имеет тип, который вам нужен (этот механизм, по-видимому, полезен в основном для вещей в характере метапрограммирования). В Haskell мы не можем этого сделать; тип результата не может зависеть от входного значения. – dfeuer