Универсальный тип трансформеров в Хаскеле

Логически этоМожно определить универсальную функцию преобразования, которая может преобразовывать из любого типа в любой тип.

Возможный путь:

{-#LANGUAGE MultiParamTypeClasses #-}
{-#LANGUAGE FlexibleInstances #-}

class FromTo a b where
    fromTo:: a->b

instance FromTo a a where fromTo = id

instance FromTo Int     Double where fromTo = fromIntegral
instance FromTo Int     Float  where fromTo = fromIntegral
instance FromTo Integer Double where fromTo = fromIntegral
instance FromTo Integer Float  where fromTo = fromIntegral

instance FromTo Double Int     where fromTo = round 
instance FromTo Double Integer where fromTo = round 
instance FromTo Float  Int     where fromTo = round 
instance FromTo Float  Integer where fromTo = round
-- e.t.c.

Ну, это работаетсидеть'с возможностью расширения. Но это'Это очень громоздко, потому что я должен перечислить любой случай, который я хочу использовать.

Есть ли хорошие решения для этого?

Одно правильное решение можно было бы сделать так, если бы оно было правильным(но это'не)

{-#LANGUAGE MultiParamTypeClasses #-}
{-#LANGUAGE FlexibleInstances #-}
{-#LANGUAGE InstanceSigs #-}

class FromTo a b where
    fromTo:: a->b

instance (Integral a, Num b) => FromTo a b where
    fromTo::a->b
    fromTo x = (fromIntegral x)

{---Commented, because addition breaks program.-------------------------------
instance (RealFrac a, Integral b) => FromTo a b where
    fromTo::a->b
    fromTo x = (round x)
-}

Возможно, это было бы возможно, если бы существовало расширение некоторых наборов типов (псевдокод, подобный Haskell):

{-#LANGUAGE MultiParamTypeClasses #-}
{-#LANGUAGE FlexibleInstances #-}
{-#LANGUAGE InstanceSigs #-}
{-#LANGUAGE TypeSets #-}

class FromTo a b where
    fromTo:: a->b

instance setfrom (Integral a, Num b). (Integral a, Num b) => FromTo a b where
    fromTo::a->b
    fromTo x = (fromIntegral x)

instance setfrom (RealFrac a, Integral b). (RealFrac a, Integral b) => FromTo a b where
    fromTo::a->b
    fromTo x = (round x)

setfrom C1 a. здесь следует определить множество типов, используя информацию об экземплярах изC1 учебный класс. Компилятор должен проверить, пересекаются ли экземпляры. Другая возможная конструкция этого расширенияset (T1,T2,...,TN) a., что позволяет просто определить набор типов.

UPD 1

1-е решение может быть улучшено таким образом (но этонекорректный путь):

{-#LANGUAGE MultiParamTypeClasses #-}
{-#LANGUAGE FlexibleInstances #-}


class FromTo a b where
    fromTo:: a->b

instance FromTo a a where fromTo = id

instance Num b => FromTo Int b where
    fromTo x = fromIntegral x

instance Num b => FromTo Integer b where
    fromTo x = fromIntegral x

instance Integral b => FromTo Float b where
    fromTo x = round x

instance Integral b => FromTo Double b where
    fromTo x = round x

Но это'все еще не хорошо и, кроме того,дает совпадения при звонке в интерактивном режиме:

*Main> fromTo (10::Double) ::Double

:108:1:
    Overlapping instances for FromTo Double Double
      arising from a use of `fromTo'
    Matching instances:
      instance FromTo a a -- Defined at 4.hs:8:10
      instance Integral b => FromTo Double b -- Defined at 4.hs:19:10
    In the expression: fromTo (10 :: Double) :: Double
    In an equation for `it': it = fromTo (10 :: Double) :: Double

Ответы на вопрос(2)

Ваш ответ на вопрос