Haskell:我如何为这个类编写一个实例

时间:2013-09-20 02:43:16

标签: haskell functional-programming

在Haskell中,如果我有一个像

这样的界面
class Eq a => Lol l a b where
    ...

我应该如何声明简单实例? 如果我尝试像

那样的话
class Lol1 a b
instance Lol Lol1 A B

它抱怨说Lol的第一个参数应该有类型* - > * - > *而Lol1有种类

* -> * -> Constraint

3 个答案:

答案 0 :(得分:2)

你得到的错误是一种不匹配。种类是类型的“类型”。例如,Int具有*种类。 *用于表示任何haskell值类型,Int s,Bool s,等等。

所以你正在寻找那种* -> * -> *的东西。这会收集2件类*并返回*。一个例子是Either

问题是您的类型类Lol1没有* -> * -> *类型,它意味着在=>的左侧使用,那些东西有Constrainta ~ Int 1}}。像这样的其他东西是等式约束,instance Foo (a ~ Int)或隐式参数。

因此,这导致了不可避免的结论,即您不能将类用作其他类的参数,如下所示。它永远不会被证实。这就像说 class Foo k where foo :: ... => k a -> ... -- Or in general, On the right side of an => foo' :: ... => Foo Foo -> ..

 data Lol1 a b = ...

所以你必须使用数据类型,

...

如果没有Lol的更多代码,我无法提供有关{{1}}应该是什么的任何详细信息。

答案 1 :(得分:1)

您是否阅读过learnyouahaskell

特别是关于typeclasses的部分以及关于kinds的部分应该对您的情况非常有帮助。

答案 2 :(得分:0)

在不知道程序的整个范围的情况下,我不能说这是否是您想要的解决方案。但是你确实可以使用类并将它们视为类实例中的类型。

{-# LANGUAGE 
 MultiParamTypeClasses,
 KindSignatures,
 ConstraintKinds,
 FlexibleInstances,
 UndecidableInstances
 #-}

import GHC.Prim (Constraint)

class Lol1 a b -- Lol1 has kind * -> * -> Constraint
class Lol2 a   -- Lol2 has kind * -> Constraint

-- Note the explicit 'kind' signature for type var 'l'. This is necessary
class Eq a => Lol (l :: * -> * -> Constraint) a b where

instance Eq b => Lol Lol1 b c
-- instance Eq b => Lol Lol2 b c -- won't work

data A; data B

你可以用类'type'变量做的唯一事情就是用它来约束其他类型变量,或者把它传递给另一个类。

class (l a b) => Lol (l :: * -> * -> Constraint) a b where

instance Lol1 a b -- removing this breaks the line below
instance Lol Lol1 a b