Haskell 没有得到我的功能依赖
Haskell not getting my functional dependency
我正在尝试创建一个实现基本队列行为的队列类型 class。我的代码如下:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
data QueueA a = QueueA { front :: [a], rear :: [a] }
class Queue a b | a -> b where
empty :: a
null :: a -> Bool
head :: a -> Maybe b
tail :: a -> Maybe a
toList :: a -> [b]
(|>) :: a -> b -> a
instance Queue (QueueA a) where
empty = QueueA [] []
null (QueueA [] []) = True
null _ = False
head (QueueA [] []) = Nothing
head (QueueA (x:xs) _) = Just x
tail (QueueA [] []) = Nothing
tail (QueueA (x:xs) (y:ys)) = Just $ QueueA (xs ++ [y]) ys
toList (QueueA x y) = x ++ y
(|>) (QueueA x y) e = if (length x > length y) then QueueA (init $ e : x) ((last x) : y) else QueueA (e : x) y
不幸的是,当我尝试编译代码时,ghc 告诉我以下内容:
queue.hs:15:10: error:
• Expecting one more argument to ‘Queue (QueueA a)’
Expected a constraint,
but ‘Queue (QueueA a)’ has kind ‘* -> Constraint’
• In the instance declaration for ‘Queue (QueueA a)’
|
15 | instance Queue (QueueA a) where
| ^^^^^^^^^^^^^^^^
虽然我没有真正理解消息。我所知道的是我的实例声明中队列的模式一定是正确的,因为它与我在上面的数据类型中指定的完全一样。我已经尝试了我的实例声明的几种变体,但无济于事。我只是忽略了什么吗?如何使它可编译?
实例需要与相应 class 相同数量的参数。但是,您创建了一个带有 2 个参数的 class 和一个只有 1 个参数的对应实例。要使其编译,您可以执行 instance Queue (QueueA a) a where
而不是 instance Queue (QueueA a) where
。 (您还需要 FlexibleInstances
扩展名。)
class 不需要多个参数。相反,class 应该采用高阶类型作为其参数,而不是具体类型。
class Queue t where
empty :: t a
null :: t a -> Bool
head :: t a -> Maybe a
tail :: t a -> Maybe (t a)
toList :: t a -> [a]
(|>) :: t a -> a -> t a
QueueA
本身有一个 Queue
实例,而不是 QueueA a
.
instance Queue QueueA where
-- same as above
我正在尝试创建一个实现基本队列行为的队列类型 class。我的代码如下:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
data QueueA a = QueueA { front :: [a], rear :: [a] }
class Queue a b | a -> b where
empty :: a
null :: a -> Bool
head :: a -> Maybe b
tail :: a -> Maybe a
toList :: a -> [b]
(|>) :: a -> b -> a
instance Queue (QueueA a) where
empty = QueueA [] []
null (QueueA [] []) = True
null _ = False
head (QueueA [] []) = Nothing
head (QueueA (x:xs) _) = Just x
tail (QueueA [] []) = Nothing
tail (QueueA (x:xs) (y:ys)) = Just $ QueueA (xs ++ [y]) ys
toList (QueueA x y) = x ++ y
(|>) (QueueA x y) e = if (length x > length y) then QueueA (init $ e : x) ((last x) : y) else QueueA (e : x) y
不幸的是,当我尝试编译代码时,ghc 告诉我以下内容:
queue.hs:15:10: error:
• Expecting one more argument to ‘Queue (QueueA a)’
Expected a constraint,
but ‘Queue (QueueA a)’ has kind ‘* -> Constraint’
• In the instance declaration for ‘Queue (QueueA a)’
|
15 | instance Queue (QueueA a) where
| ^^^^^^^^^^^^^^^^
虽然我没有真正理解消息。我所知道的是我的实例声明中队列的模式一定是正确的,因为它与我在上面的数据类型中指定的完全一样。我已经尝试了我的实例声明的几种变体,但无济于事。我只是忽略了什么吗?如何使它可编译?
实例需要与相应 class 相同数量的参数。但是,您创建了一个带有 2 个参数的 class 和一个只有 1 个参数的对应实例。要使其编译,您可以执行 instance Queue (QueueA a) a where
而不是 instance Queue (QueueA a) where
。 (您还需要 FlexibleInstances
扩展名。)
class 不需要多个参数。相反,class 应该采用高阶类型作为其参数,而不是具体类型。
class Queue t where
empty :: t a
null :: t a -> Bool
head :: t a -> Maybe a
tail :: t a -> Maybe (t a)
toList :: t a -> [a]
(|>) :: t a -> a -> t a
QueueA
本身有一个 Queue
实例,而不是 QueueA a
.
instance Queue QueueA where
-- same as above