我有这样的代码:
module Coleccion where
data Pila a= Pil [a] deriving (Show,Eq,Ord)
data Cola a= Col [a] deriving (Show,Eq,Ord)
class Coleccion n where
esVacia::n->Bool
insertar::n->a->n
primero::n->a
eliminar:: n->n
size::n->Int;
instance Coleccion (Pila a) where
esVacia (Pil [])= True
esVacia (Pil _ )= False
primero (Pil x) = last x
eliminar (Pil x)= (Pil (init x))
size (Pil []) = 0
size (Pil pila) = length pila;当我用GHCI编译它时,我有:
• Couldn't match expected type ‘a1’ with actual type ‘a’
‘a’ is a rigid type variable bound by
the instance declaration at Coleccion.hs:18:12-29
‘a1’ is a rigid type variable bound by
the type signature for:
primero :: forall a1. Pila a -> a1
at Coleccion.hs:21:5-11
• In the expression: last x
In an equation for ‘primero’: primero (Pil x) = last x
In the instance declaration for ‘Coleccion (Pila a)’
• Relevant bindings include
x :: [a] (bound at Coleccion.hs:21:18)
primero :: Pila a -> a1 (bound at Coleccion.hs:21:5)我对它们有问题的函数是具有不同于n或预定义类型的类型的函数(Bool,Integer.)比如primero。例如,esVacia、size & eliminar运行良好。我不知道声明或实例代码有什么问题。谢谢。
发布于 2017-12-11 17:30:31
在类声明中,函数insertar和primera承诺使用者可以使用任何类型的a (顺便说一句:您错过了insertar实现)。但是,当在类实例中实现它们时,可以尝试使其与特定的a (即Pila的“内容”)一起工作。类的承诺被打破了--实际上,实例中的函数不能处理任何类型的a --所以编译器会抱怨。
如果您想要使此工作,您需要声明类Coleccion的方式是:"n是一个集合,它包含类型为a__的元素,下面是应该与这些类型的n和a一起工作的函数“。
实现此的一种方法是使用关联类型
class Coleccion n where
type Elemento n
esVacia::n->Bool
insertar::n -> Elemento n -> n
primero::n -> Elemento n
eliminar:: n->n
size::n->Int;这个声明说:“无论谁为某种类型的Coleccion __定义一个实例,都应该提供一种方法来确定该集合的元素类型,而insertar和primero应该处理该类型,而不是在一些随机的无关类型上工作”。您可以这样实现它:
instance Coleccion (Pila a) where
type Elemento (Pila a) = a
...
primero (Pil x) = last x在这里,您会说:“我的收藏是Pila a__,它的元素是a__,下面是primero应该如何处理的”。
(注意:您需要使用TypeFamilies扩展来完成此操作)
Alternatively,您可以使用函数依赖项和双参数类型类:
class Coleccion n el | n -> el where
...
insertar::n -> el -> n
primero::n -> el这个声明说:“每当您为某个类型的Coleccion __定义一个实例时,您还应该指定该集合的元素el是什么”。“管道”后面的“箭头”表示,集合类型应该明确地确定元素是什么--也就是说,不能让一个集合包含几种不同类型的元素。
然后将其实现如下:
instance Coleccion (Pila a) a where
...
primero (Pil x) = last x(注意:为此您需要FunctionalDependencies和MultiParamTypeClasses扩展)
发布于 2017-12-11 18:16:16
@Fyodor解决方案是很棒的--这是另一种方法
module Coleccion where
data Pila a= Pil [a] deriving (Show,Eq,Ord)
data Cola a= Col [a] deriving (Show,Eq,Ord)
class Coleccion n where
esVacia::n->Bool
--insertar::n->a->n
primero::n->n
eliminar:: n->n
size::n->Int
instance Coleccion (Pila a) where
esVacia (Pil [])= True
esVacia (Pil _ )= False
primero (Pil xs) = (Pil [(last xs)])
eliminar (Pil xs)= (Pil (init xs))
size (Pil []) = 0
size (Pil xs) = length xs 现在使用Monad,函子和应用程序,你可以做任何你想做的事。
https://stackoverflow.com/questions/47758065
复制相似问题