无法将预期类型与实际类型进行列表构建

use*_*035 0 haskell types list

问题:拥有一个类似于地图类型的MapLike类型类,为ListL类型的MapLike实现一个实例。ListMap定义为对(键,值)对的列表。每个键只能有1个值。如果该键包含在映射中,则insert函数会将旧值更改为新值。

它部分实现了它,但是对于插入功能,我得到一个错误:

错误:

• 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)
Run Code Online (Sandbox Code Playgroud)

我不知道这是怎么回事,我正在检查密钥是否在列表的开头。如果存在,我们将更改值并将其与尾巴一起使用。如果不存在,我们将获得带有交换或串联的键/值对的列表,并为其添加一个标题。怎么了?

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)

Lee*_*Lee 6

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)