![](/img/trans.png)
[英]Couldn't match expected type `[a1]' with actual type `([a1], [a1])'
[英]Haskell: Couldn't match expected type ‘a1’ with actual type ‘a’
我有以下代碼:
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運行正常。 我不知道聲明或實例代碼有什么問題。 謝謝。
在你的類聲明,功能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;
該聲明說:“ 無論是為某個類型n
定義Coleccion
實例的人,都應提供一種方法來確定該集合的元素的類型,並且insertar
和primero
應在該類型上工作,而不是在某些隨機無關的類型上工作。 ”。 您可以這樣實現:
instance Coleccion (Pila a) where
type Elemento (Pila a) = a
...
primero (Pil x) = last x
在這里,您說:“ 我的收藏集是Pila a
,它的元素是a
,這就是primero
在其上的工作方式 ”。
(注意:您需要TypeFamilies
擴展名才能執行此操作)
或者 ,您可以使用函數依賴項和兩參數類型類:
class Coleccion n el | n -> el where
...
insertar::n -> el -> n
primero::n -> el
該聲明說:“ 每當為某些類型n
定義Coleccion
實例時,還應指定該集合的元素el
是什么 。” “管道”之后的“箭頭”表示,集合類型應明確確定元素是什么-也就是說,您不能讓一個集合包含幾種不同類型的元素。
然后,您可以像這樣實現它:
instance Coleccion (Pila a) a where
...
primero (Pil x) = last x
(注意:為此,您需要FunctionalDependencies
和MultiParamTypeClasses
擴展)
@Fyodor Soikin解決方案很棒,這是另一種實現方式
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,Functor和Applicative您可以做任何您想做的事
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.