2

我正在获取文件的内容并将其转换为表单列表:

[("abc", 123), ("def", 456)]

带有 readFile、行和单词。

现在,我可以设法将结果列表转换为IO [(String, Int)]类型。

我的问题是,当我尝试制作这样的功能时:

check x = lookup x theMap

我收到此错误,我不太确定如何解决:

Couldn't match expected type `[(a0, b0)]'
            with actual type `IO [(String, Int)]'
In the second argument of `lookup', namely `theMap'

theMap 本质上是这样的:

getLines :: String -> IO [String]
getLines = liftM lines . readFile

tuplify [x,y] = (x, read y :: Int)

theMap = do
    list <- getLines "./test.txt"
    let l = map tuplify (map words list)
    return l

文件内容是:

abc 123
def 456

谁能解释我做错了什么,或者告诉我一个更好的解决方案?几个小时前我刚开始玩 monads,一路上遇到了一些颠簸。

谢谢

4

1 回答 1

4

您将不得不theMap从 IO 中“解包”。请注意您已经getLines通过以下方式执行此操作:

do
  list <- getlines
  [...]
  return (some computation on list)

所以你可以有:

check x = do
  m <- theMap
  return . lookup x $ m

实际上,这是一种反模式(尽管是说明性的),最好使用仿函数实例,即。check x = fmap (lookup x) theMap

于 2012-10-17T09:11:46.033 回答