views:

297

answers:

2

Hi,

I need the Numeric.FAD library, albeit still being completely puzzled by existential types.

This is the code:

error_diffs :: [Double] -> NetworkState [(Int, Int, Double)]
error_diffs desired_outputs = do diff_error <- (diff_op $ error' $ map FAD.lift desired_outputs)::(NetworkState ([FAD.Dual tag Double] -> FAD.Dual tag Double))
                                 weights <- link_weights
                                 let diffs = FAD.grad (diff_error::([FAD.Dual tag a] -> FAD.Dual tag b)) weights

                                 links <- link_list
                                 return $ zipWith (\link diff ->
                                                       (linkFrom link, linkTo link, diff)
                                                  ) links diffs

error' runs in a Reader monad, ran by diff_op, which in turn generates an anonymous function to take the current NetworkState and the differential inputs from FAD.grad and stuffs them into the Reader.

Haskell confuses me with the following:

Inferred type is less polymorphic than expected
  Quantified type variable `tag' is mentioned in the environment:
    diff_error :: [FAD.Dual tag Double] -> FAD.Dual tag Double
      (bound at Operations.hs:100:33)
In the first argument of `FAD.grad', namely
    `(diff_error :: [FAD.Dual tag a] -> FAD.Dual tag b)'
In the expression:
    FAD.grad (diff_error :: [FAD.Dual tag a] -> FAD.Dual tag b) weights
In the definition of `diffs':
    diffs = FAD.grad
              (diff_error :: [FAD.Dual tag a] -> FAD.Dual tag b) weights
+2  A: 

If I write,

bigNumber :: (Num a) => a
bigNumber = product [1..100]

then when bigNumber :: Int is evaluated,
it's evaluating (product :: [Int] -> Int) [(1 :: Int) .. (100 :: Int)],

and when bigNumber :: Integer is evaluated,
it's evaluating (product :: [Integer] -> Integer) [(1 :: Integer) .. (100 :: Integer)].

Nothing is shared between the two.

error_diffs has a single type, that is: [Double] -> NetworkState [(Int, Int, Double)]. It must evaluate in exactly one way.

However, what you have inside:

... :: NetworkState ([FAD.Dual tag Double] -> FAD.Dual tag Double)

can be evaluated in different ways, depending on what tag is.

See the problem?

ephemient
No, sorry. I have no idea what purpose the tag type variable has. How am I supposed to deal with Numeric.FAD? All I need is derivation.
Astro
See http://thread.gmane.org/gmane.comp.lang.haskell.cafe/22308/ for a discussion of the "tagging" used by FAD. I don't have Numeric.FAD installed, so I can't confidently help you with restructuring your code quite yet. Maybe you can give it a try yourself, with hints from that article?
ephemient
+3  A: 

this code gives the same error as you get:

test :: Int
test =
  (res :: Num a => a)
  where
    res = 5

The complier figured that 'res' is always of type Int and is "bothered" that for some reason you think 'res' is polymorphic.

this code, however, works fine:

test :: Int
test =
  res
  where
    res :: Num a => a
    res = 5

here too 'res' is defined as polymorphic but only ever used as Int. the complier is only bothered when you type nested expressions this way. in this case 'res' could be reused and maybe one of those uses will not use it as Int, in contrast to when you type a nested expression, which cannot be reused by itself.

yairchu