[<<][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)'
Failed, modules loaded: none.
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][>>][..]