Я пытаюсь написать код для имитации случайных переменных и хочу, чтобы все было максимально полиморфно. Это может включать использование семейств шрифтов, которые для меня совершенно новые.
Вот упрощенная версия моего кода:
{-# 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
.
Любая помощь высоко ценится!
JointDist
. Тем не менее, здесь есть несколько запахов кода, которые заставляют меня думать, что гораздо более простой дизайн оправдан. Возможно, можно было бы дать лучший совет, если бы вы могли ответить на вопрос: существует ли экземплярJointDist
, который не изоморфенTrivialDist
(и если да, то как он выглядит)? - person Daniel Wagner   schedule 16.02.2019