Я получаю конфликтующую ошибку экземпляра семейства, которую я не совсем понимаю:
data DNum n = DNumAdd n | DNumSub n
instance Num n => V n where
type D n = DNum n
-- ...
data DList a = DListUpdate Int a | DListCons a
instance V [a] where
type D [a] = DList a
-- ...
Результаты
Conflicting family instance declarations:
D n = DNum n -- Defined at /Users/gmt/tmi/src/Tmi.hs:16:8
D [a] = DList a -- Defined at /Users/gmt/tmi/src/Tmi.hs:22:8
n
не являются более общими, чем [a]
из-за ограничения Num n
в заголовке экземпляра. Это не кажется мне противоречивым. Проблема в том, что позже может возникнуть конфликт, если я реализую Num
для [a]
? Если это так, разве этот потенциальный конфликт не существует для каких-либо двух экземпляров?
Позволят ли функциональные зависимости так, как это не делают семейства типов?
Полный код ниже:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Tmi
( tmiMain ) where
import Util
class V v where
type D v
(.+) :: v -> D v -> v
data DNum n = DNumAdd n | DNumSub n
instance Num n => V n where
type D n = DNum n
x .+ (DNumAdd dx) = x + dx
x .+ (DNumSub dx) = x - dx
data DList a = DListUpdate Int a | DListCons a
instance V [a] where
type D [a] = DList a
xs .+ (DListUpdate i x) = replaceAt i x
where replaceAt i x xs = take i xs ++ [x] ++ drop (i+1) xs
xs .+ (DListCons x) = x : xs
tmiMain = do
msp $ 3 .+ (DNumAdd 12)
msp $ [1, 2, 3] .+ (DListUpdate 1 20)
msp $ [1, 2, 3] .+ (DListCons 10)