Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell AD,带约束类型向量的类型统一错误_Haskell - Fatal编程技术网

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
  -- (^/) = (/)