Что делать с «Предполагаемый тип менее полиморфен, чем ожидалось»? - PullRequest
4 голосов
/ 12 июня 2009

Мне нужна библиотека Numeric.FAD, хотя все еще полностью озадачена экзистенциальными типами.

Это код:

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 'запускается в монаде Reader, запускаемой diff_op, которая, в свою очередь, генерирует анонимную функцию для получения текущего NetworkState и дифференциальных входов из FAD.grad и вставляет их в Reader.

Хаскелл смущает меня следующим:

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 ]

4 голосов
/ 12 июня 2009

этот код выдает ту же ошибку, что и вы:

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

Компилятор понял, что res всегда относится к типу Int и обеспокоен тем, что по какой-то причине вы думаете, res полиморфен.

этот код, однако, работает нормально:

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

и здесь res определяется как полиморфный, но используется только как Int. компилятор беспокоится только тогда, когда вы так печатаете вложенные выражения. в этом случае res можно использовать повторно, и, возможно, одно из этих применений не будет использовать его как Int, в отличие от ввода вложенного выражения, которое само по себе не может использоваться повторно.

3 голосов
/ 12 июня 2009

Если я напишу,

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

затем при оценке bigNumber :: Int,
это оценивает (product :: [Int] -> Int) [(1 :: Int) .. (100 :: Int)],

и когда bigNumber :: Integer оценивается,
это оценивает (product :: [Integer] -> Integer) [(1 :: Integer) .. (100 :: Integer)].

Ничего не поделено между ними.

error_diffs имеет один тип, то есть: [Double] -> NetworkState [(Int, Int, Double)]. Он должен оцениваться ровно одним способом.

Однако, что у вас внутри:

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

можно оценивать по-разному, в зависимости от значения tag.

Видите проблему?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...