Исправление определения типа для определения экземпляра Functor

Я пытаюсь определить тип с двумя параметрами i и m. Я хочу специализировать этот тип, исправляя два конкретных экземпляра, которые фиксируют параметр m. На данный момент у меня есть следующие определения:

-- | ZadehMembership: represents a membership value between 0 and 1 with min and max operators
newtype ZadehMembership = Z Double deriving (Show, Eq, Ord, Num)

-- | PAMembership: represents a membership value between 0 and 1 with algebraic sum and product operators
newtype PAMembership = PA Double deriving (Show, Eq, Ord, Num)

-- | FuzzySet type
newtype FuzzySet i m = FS (Map.Map i m) deriving (Eq, Ord)

add :: (Ord i, Eq m, L.BoundedLattice m) => FuzzySet i m -> (i, m) -> FuzzySet i m
add (FS fs) (i, m) = if m == L.bottom then FS fs else FS (Map.insert i m fs)

fromList :: (Ord i, Eq m, L.BoundedLattice m) => [(i, m)] -> FuzzySet i m
fromList = foldl add empty

Я использую определение FuzzySet следующим образом:

let fs = fromList [(1, Z 0.2), (2, Z 0.5)]

Я хочу определить Functor для типа FuzzySet, но у меня есть некоторые ограничения класса, которые должны выполняться для обоих параметров типа i и m, но это невозможно. Есть ли способ улучшить определения типов, чтобы решить эту проблему?

Спасибо.


person escher    schedule 22.01.2016    source источник
comment
Кажется, это разновидность известной проблемы, почему Data.Set.Set не является функтором/монадой?. Краткий ответ: к сожалению, наличие ограничений класса типов справляется со стандартным Functor. Индексированные функторы с ними справиться, я думаю.   -  person chi    schedule 22.01.2016
comment
Я думаю, что индексированные функторы могут быть правильным решением, но как я могу их использовать? Спасибо   -  person escher    schedule 22.01.2016
comment
@chi Вы уверены, что понятие индексированного функтора достаточно интересно? Тип imap :: IxFunctor f => (a -> b) -> f j k a -> f j k b по-прежнему не дает вам дескриптора для навешивания каких-либо ограничений на j, k, a или b. Я думаю, ему нужно что-то вроде RFunctor.   -  person Daniel Wagner    schedule 23.01.2016
comment
@DanielWagner Совсем не уверен. Я надеялся использовать какой-нибудь Constraint-индексированный функтор, возможно, использующий некоторую магию поликиндинга, но IFunctor не такой уж зверь, и моя догадка была дикой. RFunctor может быть действительно рабочим выбором.   -  person chi    schedule 23.01.2016


Ответы (1)


Никто еще этого не говорил, но почему бы просто не использовать производный экземпляр Functor?

{-# LANGUAGE DeriveFunctor #-}
newtype FuzzySet i m = FS (Map.Map i m) deriving (Eq, Ord, Functor)

Вместо того, чтобы накладывать ограничения на тип данных или экземпляр, наложите их на функции, использующие FuzzySet i m, как вы сделали для add. Таким образом, хотя вы сможете создать FuzzySet i x для некоторых x, которые не соответствуют ограничению, вы сможете выполнять полезные операции только с FuzzySet i m там, где m соответствует.

person rampion    schedule 23.01.2016