Я пытаюсь написать код для имитации случайных величин, и я хочу, чтобы все было как можно более полиморфным.Это может включать использование семейств типов, которые являются совершенно новыми для меня.
Вот упрощенная версия моего кода:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
data TrivialDist a = Trivial a
getVal :: TrivialDist a -> a
getVal (Trivial x) = x
class JointDist d a where
toTrivialDist :: d a -> TrivialDist [a]
data TrivialJointDist a = TrivialJoint [a]
instance JointDist TrivialJointDist a where
toTrivialDist :: TrivialJointDist a -> TrivialDist [a]
toTrivialDist (TrivialJoint xs) = Trivial xs
class Simulable s a where
type Samp s a :: *
-- generates infinite stream of random samples from a distribution
samples :: s a -> IO [Samp s a]
-- generates a single random sample from a distribution
sample :: s a -> IO (Samp s a)
sample = fmap head . samples
instance Simulable TrivialDist a where
type Samp TrivialDist a = a
samples :: TrivialDist a -> IO [a]
samples (Trivial x) = return $ repeat x
instance (JointDist d a) => Simulable d a where
type Samp d a = [a]
samples :: d a -> IO [[a]]
samples = samples . toTrivialDist
Когда я загружаю его в ghci, я получаю этоошибка:
test.hs:30:10: error:
Conflicting family instance declarations:
Samp TrivialDist a = a -- Defined at test.hs:30:10
Samp d a = [a] -- Defined at test.hs:40:10
|
30 | type Samp TrivialDist a = a
| ^^^^^^^^^^^^^^^^^^^^^^
Failed, 0 modules loaded.
Эта проблема, похоже, похожа на найденную здесь (объяснение, по-видимому, состоит в том, что GHC не может различить типы на основе ограничений), но решение не былопредлагаемый.
Я могу получить код для компиляции, если я изменю объявление последнего экземпляра на:
instance Simulable TrivialJointDist a where
type Samp TrivialJointDist a = [a]
samples :: TrivialJointDist a -> IO [[a]]
samples = samples . toTrivialDist
Однако тогда я потеряю преимущество полиморфизма, так как мне нужно было бы сделать отдельныйобъявления экземпляров для каждого подтипа JointDist d a
.
Любая помощь очень ценится!