如何声明这个函数的类型? [英] How to declare type of this function?

查看:132
本文介绍了如何声明这个函数的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用矢量库并试图编写简单的函数:

 将限定的Data.Vector.Generic导入为GV 

setCharges :: GV.Vector v Double =>
网络 - > v Double - > Network
setCharges n cs = n {nodes = GV.zip With setCharge(nodes n)cs}



<使用 XFlexibleContexts ghc接受类型声明,但抱怨接近 cs varibale

 无法推断(v〜Vector)

我有

 节点n :: Data.Vector.Vector节点
setCharge :: Node - >双 - >节点

不要真的得到什么问题。

setCharges 签名只要求 v c $ c>是类的一些实例 Data.Vector.Generic.Vector Network 节点字段总是一个特定类型,即 Data.Vector .Vector ,这当然是 Vector 类的一个实例,但也可以有其他的。所以你不能只用其他类型替换这个字段,不管它是否是 GV.Vector 的一个实例。但有一个通用函数 convert 这样的实例之间,使用它,你会没事的:

  setCharges n cs = n {nodes = GV.zip With setCharge(nodes n)(GV.convert cs)} 

或者,您可以设计 Network 记录,以便节点字段处于事实上是多态的,即可以保存类的任意实例,而不是一个特定的类型。这被称为存在

  { - #LANGUAGE ExistentialQuantification# - } 

data Network = Network {...
,nodes :: forall v。 GV.Vector v => v Double
,...
}

但它通常被认为有点的反模式,至少如果没有特别的理由去这条路线。


I'm using vector library and trying to write simple function:

import qualified Data.Vector.Generic as GV

setCharges :: GV.Vector v Double => 
              Network -> v Double -> Network
setCharges n cs = n{nodes = GV.zipWith setCharge (nodes n) cs}

With XFlexibleContexts ghc accepts type declaration but complain near cs varibale

Could not deduce (v ~ Vector)

I have

nodes n :: Data.Vector.Vector Node
setCharge :: Node -> Double -> Node

Don't really get, what the problem.

解决方案

It's just what GHC says: the setCharges signature only requires that v is some instance of the class Data.Vector.Generic.Vector. The nodes field of Network, OTOH, is always one particular type, namely Data.Vector.Vector, which sure enough is an instance of the Vector class, but there can be others as well. So you can't just replace this field with some other type, no matter if it's an instance of GV.Vector or not. But there's a generic function to convert between such instances, use that and you'll be fine:

setCharges n cs = n{nodes = GV.zipWith setCharge (nodes n) (GV.convert cs)}

Alternatively, you could design the Network record so the nodes field is in fact polymorphic, i.e. can hold arbitrary instances of the class rather than one particular type. This is called an existential:

{-# LANGUAGE ExistentialQuantification       #-}

data Network = Network { ...
                       , nodes :: forall v . GV.Vector v => v Double
                       , ...
                       }

But it's generally considered a bit of an antipattern, at least if there isn't a particular reason to go this route.

这篇关于如何声明这个函数的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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