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)
Другие вопросы по тегам