Haskell类具有多态数据定义的实例

Jul*_*an 1 polymorphism haskell functional-programming

关于具有多态数据类型的类定义,我有一个问题.让我们说定义的数据类型是:

data BTree a = BLeaf a | BNode a (BTree a) (BTree a) deriving(Show)
Run Code Online (Sandbox Code Playgroud)

假设我想要检索树根的值,但是在名为Tree的类的实例中:

class Tree a where
             getRoot:: a -> (?)  --<- Type of Leave value as return type
Run Code Online (Sandbox Code Playgroud)

和一个实例:

instance Tree (BTree a) where
                        getRoot BLeaf a = a
                        getRoot BNode a _ _ = a
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚函数的类型(参见questionmark),因为它不是a而且类不知道实例的参数.

4ca*_*tle 6

使class Tree声明中的type变量引用类型的构造函数* -> *,然后可以在类型签名中引用树的值类型getRoot.

class Tree t where
    getRoot :: t a -> a

instance Tree BTree where
    getRoot (BLeaf a)     = a
    getRoot (BNode a _ _) = a
Run Code Online (Sandbox Code Playgroud)

允许树结构类似的另一个稍微复杂的解决方案是*使用多参数类型类以及功能依赖性.

{-# LANGUAGE FunctionalDependencies, FlexibleInstances #-}

class Tree t a | t -> a where
    getRoot :: t -> a

instance Tree (BTree a) a where
    getRoot (BLeaf a)     = a
    getRoot (BNode a _ _) = a
Run Code Online (Sandbox Code Playgroud)

或者您可以使用类型系列.

{-# LANGUAGE TypeFamilies #-}

class Tree t where
    type Value t
    getRoot :: t -> Value t

instance Tree (BTree a) where
    type Value (BTree a) = a
    getRoot (BLeaf a)     = a
    getRoot (BNode a _ _) = a
Run Code Online (Sandbox Code Playgroud)