[英]Type declaration error: [Char] and [[Char]]
With the below snippet I want to append/prepend a string to a list that is part of a value stored in a map. 使用以下代码片段,我想在列表中追加/添加一个字符串,该列表是存储在地图中的值的一部分。
From the snippet below I get the error 从下面的代码片段中我得到了错误
Couldn't match expected type `Char' with actual type `[Char]'
Expected type: Map.Map ([Char], Integer) [Char]
Actual type: Map.Map ([Char], Integer) [[Char]]
and I am not quite sure what that should tell me. 我不太确定该告诉我什么。 Can that be solved with a change in the code or must there be something like
可以通过更改代码来解决吗,还是必须有类似的东西
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}
Together with an instance declaration? 连同实例声明?
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)
You need a change in the code. 您需要更改代码。 You start with a
Map (String, Integer) [String]
, by creating a singleton with value messages
. 您可以通过使用值
messages
创建单例,从Map (String, Integer) [String]
。 Your update function however is written for Map (String, Integer) String
. 但是,您的更新函数是针对
Map (String, Integer) String
编写的。 Either change it to the appropriate type by making it fx = x ++ [a]
(and change the type signature to 通过将其设为
fx = x ++ [a]
,将其更改为适当的类型(并将类型签名更改为
appendMsg :: String -> (String, Integer) -> Map (String, Integer) [String]
-> Map (String, Integer) [String]
too) or change your initial map by using eg unwords messages
. ),或通过使用
unwords messages
更改您的初始地图。 (I think you'll rather want the first.) (我认为您宁愿要第一个。)
[Char]
and String are the same type. [Char]
和String是同一类型。 The Haskell prelude has the following type synonym definition: Haskell序言具有以下类型同义词定义:
type String = [Char]
... which basically means those two types mean the exact same thing and are completely interchangeable. ...基本上意味着这两种类型完全相同,并且可以互换。 This means we can rewrite the compiler error as:
这意味着我们可以将编译器错误重写为:
Expected type: Map (String, Integer) String
Actual type: Map (String, Integer) [String]
The two type parameters of the Map
type are its Key
type and its Value
type. Map
类型的两个类型参数是其Key
类型和Value
类型。 So if you have a Map Int String
type, that means it's a map with Int
s as keys and Strings
as values. 因此,如果您具有
Map Int String
类型,则意味着它是一个以Int
为键和Strings
为值的映射。 This means you can now interpret the compiler message a little more clearly: 这意味着您现在可以更清楚地解释编译器消息:
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]"
This tells us that somewhere in your code you gave it a map where every value is a [String]
(ie a list of strings ), but it was expecting a map where every value was just a single String
. 这告诉我们,在代码的某个地方,您给它提供了一个映射,其中每个值都是
[String]
(即字符串列表 ),但是它期望映射中的每个值都只是一个String
。 In fact, you can trace the error to this line of code: 实际上,您可以将错误跟踪到以下代码行:
let m = Map.singleton key messages
messages
is, you guessed it, an list of String
s (ie [String]
), and you told it to store the entire array messages
as a single element in the map m
when you used the singleton
function to initialize it. 您猜到
messages
是String
的列表(即[String]
),并且您在使用singleton
函数对其进行初始化时,告诉它将整个数组messages
作为单个元素存储在映射m
。 So Haskell correctly inferred the value type of m
had to be [String]
(which was obviously not what you intended). 因此,Haskell正确地推断出
m
的值类型必须为[String]
(这显然不是您想要的)。
The compiler then noticed something was amiss when you tried to append a string to every element in your map in the following line: 然后,当您尝试在以下行中将字符串附加到映射中的每个元素时,编译器会发现某些地方不对:
let m2 = appendMsg "first" key m
You told the compiler "Please concatenate this string onto every element of my map" and the compiler then tells you "But you don't have multiple strings stored in your map; You have just one list of strings stored as a single value in your map, so I can't append 'first' onto the array itself". 您告诉编译器“请将此字符串连接到我的地图的每个元素上”,然后编译器告诉您“但是您的地图中没有存储多个字符串;您只有一个字符串列表作为单个值存储在您的地图中映射,因此无法将“第一个”附加到数组本身上”。
The fix is simple where instead of using singleton
to initialize m
, you just fromList
, which takes a list of elements (ie messages
) and converts each element in the list to an element of the map, which is what you intended. 修复很简单,只需使用
fromList
而不是使用singleton
来初始化m
,它只需获取元素列表(即messages
),然后将列表中的每个元素转换为地图中的元素,这就是您想要的。
The map you're creating with Map.singleton key messages
is a Map.Map (String, Integer) [String]
. 您使用
Map.singleton key messages
创建的地图是Map.Map (String, Integer) [String]
。 However your declaration of appendMsg
indicates that you really want a Map.Map (String, Integer) String
. 但是,您对
appendMsg
的声明表明您确实需要Map.Map (String, Integer) String
。 You need to revisit your newRq
and figure out what you're really trying to do with that Map.singleton
line. 您需要重新访问
newRq
并弄清楚您实际上在尝试使用该Map.singleton
行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.