Haskell仍然无法推导出类型相等 [英] Haskell still can't deduce type equality

查看:96
本文介绍了Haskell仍然无法推导出类型相等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是关于 Haskell无法推导出类型相等
我已经尝试使用我之前的问题中描述的可训练类型使用以下代码实现基本多项式逼近器:

 模块MachineLearning.Polynomial 
(多项式,
polynomialTrf
)其中
导入MachineLearning.Training
导入MachineLearning.Utils

polynomialTrf :: Floating n => [n] - > n - > n
polynomialTrf coeff var = helper 0 coeff var 0其中
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)=>可训练的n
polynomialSV =可训练的多项式Trf polynomialCost

这里 sqcost 只是 sqcost ab =(ab)^ 2 。我从编译器中得到以下错误消息:

$ s $ / $ Machine $ s $ / $ MachineLearning / Polynomial.hs:18:26
无法从上下文(Floating n)
推断(n1〜n)

类型签名绑定polynomialSV :: Floating n =>可在src / MachineLearning / Polynomial.hs:18:1-53
或from(浮动n1)
的可训练nn
由上下文期望的类型绑定:
浮动n1 = > [n1] - > n - > n
at src / MachineLearning / Polynomial.hs:18:16-53
`n1'是一个刚性类型变量,由
绑定,上下文期望类型:Floating n1 => [n1] - > n - > n
at src / MachineLearning / Polynomial.hs:18:16
`n'是一个刚性类型变量,由
绑定,用于polynomialSV :: Floating n =>在src / MachineLearning / Polynomial.hs:18:1
可训练n
期望类型:[n] - > n1 - > n1
实际类型:[n] - > n - > n
在可训练的第一个参数中,即`polynomialTrf'
在表达式中:可训练多项式Trf polynomialCost

src / MachineLearning / Polynomial.hs:18:40:
无法从
polynomialSV :: Floating n =>>类型签名所限制的上下文(Floating n)
中推导出(n〜n1)
。可在src / MachineLearning / Polynomial.hs:18:1-53
或from(浮动n1)
的可训练nn
由上下文期望的类型绑定:
浮动n1 = > n - > n - > [n1] - > n1
at src / MachineLearning / Polynomial.hs:18:16-53
`n'是一个刚性类型变量,由
绑定,用于polynomialSV :: Floating n =>在src / MachineLearning / Polynomial.hs:18:1中可训练n

'n1'是一个刚性类型变量,由
绑定,上下文期望类型:Floating n1 => n - > n - > [n1] - > n1
在src / MachineLearning / Polynomial.hs:18:16
预期类型:n - > n - > [n1] - > n1
实际类型:n - > n - > [n] - > n
在可训练的第二个参数中,即`polynomialCost'
在表达式中:可训练多项式Trf polynomialCost

我的问题是问题来自哪里?我该如何解决它?对我来说,感觉这两种类型是平等的,所以我有可能误解类型系统中的某些东西。 解决方案

恐怕等级2类型

  data可训练的ab 
=可训练的(forall n。漂浮的n => ; [n] - > a - > b)
(forall n。浮动n => a - > b - > [n] - > n)

不会帮助你。我只关注另一个问题中的类型错误,并没有注意到 Floating 没有足够的丰富性来使它真正可用。既然你不能一般地从浮动类型转换为其他类型,或者浮动 code> Real s( realToFrac ),对于给定的多态类型,一般不会写很多有趣的函数,对不起。 / p>

这里的问题是,上面的类型要求传递给可训练构造函数的函数适用于所有浮动类型 n (不管指定的 a b ),但是实现 polynomialTrf polynomialCost 只适用于一个特定的浮动类型,即作为(两个)参数给出的类型。 polynomialTrf 的类型为浮动n => [n] - > n - > n ,但它需要类型为(Floating n,Floating f)=> [f] - > n - > n 有资格被传递给可训练的构造函数。



类型参数,你可以有

 可训练的多项式Trf polynomialCost :: Floating n =>>可训练的nnn 

trainSgdFull 需要类型

  trainSgdFull ::(Floating n,Ord n,Mode s)=>可训练a b(AD s n) - > [n]  - > a  - > b  - >为了能够使用 gradientdecent   

$ c $。

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


This question is a follow up on the question Haskell can't deduce type equality. I have tried implementing a basic polynomial approximator using the Trainable type described in my previous question with the following code:

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

Here sqcost is just sqcost a b = (a-b) ^ 2. I get the following error message from the compiler:

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

My question is where is the problem coming from? How can I solve it? For me it feels clear the those two types are equal, so there is the possibility that I misunderstand something in the type system.

解决方案

I'm afraid the rank 2 type

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

won't help you. I concentrated only on the type error in the other question, and didn't notice that Floating isn't rich enough to make that really usable. Since you can't generically convert from a Floating type to some other type or to a Floating type from anything but Reals (realToFrac), you can't write many interesting functions of the given polymorphic types in general, sorry.

The problem here is that the above type demands that the functions passed to the Trainable constructor work for all Floating types n (whatever the specified a and b), but the implementations polynomialTrf and polynomialCost only work for one specific Floating type, the one that is given as (both) the parameters. polynomialTrf has the type Floating n => [n] -> n -> n, but it would need to have the type (Floating n, Floating f) => [f] -> n -> n to be eligible to be passed to the Trainable constructor.

With a third type parameter, you would have

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

and for trainSgdFull, you would need the type

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

to be able to use gradientDescent.

I don't know how a proper solution to your problem might look like.

这篇关于Haskell仍然无法推导出类型相等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆