0

这个问题是对Haskell can't deduc type equal问题的跟进。我尝试使用我上一个问题中描述的可训练类型和以下代码来实现一个基本的多项式逼近器:

module MachineLearning.Polynomial
       (polynomial,
        polynomialTrf
       ) where
import MachineLearning.Training
import MachineLearning.Utils

polynomialTrf :: Floating n => [n] -> n -> n
polynomialTrf coeff var = helper 0 coeff var 0 where
  helper _ [] var acc = acc
  helper 0 (c:cs) var acc = helper 1 cs var c 
  helper deg (c:cs) var acc = helper (deg+1) cs var (acc+(c*(var^deg)))

polynomialCost :: Floating n => n -> n -> [n] -> n
polynomialCost var target coeff = sqcost (polynomialTrf coeff var) target

polynomialSV :: (Floating n) => Trainable n n
polynomialSV = Trainable polynomialTrf polynomialCost

这里sqcost只是sqcost a b = (a-b) ^ 2. 我从编译器收到以下错误消息:

src/MachineLearning/Polynomial.hs:18:26:
    Could not deduce (n1 ~ n)
    from the context (Floating n)
      bound by the type signature for
                 polynomialSV :: Floating n => Trainable n n
      at src/MachineLearning/Polynomial.hs:18:1-53
    or from (Floating n1)
      bound by a type expected by the context:
                 Floating n1 => [n1] -> n -> n
      at src/MachineLearning/Polynomial.hs:18:16-53
      `n1' is a rigid type variable bound by
           a type expected by the context: Floating n1 => [n1] -> n -> n
           at src/MachineLearning/Polynomial.hs:18:16
      `n' is a rigid type variable bound by
          the type signature for polynomialSV :: Floating n => Trainable n n
          at src/MachineLearning/Polynomial.hs:18:1
    Expected type: [n] -> n1 -> n1
      Actual type: [n] -> n -> n
    In the first argument of `Trainable', namely `polynomialTrf'
    In the expression: Trainable polynomialTrf polynomialCost

src/MachineLearning/Polynomial.hs:18:40:
    Could not deduce (n ~ n1)
    from the context (Floating n)
      bound by the type signature for
                 polynomialSV :: Floating n => Trainable n n
      at src/MachineLearning/Polynomial.hs:18:1-53
    or from (Floating n1)
      bound by a type expected by the context:
                 Floating n1 => n -> n -> [n1] -> n1
      at src/MachineLearning/Polynomial.hs:18:16-53
      `n' is a rigid type variable bound by
          the type signature for polynomialSV :: Floating n => Trainable n n
          at src/MachineLearning/Polynomial.hs:18:1
      `n1' is a rigid type variable bound by
           a type expected by the context: Floating n1 => n -> n -> [n1] -> n1
           at src/MachineLearning/Polynomial.hs:18:16
    Expected type: n -> n -> [n1] -> n1
      Actual type: n -> n -> [n] -> n
    In the second argument of `Trainable', namely `polynomialCost'
    In the expression: Trainable polynomialTrf polynomialCost

我的问题是问题出在哪里?我该如何解决?对我来说,这两种类型很明显是相等的,所以我有可能误解了类型系统中的某些东西。

4

1 回答 1

2

恐怕是等级2

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

不会帮你的。我只关注另一个问题中的类型错误,并没有注意到Floating它还不够丰富,无法使其真正可用。由于您一般不能从一个Floating类型转换为其他类型或Floating从除Reals ( realToFrac) 之外的任何类型转换为一个类型,因此您通常无法编写给定多态类型的许多有趣的函数,抱歉。

这里的问题是,上述类型要求传递给Trainable构造函数的函数适用于所有Floating类型n(无论指定什么ab),但实现polynomialTrfpolynomialCost适用于一种特定Floating类型,即作为(两个)参数给出的类型。polynomialTrf有 type Floating n => [n] -> n -> n,但它需要有 type(Floating n, Floating f) => [f] -> n -> n才有资格传递给Trainable构造函数。

使用第三种类型参数,您将拥有

Trainable polynomialTrf polynomialCost :: Floating n => Trainable n n n

而对于trainSgdFull,您将需要类型

trainSgdFull :: (Floating n, Ord n, Mode s) => Trainable a b (AD s n) -> [n] -> a -> b -> [[n]]

能够使用gradientDescent

我不知道如何正确解决您的问题。

于 2013-02-06T22:10:21.003 回答