我一直在为 Haskell 中的列表摆弄通用类型类。
class HasEmpty a where
empty :: a
isEmpty :: a -> Bool
class HasEmpty (l a) => List l where
cons :: a -> l a -> l a
uncons :: l a -> (a, l a)
为了让您了解它的工作原理,这里是
[]
的实例。 :instance HasEmpty [a] where
empty = []
isEmpty [] = True
isEmpty _ = False
instance List [] where
cons = (:)
uncons (x:xs) = (x,xs)
但是,这会引发错误:
Not in scope: type variable 'a'
这是由约束
HasEmpty (l a)
引起的.我对这个特定的例子并不是特别感兴趣,但我对一般的概念感兴趣。 HasEmpty
是类型类型的类 *
, 而 List
是类型类型的类 * -> *
. 我是否可以创建与它所约束的类型类不同的类型类约束?
最佳答案
在任何情况下,您始终可以使用多参数类型类来表达底层逻辑(实际上它是在 ListLike 中完成的):
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
class HasEmpty a where
empty :: a
isEmpty :: a -> Bool
class HasEmpty (l a) => List l a where
cons :: a -> l a -> l a
uncons :: l a -> (a, l a)
instance HasEmpty [a] where
empty = []
isEmpty [] = True
isEmpty _ = False
instance List [] a where
cons = (:)
uncons (x:xs) = (x,xs)
或者更优雅地通过类型系列:
{-# LANGUAGE TypeFamilies #-}
class HasEmpty a where
empty :: a
isEmpty :: a -> Bool
class HasEmpty a => List a where
type Elem a :: *
cons :: Elem a -> a -> a
uncons :: a -> (Elem a, a)
instance HasEmpty [a] where
empty = []
isEmpty [] = True
isEmpty _ = False
instance List [a] where
type Elem [a] = a
cons = (:)
uncons (x:xs) = (x,xs)
关于haskell - 不同种类的类型类约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7816622/