Haskell无法推断出类型相等

lac*_*i37 1 haskell automatic-differentiation

我有以下代码,不编译:

  import Numeric.AD

  data Trainable a b = forall n . Floating n =>  Trainable ([n] -> a -> b) (a -> b -> [n] -> n) 

  trainSgdFull :: (Floating n, Ord n) => Trainable a b -> [n] -> a -> b -> [[n]]
  trainSgdFull (Trainable _ cost) init input target =  gradientDescent (cost input target) init
Run Code Online (Sandbox Code Playgroud)

我想使用Trainable类型来表示可通过梯度下降训练的机器学习系统.第一个算法是传递函数,sencond是成本函数,a是输入类型,b是输出/目标类型,列表包含可学习参数.编译器抱怨这个:

 src/MachineLearning/Training.hs:12:73:
Could not deduce (n1 ~ ad-3.3.1.1:Numeric.AD.Internal.Types.AD s n)
from the context (Floating n, Ord n)
  bound by the type signature for
             trainSgdFull :: (Floating n, Ord n) =>
                             Trainable a b -> [n] -> a -> b -> [[n]]
  at src/MachineLearning/Training.hs:12:3-95
or from (Floating n1)
  bound by a pattern with constructor
             Trainable :: forall a b n.
                          Floating n =>
                          ([n] -> a -> b) -> (a -> b -> [n] -> n) -> Trainable a b,
           in an equation for `trainSgdFull'
  at src/MachineLearning/Training.hs:12:17-32
or from (Numeric.AD.Internal.Classes.Mode s)
  bound by a type expected by the context:
             Numeric.AD.Internal.Classes.Mode s =>
             [ad-3.3.1.1:Numeric.AD.Internal.Types.AD s n]
             -> ad-3.3.1.1:Numeric.AD.Internal.Types.AD s n
  at src/MachineLearning/Training.hs:12:56-95
  `n1' is a rigid type variable bound by
       a pattern with constructor
         Trainable :: forall a b n.
                      Floating n =>
                      ([n] -> a -> b) -> (a -> b -> [n] -> n) -> Trainable a b,
       in an equation for `trainSgdFull'
       at src/MachineLearning/Training.hs:12:17
Expected type: [ad-3.3.1.1:Numeric.AD.Internal.Types.AD s n1]
               -> ad-3.3.1.1:Numeric.AD.Internal.Types.AD s n1
  Actual type: [n] -> n
In the return type of a call of `cost'
In the first argument of `gradientDescent', namely
  `(cost input target)'
Run Code Online (Sandbox Code Playgroud)

基本概念是对的吗?如果是,我怎么能编译代码?

Dan*_*her 7

问题是

data Trainable a b = forall n . Floating n =>  Trainable ([n] -> a -> b) (a -> b -> [n] -> n)
Run Code Online (Sandbox Code Playgroud)

意味着在

Trainable transfer cost
Run Code Online (Sandbox Code Playgroud)

使用的类型n丢失了.所有已知的是,有一些类型Guessme具有这样的Floating实例

transfer :: [Guessme] -> a -> b
cost :: a -> b -> [Guessme] -> Guessme
Run Code Online (Sandbox Code Playgroud)

您可以Trainable使用仅适用于Complex Float或仅适用于Double或...的功能构建s

但在

trainSgdFull :: (Floating n, Ord n) => Trainable a b -> [n] -> a -> b -> [[n]]
trainSgdFull (Trainable _ cost) init input target =  gradientDescent (cost input target) init
Run Code Online (Sandbox Code Playgroud)

你试图使用cost任何Floating类型作为参数提供.

Trainable被构建为使用类型n0,用户供应类型n1,那些可能是或可能不相同.因此编译器无法推断它们是相同的.

如果您不想创建n类型参数Trainable,则需要使其包含多态函数,该函数适用于调用​​者提供的每种 Floating类型

data Trainable a b
    = Trainable (forall n. Floating n => [n] -> a -> b)
                (forall n. Floating n => a -> b -> [n] -> n)
Run Code Online (Sandbox Code Playgroud)

(需要Rank2Types,或者,因为这是在被弃用的过程中RankNTypes).