Tipos aceitáveis em funções Numeric.AD
-
11-12-2019 - |
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)
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