Haskell AD,带约束类型向量的类型统一错误
我需要找到一个Haskell AD,带约束类型向量的类型统一错误,haskell,Haskell,我需要找到一个V.vectorcdouble->V.vectorcdouble函数的雅可比矩阵 在试图从答案中产生一个最小的例子时,我仍然偶然发现了一个类型统一问题的结。到目前为止,我得到的最接近的结果(下面完整的代码)给出了以下错误: Could not deduce (t ~ CDouble) from the context (a ~ CDouble) bound by the type signature for jf1 ::
V.vectorcdouble->V.vectorcdouble
函数的雅可比矩阵
在试图从答案中产生一个最小的例子时,我仍然偶然发现了一个类型统一问题的结。到目前为止,我得到的最接近的结果(下面完整的代码)给出了以下错误:
Could not deduce (t ~ CDouble)
from the context (a ~ CDouble)
bound by the type signature for
jf1 :: a ~ CDouble => V.Vector a -> V.Vector (V.Vector a)
at ADMode.hs:17:8-69
or from (AD.Scalar t ~ a, AD.Mode t)
bound by the type signature for
go :: (AD.Scalar t ~ a, AD.Mode t) => V.Vector t -> V.Vector t
at ADMode.hs:19:9-74
‘t’ is a rigid type variable bound by
the type signature for
go :: (AD.Scalar t ~ a, AD.Mode t) => V.Vector t -> V.Vector t
at ADMode.hs:19:16
Expected type: V.Vector t
Actual type: V.Vector CDouble
注意:我在jf1
类型上添加了实例AD.Mode CDouble
和约束(a~CDouble)
;这些(AFAICT)是唯一与参考SO答案相关的变更
我承认我仍然不理解双重存在量化的作用,以及类型约束提示(即,
~
)如何与类型推断交互。另一方面,我只是想让这个小玩意儿暂时发挥作用
欢迎任何提示和解释。提前谢谢你
AD.jacobian(fmap realToFrac.f1.fmap realToFrac)
谢谢@user2407038;在完成所有类型注释之后,它就可以工作了。现在我想理解为什么类型约束如此简化,只需应用realToFrac
的双过程。realToFrac
只是从Reverse s CDouble
转换为CDouble
<代码>反向有一个实例(具体化s磁带,分数a)=>分数(反向s a)
和(具体化s磁带,实a)=>实(反向s a)
,允许进行此转换。realToFrac
的使用并没有简化约束-您所给出的go
类型只是比开始时需要的更一般。你说它适用于任何模式t
(实际上现在它将是分数t,实t
),但它仅用一个t
实例化-即反向s CDouble
@user2407038,你认为有办法绕过这种双重转换吗?因为一方面它会进行打字检查,但另一方面所有的导数都会因为它而被调零。我怀疑AD.jacobian(fmap realToFrac.f1.fmap realToFrac)的精确度有所下降。谢谢@user2407038;在完成所有类型注释之后,它就可以工作了。现在我想理解为什么类型约束如此简化,只需应用realToFrac
的双过程。realToFrac
只是从Reverse s CDouble
转换为CDouble
<代码>反向有一个实例(具体化s磁带,分数a)=>分数(反向s a)
和(具体化s磁带,实a)=>实(反向s a)
,允许进行此转换。realToFrac
的使用并没有简化约束-您所给出的go
类型只是比开始时需要的更一般。你说它适用于任何模式t
(实际上现在它将是分数t,实t
),但它仅用一个t
实例化-即反向s CDouble
@user2407038,你认为有办法绕过这种双重转换吗?因为一方面它会进行打字检查,但另一方面所有的导数都会因为它而被调零。我怀疑这涉及到精度的损失
{-# language TypeFamilies, RankNTypes, ScopedTypeVariables #-}
module ADMode where
import Foreign.C.Types
import qualified Numeric.AD as AD
import qualified Data.Vector as V
f1 :: V.Vector CDouble -> V.Vector CDouble
f1 = V.map (**2)
jf1 :: forall a. (a ~ CDouble) => V.Vector a -> V.Vector (V.Vector a)
jf1 = AD.jacobian go where
go :: forall t. (AD.Scalar t ~ a, AD.Mode t) => V.Vector t -> V.Vector t
go x = f1 (V.map AD.auto x)
instance AD.Mode CDouble where
type Scalar CDouble = CDouble
-- isKnownConstant _ = True
-- isKnownZero x = 0 == x
auto = id
-- (^/) = (/)