LINUX.ORG.RU

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

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

Вот тебе неявное приведение:

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DefaultSignatures #-}

type family Wider a b where
  Wider a a = a
  Wider Int Double = Double
  Wider Int Integer = Integer
  Wider a b = Wider b a

class Convert a b where
  convert :: a -> b
  default convert :: (Integral a, Num b) => a -> b
  convert = fromIntegral

instance Convert a a where
  convert = id

instance Convert Int Double

(^+) :: (Num (Wider a b), Convert a (Wider a b), Convert b (Wider a b)) => a -> b -> Wider a b 
a ^+ b = convert a + convert b
*Main> (1 :: Int) ^+ (7:: Double)
8.0

с кодом играйся осторожнее, т.к. семейство типов тут рекурсивное.

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

Вот тебе неявное приведение:

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DefaultSignatures #-}

type family Wider a b where
  Wider a a = a
  Wider Int Double = Double
  Wider Int Integer = Integer
  Wider a b = Wider b a

class Convert a b where
  convert :: a -> b
  default convert :: (Integral a, Num b) => a -> b
  convert = fromIntegral

instance Convert a a where
  convert = id

instance Convert Int Double where
  convert = fromIntegral

(^+) :: (Num (Wider a b), Convert a (Wider a b), Convert b (Wider a b)) => a -> b -> Wider a b 
a ^+ b = convert a + convert b
*Main> (1 :: Int) ^+ (7:: Double)
8.0

с кодом играйся осторожнее, т.к. семейство типов тут рекурсивное.

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

Вот тебе неявное приведение:

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DefaultSignatures #-}

import Data.Function

type family Wider a b where
  Wider a a = a
  Wider Int Double = Double
  Wider Int Integer = Integer
  Wider a b = Wider b a

class Convert a b where
  convert :: a -> b
  default convert :: (Integral a, Num b) => a -> b
  convert = fromIntegral

instance Convert a a where
  convert = id

instance Convert Int Double where
  convert = fromIntegral

(^+) :: (Num (Wider a b), Convert a (Wider a b), Convert b (Wider a b)) => a -> b -> Wider a b 
a ^+ b = convert a + convert b
*Main> (1 :: Int) ^+ (7:: Double)
8.0

с кодом играйся осторожнее, т.к. семейство типов тут рекурсивное.