Haskell fromSing and Sing опечатки / добрые ошибки
Я пытаюсь написать код на Haskell для представления отрицательного биномиального распределения в существующей библиотеке (HLearn). Из того, что я могу сказать, HLearn требует, чтобы параметры модели (в данном случае значение r для отрицательного биномиального распределения) вводились как натуральные числа уровня типа в классе типов, представляющем распределение. Моя проблема в том, что я получаю ошибку, связанную с видом, когда пытаюсь использовать sing для доступа к значению параметра во время выполнения.
Соответствующий код комментируется
-- | Negative binomial distribution
{-# LANGUAGE
GeneralizedNewtypeDeriving,
TypeFamilies,
DataKinds,
KindSignatures #-}
module HLearn.Models.Distributions.Univariate.NegativeBinomial
(NegativeBinomial
)
where
import GHC.TypeLits
import HLearn.Algebra
import HLearn.Models.Distributions.Common
import HLearn.Models.Distributions.Univariate.Internal.Moments
newtype NegativeBinomial (r::Nat) prob dp = NegativeBinomial { moments :: (Moments3 dp) }
deriving (Read, Show, Eq, Ord, Monoid, Group)
instance (Num dp) => HomTrainer (NegativeBinomial r prob dp) where
type Datapoint (NegativeBinomial r prob dp) = dp
train1dp dp = NegativeBinomial $ train1dp dp
instance (Num dp) => Probabilistic (NegativeBinomial r prob dp) where
type Probability (NegativeBinomial r prob dp) = prob
-- The function in question
negbin_p :: (SingI r, Integral dp, Fractional prob) => NegativeBinomial r prob dp -> prob
negbin_p (NegativeBinomial moments) = ((fromIntegral $ m0 moments)/(fromIntegral $ m1 moments)) * rval
where
rval = fromSing (sing :: Sing r) -- This is the code that is reported as causing errors
Я получаю следующие ошибки:
src\HLearn\Models\Distributions\Univariate\NegativeBinomial.hs:33:24:
Could not deduce (SingE * (Kind *) prob)
arising from a use of `fromSing'
from the context (SingI Nat r, Integral dp, Fractional prob)
bound by the type signature for
negbin_p :: (SingI Nat r, Integral dp, Fractional prob) =>
NegativeBinomial r prob dp -> prob
at src\HLearn\Models\Distributions\Univariate\NegativeBinomial.hs:30:13-89
Possible fix:
add an instance declaration for (SingE * (Kind *) prob)
In the expression: fromSing (sing :: Sing r)
In an equation for `rval': rval = fromSing (sing :: Sing r)
In an equation for `negbin_p':
negbin_p (NegativeBinomial moments)
= ((fromIntegral $ m0 moments) / (fromIntegral $ m1 moments))
* rval
where
rval = fromSing (sing :: Sing r)
src\HLearn\Models\Distributions\Univariate\NegativeBinomial.hs:33:34:
Could not deduce (SingI * r1) arising from a use of `sing'
from the context (SingI Nat r, Integral dp, Fractional prob)
bound by the type signature for
negbin_p :: (SingI Nat r, Integral dp, Fractional prob) =>
NegativeBinomial r prob dp -> prob
at src\HLearn\Models\Distributions\Univariate\NegativeBinomial.hs:30:13-89
Possible fix: add an instance declaration for (SingI * r1)
In the first argument of `fromSing', namely `(sing :: Sing r)'
In the expression: fromSing (sing :: Sing r)
In an equation for `rval': rval = fromSing (sing :: Sing r)
Что я делаю неправильно?
1 ответ
Спасибо Luqui за указание на ScopedTypeVariables. После добавления этого к языковой прагме обновленный рабочий код будет таким же, за исключением:
negbin_p :: forall r dp prob . (SingI r, Integral dp, Fractional prob) => NegativeBinomial r prob dp -> prob
negbin_p (NegativeBinomial moments) = ((fromIntegral $ m0 moments)/(fromIntegral $ m1 moments)) * rval
where
rval = fromIntegral $ fromSing (sing :: Sing r)