Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Haskell中返回另一个Typeclass的Typeclass方法_Haskell_Typeclass - Fatal编程技术网

在Haskell中返回另一个Typeclass的Typeclass方法

在Haskell中返回另一个Typeclass的Typeclass方法,haskell,typeclass,Haskell,Typeclass,我的任务是在Haskell中定义2个TypeClass。一个是简单的-它实现Ord,并有一个方法将给定类型转换为int。类似如下: class (Ord a) => Id a where toInt :: a -> Int class HasId a where getId :: a -> Id a 但是我有另一个类型类HasId,它有一个getId方法。此方法应返回Id typeclass。所以我写了这样的东西: class (Ord a) => Id a

我的任务是在Haskell中定义2个TypeClass。一个是简单的-它实现Ord,并有一个方法将给定类型转换为int。类似如下:

class (Ord a) => Id a where
  toInt :: a -> Int
class HasId a where
  getId :: a -> Id a 
但是我有另一个类型类HasId,它有一个getId方法。此方法应返回Id typeclass。所以我写了这样的东西:

class (Ord a) => Id a where
  toInt :: a -> Int
class HasId a where
  getId :: a -> Id a 
我遇到了一个我不知道如何解决的错误

• Expected kind ‘* -> Constraint’, but ‘Int’ has kind ‘*’
• In the class declaration for ‘HasId’
 |
 | class (Int a) => HasId a where     |        ^^^^^

• Expected a type, but ‘Id a’ has kind ‘Constraint’
• In the type signature: getId :: a -> Id a
  In the class declaration for ‘HasId’
 |
 |  getId :: a -> Id a     |             
有人能告诉我如何在别人的typeclass方法中返回typeclass吗?
我应该首先实现Id typeclass的某个实例吗?

您声明返回值为HKT
Id a
,但您需要的是另一个类型,受typeclass
Id
的约束


您需要的不是
getId::a->ida
,而是
getId::idb=>a->b

了解Haskell
类与OO语言中的类非常不同,这一点很重要。它是一个类型类,即它“将一组类型组合在一起”,而OO类将一组值组合在一起。依我看,OO类是一种类型(包含值),但Haskell类实际上更像是一种类型

现在,函数/方法总是将值作为参数,并将值作为结果返回。但它不能返回类型,也不能返回“类型类的值”,因为根本没有这样的东西

相反,使用类型类的方法是:编写一个多态函数,即一个接受或生成未指定类型值的函数。这就是类型变量的用途。通常,多态签名意味着函数可以处理任何类型的值,比如

length :: [a] -> Int
它接受一个列表,不关心其元素的类型。但是你说你确实有点在乎使用什么类型,也就是说,你要求它们在类中。这是一个约束,它是用
=>
符号编写的
toInt
实际具有签名(由类声明自动生成)

坦率地说,我怀疑这是否真的是你想要的。如果对
Id a
所能做的只是将其转换为
Int
,那么不管
a
参数是什么,结果实际上就是一个
Int
(只是带有一个类型注释,指示该Id属于哪种类型的对象)。因此,代替<代码> ID <代码>类,应该考虑有<代码> ID <代码>类型

然后,你有更明智的类型

toInt :: Id' a -> Int
不需要任何约束

newtype
与OO类更为相似,因为它实际上定义了一个具体类型,其中包含可以传递的值

getId
方法也是一个受约束的多态函数,它可以获取“具有
Id
”的内容并返回该Id。在这种情况下,类是有意义的(因为可以使用不同的数据结构以不同的方式存储它们的Id)。这实际上是

class HasId a where
  getId :: a -> Id' a
根据,使用原始的
Id
类来定义
HasId
确实也很方便,只是它没有多大意义
Id
是可以用作标识符的所有类型的类。您可以表示
getId
可以生成任何此类类型的Id:

class HasId a where
  getId :: Id b => a -> b
请注意,结果Id类型现在完全独立于要计算其Id的对象类型<代码>b
始终可以是任何Id类型。正如我所说的,这是没有意义的:为什么您需要大量不同的类型来表示ID,但需要所有的
HasId
类型来支持它们

事实上,这无法按现状实现,因为没有任何机制允许您生成任意
Id
类型的Id。这需要一种额外的方法

class Id a where
  toInt :: a -> Int
  fromInt :: Int -> a
现在你可以做了

class HasId a where
  getId :: Id b => a -> b

data SomeObj { objName :: String
             , objId :: Int }

instance HasId SomeObj where
  getId (SomeObj _ i) = fromInt i

但是,如果您要求任何
Id
类型都可以从
Int
和转换为
Int
,那么这些类型必须与
Int
本身同构。因此,
newtypeid'a
方法几乎肯定更好。

这可能会进行类型检查,但我怀疑它是否真的有效。问题中给出的
Id
类使得
getId::Id b=>a->b
基本上不可能实现。谢谢你的扩展答案!非常感谢你的帮助。事实上,我明天的考试需要它,所以再次非常感谢:)