2016-10-05 3 views
-2

У меня есть тип фантом:Как сравнить экземпляры фантомного типа относительно аргумента фантомного типа?

newtype MyType a = {getSth :: SthType} 

Как я могу сравнить MyType a1 и MyType a2 относительно результата a1 и a2 сравнения, то есть, если a1 < a2 затем MyType a1 < MyType a2?

+0

Ваш 'newtype' не является синтаксически правильным. При этом «a1 a -> a -> Bool'. Что вы на самом деле хотите сделать? – Zeta

ответ

2

44. Сравнение классов стандартного класса Eq и Ord требует, чтобы оба сравниваемых значения имели одинаковый тип (включая параметр фантомного типа), вам нужно либо определить собственные операторы сравнения, либо использовать экзистенциальную оболочку. Например:

{-# LANGUAGE ExistentialQuantification #-} 

newtype MyType a = MyType { getInt :: Int } 

data SomeType = forall a . SomeType (MyType a) 

instance Eq SomeType where 
    (SomeType (MyType a)) == (SomeType (MyType b)) = a == b 

instance Ord SomeType where 
    compare (SomeType (MyType a)) (SomeType (MyType b)) = compare a b 

test = SomeType a < SomeType b where 
    a :: MyType Char 
    a = MyType 10 

    b :: MyType Float 
    b = MyType 15 

Другой вариант заключается в использовании Data.Coerce, который позволяет использовать стандартные функции сравнения без написания каких-либо экземпляров шаблонных. Вам просто нужно предоставить некоторые явные сигнатуры типа:

import Data.Coerce 

test2 :: Bool 
test2 = coerce ((<) :: Int -> Int -> Bool) a b where 
    a :: MyType Char 
    a = MyType 10 

    b :: MyType Float 
    b = MyType 15 
+0

Шан, спасибо! – user2466068

+0

Собственно, это не отвечает на оригинальный вопрос. Первоначальная цель - сравнить как-то «x :: MyType a» с «y :: MyType b» типами 'a' и' b' сначала, а только тогда значениями 'getInt x' и' getInt y'. Вы просто реализовали сравнение значений объектов разных типов. Но сравнение не лексикографически по отношению к типам. – Shersh

Смежные вопросы