LINUX.ORG.RU

История изменений

Исправление Miguel, (текущая версия) :

Если появится что-то вроде семейств классов, то можно будет сделать

Да уже можно, причём порядок будет проверяться автоматически:

{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module SubClass where
import GHC.Prim(Constraint)
data Wrapper c where Wrapper :: c a => a -> Wrapper c
cons :: c a => a -> [Wrapper c] -> [Wrapper c]
cons x xs = Wrapper x : xs
deCons :: (forall a. c a => a -> b) -> [Wrapper c] -> Maybe (b, [Wrapper c])
deCons _ [] = Nothing
deCons h (Wrapper x : xs) = Just (h x, xs)
data Void (c :: * -> Constraint) = Void
data Evidence c a where Evidence :: c a => Evidence c a
evidence :: c a => Evidence c a
evidence = Evidence
class c1 :<= c2 where
    isSubClass :: c1 a => Void c1 -> Evidence c2 a
    default isSubClass :: c2 a => Void c1 -> Evidence c2 a
    isSubClass _ = evidence
instance Show :<= Show
instance Floating :<= Fractional
-- instance Fractional :<= Floating -- хрен тебе, а не компиляция
instance (c :<= Show) => Show (Wrapper c) where
    show (Wrapper (a :: t)) = case isSubClass (Void :: Void c) :: Evidence Show t of Evidence -> show a
Увы, без UndecidableInstances я обойтись не сумел.

Исправление Miguel, :

Если появится что-то вроде семейств классов, то можно будет сделать

Да уже можно, причём порядок будет проверяться автоматически:

{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module SubClass where
import GHC.Prim(Constraint)
data Wrapper c where Wrapper :: c a => a -> Wrapper c
cons :: c a => a -> [Wrapper c] -> [Wrapper c]
cons x xs = Wrapper x : xs
deCons :: (forall a. c a => a -> b) -> [Wrapper c] -> Maybe (b, [Wrapper c])
deCons _ [] = Nothing
deCons h (Wrapper x : xs) = Just (h x, xs)
data Void (c :: * -> Constraint) = Void
data Evidence c a where Evidence :: c a => Evidence c a
evidence :: c a => Evidence c a
evidence = Evidence
class c1 :<= c2 where
    isSubClass :: c1 a => Void c1 -> Evidence c2 a
    default isSubClass :: c2 a => Void c1 -> Evidence c2 a
    isSubClass _ = evidence
instance Show :<= Show
instance Floating :<= Fractional
-- instance Fractional :<= Floating -- хрен тебе, а не компиляция
instance (c :<= Show) => Show (Wrapper c) where
    show (Wrapper (a :: t)) = case isSubClass (Void :: Void c) :: Evidence Show t of Evidence -> show a
Увы, без UndecidableInstances я обойтись не сумел.

Исходная версия Miguel, :

Если появится что-то вроде семейств классов, то можно будет сделать

Да уже можно, причём порядок будет проверяться автоматически:

{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module SubClass where
import GHC.Prim(Constraint)
data Wrapper c where Wrapper :: c a => a -> Wrapper c
cons :: c a => a -> [Wrapper c] -> [Wrapper c]
cons x xs = Wrapper x : xs
deCons :: (forall a. c a => a -> b) -> [Wrapper c] -> Maybe (b, [Wrapper c])
deCons _ [] = Nothing
deCons h (Wrapper x : xs) = Just (h x, xs)
data Void (c :: * -> Constraint) = Void
data Evidence c a where Evidence :: c a => Evidence c a
evidence :: c a => Evidence c a
evidence = Evidence
class c1 :<= c2 where
    isSubClass :: c1 a => Void c1 -> Evidence c2 a
    default isSubClass :: c2 a => Void c1 -> Evidence c2 a
    isSubClass _ = evidence
instance Show :<= Show
instance Floating :<= Fractional
-- instance IsSubClass Fractional Floating -- хрен тебе, а не компиляция
instance (c :<= Show) => Show (Wrapper c) where
    show (Wrapper (a :: t)) = case isSubClass (Void :: Void c) :: Evidence Show t of Evidence -> show a
Увы, без UndecidableInstances я обойтись не сумел.