
Grady Lemoine wrote:
Hello,
I've been playing around with Dan Piponi's work on automatic differentiation (from http://sigfpe.blogspot.com/2005/07/automatic-differentiation.html and http://sigfpe.blogspot.com/2006/09/practical-synthetic-differential.html) and I'm getting some odd behavior with the inferred types of functions in GHCi 6.4.2. My test case is as follows:
data Dual a = D a a deriving (Show,Eq)
instance Num a => Num (Dual a) where fromInteger i = D (fromInteger i) 0 (D a a')+(D b b') = D (a+b) (a'+b') (D a a')-(D b b') = D (a-b) (a'-b') (D a a')*(D b b') = D (a*b) (a*b'+a'*b)
evalDeriv f x = (v, v') where D v v' = f (D x 1)
f x = x^3
f' = snd . (evalDeriv f)
When I load this in GHCi, I get:
*Main> :t f f :: (Num a) => a -> a *Main> :t snd . (evalDeriv f) snd . (evalDeriv f) :: (Num a, Num (Dual a)) => a -> a *Main> :t f' f' :: Integer -> Integer
Why is the type of f' Integer -> Integer, especially when the type of the expression it's defined as is more general? Is this something I'm not understanding about Haskell, or is it more to do with GHC 6.4.2 specifically?
Any help appreciated,
--Grady Lemoine
You have two different things making this error possible. First there is the default(Integer,Int) that Haskell implicitly provides. Second, there is the monomorphism restriction. Try this:
default ()
data Dual a = D a a deriving (Show,Eq)
instance Num a => Num (Dual a) where fromInteger i = D (fromInteger i) 0 (D a a')+(D b b') = D (a+b) (a'+b') (D a a')-(D b b') = D (a-b) (a'-b') (D a a')*(D b b') = D (a*b) (a*b'+a'*b) abs _ = error "no abs" signum _ = error "no signum"
evalDeriv f x = (v, v') where D v v' = f (D x 1)
f x = x^(3::Int)
f' :: (Num a) => a -> a f' = snd . (evalDeriv f)
I played with such things, as seen on the old wiki: http://haskell.org/hawiki/ShortExamples_2fSymbolDifferentiation -- Chris