Pergunta

Estou tendo pouco sucesso em entender o encanamento básico dos tipos envolvidos no ad pacote.Por exemplo, o seguinte funciona perfeitamente:

import Numeric.AD

ex :: Num a => [a] -> a
ex [x, y] = x + 2*y

> grad ex [1.0, 1.0]
[1.0, 2.0]

onde grad tem o tipo:

grad
  :: (Num a, Traversable f) =>
     (forall (s :: * -> *). Mode s => f (AD s a) -> AD s a)
     -> f a -> f a

Se eu alterar a assinatura de tipo de ex para [Double] -> Double e tentar a mesma coisa, eu entendo

Couldn't match expected type `AD s a0' with actual type `Double'
Expected type: f0 (AD s a0) -> AD s a0
  Actual type: [Double] -> Double

O mesmo comportamento ocorre ao substituir Double com aparentemente qualquer construtor de tipo com tipo * que instancia Num.

Quando o Traversable f é uma lista, o primeiro argumento de grad deve ter tipo [AD s a] -> AD s a para alguns aceitáveis Mode - por exemplo., Reverse.Mas claramente o usuário de grad não precisa lidar com AD construtor ou o Mode diretamente.Espiar esses detalhes internos me deixou um pouco confuso;especificamente, não consigo seguir a trilha tipo/tipo para a diferença entre usar Num a => [a] -> a e [Double] -> Double.

Por que a assinatura de tipo [Double] -> Double causar problemas com grad?E em termos de uso da biblioteca antiga:existe alguma maneira de usar o [Double] -> Double versão de ex, ou é necessária uma versão polimórfica?

(título inspirado em esta pergunta semelhante)

Foi útil?

Solução

eu não sei o ad biblioteca, mas desde grad espera uma função do tipo [AD s a] -> AD s a como seu primeiro parâmetro, você não pode esperar poder passar para ele uma função do tipo [Double] -> Double, desde Double e AD são tipos completamente diferentes.

A função genérica com Num restrição funciona, porque AD em si também é um exemplo de Num, portanto, no seu exemplo de trabalho, ex se especializa em algo como

ex :: (Mode s, Fractional a) => [AD s a] -> AD s a

Se você quiser se especializar ex para cálculos usando Doubles, você precisa fornecer uma assinatura como

ex :: Mode s => [AD s Double] -> AD s Double
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top