Haskell仍然无法推断出类型相等

时间:2013-02-06 20:29:56

标签: haskell

这个问题是Haskell can't deduce type equality问题的后续问题。 我尝试使用上一个问题中描述的Trainable类型实现基本多项式逼近器,代码如下:

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

我的问题是问题来自哪里?我该如何解决?对我而言,这两种类型是平等的,所以我可能会误解类型系统中的某些内容。

1 个答案:

答案 0 :(得分:2)

我害怕排名2型

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

不会帮助你。我只关注其他问题中的类型错误,并没有注意到Floating不够丰富,无法使其真正可用。由于您无法通过Floating s(Floating)之外的任何内容将Real类型转换为其他类型或realToFrac类型,因此您无法编写一般来说,给定多态类型的许多有趣函数,抱歉。

此处的问题是,上述类型要求传递给Trainable构造函数的函数适用于所有Floating类型n(无论指定的a和{{ 1}}),但实现bpolynomialTrf仅适用于一种特定的polynomialCost类型,即作为(两者)参数的类型。 Floating的类型为polynomialTrf,但需要将Floating n => [n] -> n -> n类型的内容传递给(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]]

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