使用下面的代码片段,我希望将一个字符串附加/预先添加到一个列表中,该列表是存储在映射中的值的一部分。
从下面的代码片段中,我得到了错误
Couldn't match expected type `Char' with actual type `[Char]'
Expected type: Map.Map ([Char], Integer) [Char]
Actual type: Map.Map ([Char], Integer) [[Char]]我不太确定这应该告诉我什么。可以通过更改代码来解决这个问题吗?或者必须有如下内容
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}与实例声明一起使用?
import Data.Time
import Data.Time.Clock.POSIX
import qualified Data.PSQueue as PSQ
import qualified Data.Map as Map
import Data.Maybe
import Control.Category
import Control.Concurrent
import Control.Concurrent.MVar
import Control.Monad
key = ("192.168.1.1", 4711)
messages = ["aaa", "bbbb", "ccccc"]
newRq = do
time <- getPOSIXTime
let q = PSQ.singleton key time
let m = Map.singleton key messages
return (q, m)
appendMsg :: String -> (String, Integer) -> Map.Map ([Char], Integer) [Char] -> Map.Map ([Char], Integer) [Char]
appendMsg a (b, c) m = m2
where
f x = x ++ a
m2 = Map.adjust f (b, c) m
main :: IO()
main = do
(q, m) <- newRq
let m2 = appendMsg "first" key m
print (m2)发布于 2012-02-09 07:32:38
您需要在代码中进行更改。首先创建一个值为messages的单例( Map (String, Integer) [String] )。但是,您的更新函数是为Map (String, Integer) String编写的。通过将其设置为f x = x ++ [a]将其更改为适当的类型(并将类型签名更改为
appendMsg :: String -> (String, Integer) -> Map (String, Integer) [String]
-> Map (String, Integer) [String]也可以),或者通过使用unwords messages来更改初始地图。(我想您会更想要第一个。)
发布于 2012-02-09 13:50:29
[Char]和String是同一类型。Haskell前奏具有以下类型同义词定义:
type String = [Char]..。这基本上意味着这两种类型的含义是完全相同的,并且完全可以互换。这意味着我们可以将编译器错误重写为:
Expected type: Map (String, Integer) String
Actual type: Map (String, Integer) [String]Map类型的两个类型参数是它的Key类型和Value类型。因此,如果你有一个Map Int String类型,这意味着它是一个以Ints作为键,Strings作为值的映射。这意味着您现在可以更清楚地解释编译器消息:
Expected type: Map from keys of type "(String, Integer)" to values of type "String"
Actual type: Map from keys of type "(String, Integer)" to values of type "[String]"这告诉我们,在您的代码中的某个地方,您为它提供了一个映射,其中每个值都是一个[String] (即字符串的列表),但它期望的是一个每个值都只是一个String的映射。实际上,您可以将错误追溯到下面这行代码:
let m = Map.singleton key messages您已经猜到了,messages是String的列表(即[String]),当您使用singleton函数初始化它时,您告诉它将整个数组messages作为单个元素存储在映射m中。因此,Haskell正确地推断出m的值类型一定是[String] (这显然不是您想要的)。
然后,编译器注意到当您尝试将字符串附加到映射中的以下行中的每个元素时,出现了问题:
let m2 = appendMsg "first" key m您告诉编译器“请将此字符串连接到我的map的每个元素上”,然后编译器告诉您“但是您的map中没有存储多个字符串;您的map中只有一个字符串列表作为单个值存储,所以我不能将'first‘附加到数组本身”。
修复方法很简单,不是使用singleton来初始化m,而是使用fromList,它接受一个元素列表(即messages),并将列表中的每个元素转换为映射的一个元素,这正是您想要的。
发布于 2012-02-09 07:32:49
您使用Map.singleton key messages创建的地图是一个Map.Map (String, Integer) [String]。但是,您对appendMsg的声明表明您确实需要一个Map.Map (String, Integer) String。您需要重新访问您的newRq,并弄清楚您真正想要用该Map.singleton行做什么。
https://stackoverflow.com/questions/9203171
复制相似问题