`[<<][meta][>>][..]`
Sat Jul 23 15:08:45 CEST 2011

## General -> concrete type?

```I'm trying to express something that doesn't seem to be possible
without special tricks.  Questions: 1. what exactly goes wrong and
2. do I need this?

-- Expr with type annotation and type conversions.
data TExpr = Tfloat {teFloat :: Expr Double}
| Tint   {teInt   :: Expr Integer}
| Tbool  {teBool  :: Expr Bool}
deriving Show

teLift1 :: (Expr a -> Expr a) -> (TExpr -> TExpr)

teLift1 f = l where
l :: TExpr -> TExpr
l (Tfloat x) = Tfloat (f x)
l (Tint x)   = Tint   (f x)
l (Tbool x)  = Tbool  (f x)
l _ = error "teLift1: Type not supported"

The error is:

Couldn't match expected type `Double'
against inferred type `Integer'
Expected type: Expr a
Inferred type: Expr Integer
In the first argument of `f', namely `x'
In the first argument of `Tint', namely `(f x)'

I think I'm making a conceptual error.  My assumption is that while
`f' has a generic type, at compile time it has a clear and definite
implementation and can't be specialized to the 3 uses of types.

It seems that the approach is flawed.  Is there another way to trick
the compiler into specializing this into 3 different versions?

The following typechecks, but just moves the problem upwards.  Maybe
it is enough though to make this work for instance declarations.

teLift1 ff fi fb = l where
l (Tfloat x) = Tfloat (ff x)
l (Tint x)   = Tint   (fi x)
l (Tbool x)  = Tbool  (fb x)

teLift2 ff fi fb = l where
l (Tfloat x) (Tfloat y) = Tfloat (ff x y)
l (Tint x)   (Tint y)   = Tint   (fi x y)
l (Tbool x)  (Tbool y)  = Tbool  (fb x y)

instance Num TExpr where
(+) = teLift2 (+) (+) (+)
(*) = teLift2 (*) (*) (*)
abs = teLift1 abs abs abs
signum = teLift1 signum signum signum
fromInteger = Tint . lit

It doesn't seem to be such a problem though.  Just a bit of
duplication to "punish me" because I want to do automatic type
conversion ;)

```
`[Reply][About]`
`[<<][meta][>>][..]`