Haskell:使用 IO 字符串制作 IO 映射时输入错误
Haskell: Wrong typing when making an IO Map out of IO Strings
我有一个具有以下签名的函数:
Config -> IO (Map.Map String String)
用于从 Config 中提取文件路径,然后加载该文件(包含文本行),然后将这些行解析为键和值 - 这就是我需要将它们保存到地图中的原因,最好。
所以,我创建了以下函数:
let lns = liftM lines $ readFile $ getSet $ listF c in
foldM (\m n -> liftM3 Map.insert n n m) (return Map.empty) lns
现在,我希望 Haskell 意识到我希望这是一个字符串的 IO 映射(为简单起见,我暂时不将行解析为键和值,只是将整行在那里)。
但是,我收到以下错误:
• Couldn't match type ‘Map.Map String’ with ‘IO’
Expected type: IO (Map.Map String String)
Actual type: Map.Map
String (Map.Map String (Map.Map String String))
• In the expression:
foldM (\ m n -> liftM3 Map.insert n n m) (return Map.empty) lns
In the expression:
let lns = liftM lines $ readFile $ getSet $ listF c
in foldM (\ m n -> liftM3 Map.insert n n m) (return Map.empty) lns
In an equation for ‘getEpisodeNames’:
getEpisodeNames c
| listF c == NotSet = return Map.empty
| otherwise
= let lns = liftM lines $ readFile $ getSet $ listF c
in foldM (\ m n -> liftM3 Map.insert n n m) (return Map.empty) lns
• Couldn't match type ‘[Char]’ with ‘Map.Map String String’
Expected type: Map.Map
String (Map.Map String (Map.Map String String))
Actual type: Map.Map String (Map.Map String String)
• In the expression: liftM3 Map.insert n n m
In the first argument of ‘foldM’, namely
‘(\ m n -> liftM3 Map.insert n n m)’
In the expression:
foldM (\ m n -> liftM3 Map.insert n n m) (return Map.empty) lns
• Couldn't match type ‘[]’ with ‘Map.Map String’
Expected type: IO (Map.Map String String)
Actual type: IO [String]
• In the third argument of ‘foldM’, namely ‘lns’
In the expression:
foldM (\ m n -> liftM3 Map.insert n n m) (return Map.empty) lns
In the expression:
let lns = liftM lines $ readFile $ getSet $ listF c
in foldM (\ m n -> liftM3 Map.insert n n m) (return Map.empty) lns
由此看来,return Map.empty
似乎试图将 Map 包装在 IO monad 之外的其他东西中,老实说,这对我来说没有意义。
因为 Haskell 从不犯错,所以我很清楚我在某个地方搞砸了,我就是找不到,在哪里(虽然我很确定它在第二行,因为我已使用 ghci 中的 :t
检查 lns 的正确类型)。我还尝试将函数重写为 >>= 符号而不是 let ... in ...,但它没有帮助。感谢您的帮助。
好的,所以我实际上已经设法修复了代码,尽管我仍然不完全确定问题出在哪里,所以如果有人能指出这一点,我仍然会很感激。
所以,而不是
let lns = liftM lines $ readFile $ getSet $ listF c in
foldM (\m n -> liftM3 Map.insert n n m) (return Map.empty) lns
我用过
(readFile . getSet $ listF c)
>>= (\tx -> return $ lines tx)
>>= (\lns -> return $ foldl (\m n -> Map.insert n n m) Map.empty lns)
foldM
的签名是
foldM :: Monad m => (a -> b -> m a) -> a -> [b] -> m a
让我们看看你有什么:
return Map.empty :: IO (Map String String)
lns :: IO [String]
那绝对不匹配参数 a
和 [b]
。修复前者很容易:只需使用 Map.empty
。对于后者,您需要访问 lns
中的内容,这就是绑定运算符的用途:
>>= :: m a -> (a -> m b) -> m b
因此
lns >>= foldM (…) Map.empty
但是既然你的操作是纯粹的,你还不如直接使用fmap
和foldl
foldl (…) Map.empty <$> lns
我有一个具有以下签名的函数:
Config -> IO (Map.Map String String)
用于从 Config 中提取文件路径,然后加载该文件(包含文本行),然后将这些行解析为键和值 - 这就是我需要将它们保存到地图中的原因,最好。
所以,我创建了以下函数:
let lns = liftM lines $ readFile $ getSet $ listF c in
foldM (\m n -> liftM3 Map.insert n n m) (return Map.empty) lns
现在,我希望 Haskell 意识到我希望这是一个字符串的 IO 映射(为简单起见,我暂时不将行解析为键和值,只是将整行在那里)。
但是,我收到以下错误:
• Couldn't match type ‘Map.Map String’ with ‘IO’
Expected type: IO (Map.Map String String)
Actual type: Map.Map
String (Map.Map String (Map.Map String String))
• In the expression:
foldM (\ m n -> liftM3 Map.insert n n m) (return Map.empty) lns
In the expression:
let lns = liftM lines $ readFile $ getSet $ listF c
in foldM (\ m n -> liftM3 Map.insert n n m) (return Map.empty) lns
In an equation for ‘getEpisodeNames’:
getEpisodeNames c
| listF c == NotSet = return Map.empty
| otherwise
= let lns = liftM lines $ readFile $ getSet $ listF c
in foldM (\ m n -> liftM3 Map.insert n n m) (return Map.empty) lns
• Couldn't match type ‘[Char]’ with ‘Map.Map String String’
Expected type: Map.Map
String (Map.Map String (Map.Map String String))
Actual type: Map.Map String (Map.Map String String)
• In the expression: liftM3 Map.insert n n m
In the first argument of ‘foldM’, namely
‘(\ m n -> liftM3 Map.insert n n m)’
In the expression:
foldM (\ m n -> liftM3 Map.insert n n m) (return Map.empty) lns
• Couldn't match type ‘[]’ with ‘Map.Map String’
Expected type: IO (Map.Map String String)
Actual type: IO [String]
• In the third argument of ‘foldM’, namely ‘lns’
In the expression:
foldM (\ m n -> liftM3 Map.insert n n m) (return Map.empty) lns
In the expression:
let lns = liftM lines $ readFile $ getSet $ listF c
in foldM (\ m n -> liftM3 Map.insert n n m) (return Map.empty) lns
由此看来,return Map.empty
似乎试图将 Map 包装在 IO monad 之外的其他东西中,老实说,这对我来说没有意义。
因为 Haskell 从不犯错,所以我很清楚我在某个地方搞砸了,我就是找不到,在哪里(虽然我很确定它在第二行,因为我已使用 ghci 中的 :t
检查 lns 的正确类型)。我还尝试将函数重写为 >>= 符号而不是 let ... in ...,但它没有帮助。感谢您的帮助。
好的,所以我实际上已经设法修复了代码,尽管我仍然不完全确定问题出在哪里,所以如果有人能指出这一点,我仍然会很感激。
所以,而不是
let lns = liftM lines $ readFile $ getSet $ listF c in
foldM (\m n -> liftM3 Map.insert n n m) (return Map.empty) lns
我用过
(readFile . getSet $ listF c)
>>= (\tx -> return $ lines tx)
>>= (\lns -> return $ foldl (\m n -> Map.insert n n m) Map.empty lns)
foldM
的签名是
foldM :: Monad m => (a -> b -> m a) -> a -> [b] -> m a
让我们看看你有什么:
return Map.empty :: IO (Map String String)
lns :: IO [String]
那绝对不匹配参数 a
和 [b]
。修复前者很容易:只需使用 Map.empty
。对于后者,您需要访问 lns
中的内容,这就是绑定运算符的用途:
>>= :: m a -> (a -> m b) -> m b
因此
lns >>= foldM (…) Map.empty
但是既然你的操作是纯粹的,你还不如直接使用fmap
和foldl
foldl (…) Map.empty <$> lns