use*_*035 0 haskell types list
问题:拥有一个类似于地图类型的MapLike类型类,为ListL类型的MapLike实现一个实例。ListMap定义为对(键,值)对的列表。每个键只能有1个值。如果该键包含在映射中,则insert函数会将旧值更改为新值。
它部分实现了它,但是对于插入功能,我得到一个错误:
错误:
Run Code Online (Sandbox Code Playgroud)• Couldn't match expected type ‘[ListMap k0 v0]’ with actual type ‘ListMap k v’ • In the second argument of ‘(:)’, namely ‘t’ In the expression: (ListMap (k, v) : t) In the expression: let t = insert key val (ListMap xs) in (ListMap (k, v) : t)
我不知道这是怎么回事,我正在检查密钥是否在列表的开头。如果存在,我们将更改值并将其与尾巴一起使用。如果不存在,我们将获得带有交换或串联的键/值对的列表,并为其添加一个标题。怎么了?
import Prelude hiding (lookup)
import qualified Data.List as L
class MapLike m where
empty :: m k v
lookup :: Ord k => k -> m k v -> Maybe v
insert :: Ord k => k -> v -> m k v -> m k v
delete :: Ord k => k -> m k v -> m k v
fromList :: Ord k => [(k,v)] -> m k v
fromList [] = empty
fromList ((k,v):xs) = insert k v (fromList xs)
newtype ListMap k v = ListMap { getListMap :: [(k,v)] }
deriving (Eq,Show)
instance MapLike ListMap where
empty = ListMap []
lookup key (ListMap []) = Nothing
lookup key (ListMap ((k, v):xs)) | key == k = Just v
| otherwise = lookup key (ListMap xs)
insert key val (ListMap []) = ListMap [(key, val)]
insert key val (ListMap ((k, v):xs)) | key == k = ListMap ((k, val):xs)
| otherwise = let (ListMap t) = insert key val (ListMap xs) in
(ListMap (k, v):t) -- <-?
Run Code Online (Sandbox Code Playgroud)
ListMap (k, v):t被解析为((ListMap (k, v)) : t)。由于(:)具有type a -> [a] -> [a],并且ListMap构造一个ListMap k v,t必须具有type才能进行类型检查[ListMap k v]。由于t(正确)具有类型,[(k, v)]因此检查失败。您还会遇到另一个错误,即(k, v)没有所需的类型[(k, v)]用作ListMap构造函数的参数。
您可以通过确保所需的解析来解决这两个问题:
ListMap ((k, v):t)
Run Code Online (Sandbox Code Playgroud)
要么
ListMap $ (k,v):t
Run Code Online (Sandbox Code Playgroud)