Мне нужно установить порядок между * -> * типами на основе того, что каждый член одного типа может быть представлен другим. Это гомоморфизм.
Проблема в том, что я могу определить транзитивность отношения !<=!, но программа проверки типов не может этого понять. Это также очень неоднозначно, Identity !<=! Maybe может быть получено из Identity !<=! Maybe или Identity !<=! Identity !<=! Maybe, ... Каждое производное имеет другое (но эквивалентное) определение для repr.
Поэтому я ищу другие способы создать рефлексивные и транзитивные отношения.
{-# LANGUAGE ScopedTypeVariables, TypeOperators, MultiParamTypeClasses, FlexibleInstances, UndecidableInstances, AllowAmbiguousTypes, OverlappingInstances #-}
import Control.Monad.Identity
import Data.Maybe
class x !<=! y where
repr :: x a -> y a
instance x !<=! x where
repr = id
instance Identity !<=! Maybe where
repr = return . runIdentity
instance Maybe !<=! [] where
repr = maybeToList
instance (x !<=! y, y !<=! z) => x !<=! z where
repr = r2 . r1
where r1 :: x a -> y a
r1 = repr
r2 :: y a -> z a
r2 = repr
примечание: я пробовал это на GHC 7.8. Возможно, вам придется удалить AllowAmbiguousTypes.
Изменить: я хотел бы сделать что-то вроде repr (Identity 3 :: Identity Int) :: [Int]
Context reduction stack overflow; size = 21- person Boldizsár Németh   schedule 16.07.2014A <= B,A <= A <= BилиA <= A <= A <= ... <= Bдают один и тот же результат? Вы можете легко определить экземплярT <= Tдля некоторогоT, чтобыT <= T <= TиT <= Tфактически производили разные функции. Вы можете сделать что-то с функциями типов, в которых вы берете список отношений и пытаетесь создать целевое отношение. Или вы можете сделать так, чтобы функцияreprпринимала аргумент, определяющий путь. Но это не может произойти автоматически (волшебным образом). - person user2407038   schedule 16.07.2014UndecidableInstancesдляinstance x !<=! x where. Может еще нужныFlexibleInstances,OverlappingInstances,IncoherentInstances. - person viorior   schedule 16.07.2014